diff --git a/Core/EntityReference/EnginesRoot.LocatorMap.cs b/Core/EntityReference/EnginesRoot.LocatorMap.cs index 147d53c..69dca5d 100644 --- a/Core/EntityReference/EnginesRoot.LocatorMap.cs +++ b/Core/EntityReference/EnginesRoot.LocatorMap.cs @@ -222,6 +222,7 @@ namespace Svelto.ECS } internal LocatorMap entityLocator => _entityLocator; + LocatorMap _entityLocator; } } \ No newline at end of file diff --git a/Core/GroupHashMap.cs b/Core/GroupHashMap.cs index 8e761d9..6702aae 100644 --- a/Core/GroupHashMap.cs +++ b/Core/GroupHashMap.cs @@ -77,7 +77,7 @@ namespace Svelto.ECS if(_groupsByHash.ContainsKey(nameHash)) throw new ECSException($"Group hash collision with {name} and {_groupsByHash[nameHash]}"); - Console.LogDebug($"Reigstering group {name} with ID {(uint)exclusiveGroupStruct} to {nameHash}"); + Console.LogDebug($"Registering group {name} with ID {(uint)exclusiveGroupStruct} to {nameHash}"); _groupsByHash.Add(nameHash, exclusiveGroupStruct); _hashByGroups.Add(exclusiveGroupStruct, nameHash); diff --git a/Core/Groups/ExclusiveGroup.cs b/Core/Groups/ExclusiveGroup.cs index b931d0e..2047525 100644 --- a/Core/Groups/ExclusiveGroup.cs +++ b/Core/Groups/ExclusiveGroup.cs @@ -18,20 +18,19 @@ namespace Svelto.ECS /// public static ExclusiveGroup[] GroupOfGroups = { MyExclusiveGroup1, ...}; //for each on this! /// } /// - ///To debug it use in your debug window: Svelto.ECS.Debugger.EGID.GetGroupNameFromId(groupID) public sealed class ExclusiveGroup { - public const uint MaxNumberOfExclusiveGroups = 2 << 20; + public const uint MaxNumberOfExclusiveGroups = 2 << 20; public ExclusiveGroup(ExclusiveGroupBitmask bitmask = 0) { - _group = ExclusiveGroupStruct.Generate((byte)bitmask); + _group = ExclusiveGroupStruct.Generate((byte) bitmask); } public ExclusiveGroup(string recognizeAs, ExclusiveGroupBitmask bitmask = 0) { - _group = ExclusiveGroupStruct.Generate((byte)bitmask); + _group = ExclusiveGroupStruct.Generate((byte) bitmask); _knownGroups.Add(recognizeAs, _group); } @@ -66,13 +65,13 @@ namespace Svelto.ECS return (uint) @group._group; } - public static ExclusiveGroupStruct operator+(ExclusiveGroup a, uint b) + public static ExclusiveGroupStruct operator +(ExclusiveGroup a, uint b) { #if DEBUG if (a._range == 0) - throw new ECSException($"Adding values to a not ranged ExclusiveGroup: {(uint)a}"); + throw new ECSException($"Adding values to a not ranged ExclusiveGroup: {(uint) a}"); if (b >= a._range) - throw new ECSException($"Using out of range group: {(uint)a} + {b}"); + throw new ECSException($"Using out of range group: {(uint) a} + {b}"); #endif return a._group + b; } @@ -91,12 +90,12 @@ namespace Svelto.ECS return _group.ToString(); } - static readonly Dictionary _knownGroups = new Dictionary(); + static readonly Dictionary _knownGroups = + new Dictionary(); #if DEBUG readonly ushort _range; #endif ExclusiveGroupStruct _group; } -} +} \ No newline at end of file diff --git a/Core/Groups/ExclusiveGroupStruct.cs b/Core/Groups/ExclusiveGroupStruct.cs index bd24981..e38290e 100644 --- a/Core/Groups/ExclusiveGroupStruct.cs +++ b/Core/Groups/ExclusiveGroupStruct.cs @@ -122,6 +122,8 @@ namespace Svelto.ECS internal ExclusiveGroupStruct(uint groupID):this() { + DBC.ECS.Check.Require(groupID < 0xFFFFFF); + _id = groupID; } diff --git a/Core/Groups/GroupCompound.cs b/Core/Groups/GroupCompound.cs index 8ae5530..3a29e63 100644 --- a/Core/Groups/GroupCompound.cs +++ b/Core/Groups/GroupCompound.cs @@ -5,6 +5,19 @@ using Svelto.DataStructures; namespace Svelto.ECS { + /// + /// This mechanism is not for thread-safety but to be sure that all the permutations of group tags always + /// point to the same group ID. + /// A group compound can generate several permutation of tags, so that the order of the tag doesn't matter, + /// but for this to work, each permutation must be identified by the same ID (generated by the unique combination) + /// + static class GroupCompoundInitializer + { + internal static readonly ThreadLocal skipStaticCompoundConstructorsWith4Tags = new ThreadLocal(); + internal static readonly ThreadLocal skipStaticCompoundConstructorsWith3Tags = new ThreadLocal(); + internal static readonly ThreadLocal skipStaticCompoundConstructorsWith2Tags = new ThreadLocal(); + } + public abstract class GroupCompound where G1 : GroupTag where G2 : GroupTag where G3 : GroupTag @@ -22,41 +35,28 @@ namespace Svelto.ECS static GroupCompound() { - if (Interlocked.CompareExchange(ref isInitializing, 1, 0) == 0) + //avoid race conditions if compounds are using on multiple thread + if (Interlocked.CompareExchange(ref isInitializing, 1, 0) == 0 + && GroupCompoundInitializer.skipStaticCompoundConstructorsWith4Tags.Value == false) { _Groups = new FasterList(1); - var Group = new ExclusiveGroup(); - _Groups.Add(Group); - _GroupsHashSet = new HashSet(_Groups.ToArrayFast(out _)); - - GroupCompound.Add(Group); - GroupCompound.Add(Group); - GroupCompound.Add(Group); - GroupCompound.Add(Group); - - GroupCompound.Add(Group); // and must share the same array - GroupCompound.Add(Group); - GroupCompound.Add(Group); - GroupCompound.Add(Group); - GroupCompound.Add(Group); - GroupCompound.Add(Group); - - //This is done here to be sure that the group is added once per group tag - //(if done inside the previous group compound it would be added multiple times) - GroupTag.Add(Group); - GroupTag.Add(Group); - GroupTag.Add(Group); - GroupTag.Add(Group); - + var group = new ExclusiveGroup(); + _Groups.Add(group); + + var name = + $"Compound: {typeof(G1).Name}-{typeof(G2).Name}-{typeof(G3).Name}-{typeof(G4).Name} ID {(uint) group}"; #if DEBUG - GroupNamesMap.idToName[(uint) Group] = - $"Compound: {typeof(G1).Name}-{typeof(G2).Name}-{typeof(G3).Name}-{typeof(G4).Name} ID {(uint) Group}"; + GroupNamesMap.idToName[(uint) group] = name; #endif - GroupHashMap.RegisterGroup(BuildGroup, - $"Compound: {typeof(G1).Name}-{typeof(G2).Name}-{typeof(G3).Name}-{typeof(G4).Name}"); + GroupHashMap.RegisterGroup(group, name); + + _GroupsHashSet = new HashSet(_Groups.ToArrayFast(out _)); - //all the combinations must share the same group and group hashset + GroupCompoundInitializer.skipStaticCompoundConstructorsWith4Tags.Value = true; + + //all the permutations must share the same group and group hashset. Warm them up, avoid call the + //constructors again, set the desired value GroupCompound._Groups = _Groups; GroupCompound._Groups = _Groups; GroupCompound._Groups = _Groups; @@ -80,6 +80,9 @@ namespace Svelto.ECS GroupCompound._Groups = _Groups; GroupCompound._Groups = _Groups; GroupCompound._Groups = _Groups; + + //all the permutations are warmed up now + GroupCompoundInitializer.skipStaticCompoundConstructorsWith4Tags.Value = false; GroupCompound._GroupsHashSet = _GroupsHashSet; GroupCompound._GroupsHashSet = _GroupsHashSet; @@ -104,6 +107,25 @@ namespace Svelto.ECS GroupCompound._GroupsHashSet = _GroupsHashSet; GroupCompound._GroupsHashSet = _GroupsHashSet; GroupCompound._GroupsHashSet = _GroupsHashSet; + + GroupCompound.Add(group); + GroupCompound.Add(group); + GroupCompound.Add(group); + GroupCompound.Add(group); + + GroupCompound.Add(group); // and must share the same array + GroupCompound.Add(group); + GroupCompound.Add(group); + GroupCompound.Add(group); + GroupCompound.Add(group); + GroupCompound.Add(group); + + //This is done here to be sure that the group is added once per group tag + //(if done inside the previous group compound it would be added multiple times) + GroupTag.Add(group); + GroupTag.Add(group); + GroupTag.Add(group); + GroupTag.Add(group); } } @@ -117,7 +139,10 @@ namespace Svelto.ECS _GroupsHashSet.Add(group); } - public static bool Includes(ExclusiveGroupStruct @group) { return _GroupsHashSet.Contains(@group); } + public static bool Includes(ExclusiveGroupStruct @group) + { + return _GroupsHashSet.Contains(@group); + } } public abstract class GroupCompound @@ -130,7 +155,7 @@ namespace Svelto.ECS new FasterReadOnlyList(_Groups); public static ExclusiveBuildGroup BuildGroup => new ExclusiveBuildGroup(_Groups[0]); - + static int isInitializing; internal static void Add(ExclusiveGroupStruct group) @@ -143,35 +168,31 @@ namespace Svelto.ECS _GroupsHashSet.Add(group); } - public static bool Includes(ExclusiveGroupStruct @group) { return _GroupsHashSet.Contains(@group); } + public static bool Includes(ExclusiveGroupStruct @group) + { + return _GroupsHashSet.Contains(@group); + } static GroupCompound() { - if (Interlocked.CompareExchange(ref isInitializing, 1, 0) == 0) + if (Interlocked.CompareExchange(ref isInitializing, 1, 0) == 0 && + GroupCompoundInitializer.skipStaticCompoundConstructorsWith3Tags.Value == false) { _Groups = new FasterList(1); - var Group = new ExclusiveGroup(); - _Groups.Add(Group); - _GroupsHashSet = new HashSet(_Groups.ToArrayFast(out _)); - - GroupCompound.Add(Group); // and must share the same array - GroupCompound.Add(Group); - GroupCompound.Add(Group); - - //This is done here to be sure that the group is added once per group tag - //(if done inside the previous group compound it would be added multiple times) - GroupTag.Add(Group); - GroupTag.Add(Group); - GroupTag.Add(Group); + var group = new ExclusiveGroup(); + _Groups.Add(group); + var name = $"Compound: {typeof(G1).Name}-{typeof(G2).Name}-{typeof(G3).Name} ID {(uint) group}"; #if DEBUG - GroupNamesMap.idToName[(uint) Group] = - $"Compound: {typeof(G1).Name}-{typeof(G2).Name}-{typeof(G3).Name} ID {(uint) Group}"; + GroupNamesMap.idToName[(uint) group] = name; #endif - GroupHashMap.RegisterGroup(BuildGroup, - $"Compound: {typeof(G1).Name}-{typeof(G2).Name}-{typeof(G3).Name}"); + GroupHashMap.RegisterGroup(group, name); + _GroupsHashSet = new HashSet(_Groups.ToArrayFast(out _)); + + GroupCompoundInitializer.skipStaticCompoundConstructorsWith3Tags.Value = true; + //all the combinations must share the same group and group hashset GroupCompound._Groups = _Groups; GroupCompound._Groups = _Groups; @@ -179,11 +200,24 @@ namespace Svelto.ECS GroupCompound._Groups = _Groups; GroupCompound._Groups = _Groups; + //all the constructor have been called now + GroupCompoundInitializer.skipStaticCompoundConstructorsWith3Tags.Value = false; + GroupCompound._GroupsHashSet = _GroupsHashSet; GroupCompound._GroupsHashSet = _GroupsHashSet; GroupCompound._GroupsHashSet = _GroupsHashSet; GroupCompound._GroupsHashSet = _GroupsHashSet; GroupCompound._GroupsHashSet = _GroupsHashSet; + + GroupCompound.Add(group); // and must share the same array + GroupCompound.Add(group); + GroupCompound.Add(group); + + //This is done here to be sure that the group is added once per group tag + //(if done inside the previous group compound it would be added multiple times) + GroupTag.Add(group); + GroupTag.Add(group); + GroupTag.Add(group); } } } @@ -197,7 +231,7 @@ namespace Svelto.ECS new FasterReadOnlyList(_Groups); public static ExclusiveBuildGroup BuildGroup => new ExclusiveBuildGroup(_Groups[0]); - + static int isInitializing; internal static void Add(ExclusiveGroupStruct group) @@ -210,30 +244,37 @@ namespace Svelto.ECS _GroupsHashSet.Add(group); } - public static bool Includes(ExclusiveGroupStruct @group) { return _GroupsHashSet.Contains(@group); } + public static bool Includes(ExclusiveGroupStruct @group) + { + return _GroupsHashSet.Contains(@group); + } static GroupCompound() { - if (Interlocked.CompareExchange(ref isInitializing, 1, 0) == 0) + if (Interlocked.CompareExchange(ref isInitializing, 1, 0) == 0 && + GroupCompoundInitializer.skipStaticCompoundConstructorsWith2Tags.Value == false) { - var Group = new ExclusiveGroup(); + var group = new ExclusiveGroup(); _Groups = new FasterList(1); - _Groups.Add(Group); - _GroupsHashSet = new HashSet(_Groups.ToArrayFast(out _)); - - //every abstract group preemptively adds this group, it may or may not be empty in future - GroupTag.Add(Group); - GroupTag.Add(Group); + _Groups.Add(group); + var groupName = $"Compound: {typeof(G1).Name}-{typeof(G2).Name} ID {(uint) group}"; #if DEBUG - GroupNamesMap.idToName[(uint) Group] = $"Compound: {typeof(G1).Name}-{typeof(G2).Name} ID {(uint) Group}"; + GroupNamesMap.idToName[(uint) group] = groupName; #endif - GroupHashMap.RegisterGroup(BuildGroup, - $"Compound: {typeof(G1).Name}-{typeof(G2).Name}"); + GroupHashMap.RegisterGroup(group, groupName); + + _GroupsHashSet = new HashSet(_Groups.ToArrayFast(out _)); - GroupCompound._Groups = _Groups; - GroupCompound._GroupsHashSet = _GroupsHashSet; + GroupCompoundInitializer.skipStaticCompoundConstructorsWith2Tags.Value = true; + GroupCompound._Groups = _Groups; + GroupCompoundInitializer.skipStaticCompoundConstructorsWith2Tags.Value = false; + GroupCompound._GroupsHashSet = _GroupsHashSet; + + //every abstract group preemptively adds this group, it may or may not be empty in future + GroupTag.Add(group); + GroupTag.Add(group); } } } @@ -254,7 +295,7 @@ namespace Svelto.ECS new FasterReadOnlyList(_Groups); public static ExclusiveBuildGroup BuildGroup => new ExclusiveBuildGroup(_Groups[0]); - + static int isInitializing; static GroupTag() @@ -263,19 +304,22 @@ namespace Svelto.ECS { var group = new ExclusiveGroup(); _Groups.Add(group); - _GroupsHashSet = new HashSet(_Groups.ToArrayFast(out _)); + -#if DEBUG var typeInfo = typeof(T); + + var name = $"Compound: {typeInfo.Name} ID {(uint) @group}"; +#if DEBUG var typeInfoBaseType = typeInfo.BaseType; if (typeInfoBaseType.GenericTypeArguments[0] != typeInfo) throw new ECSException("Invalid Group Tag declared"); - - GroupNamesMap.idToName[(uint)group] = $"Compound: {typeInfo.Name} ID {(uint)group}"; + + GroupNamesMap.idToName[(uint) group] = name; #endif - GroupHashMap.RegisterGroup(BuildGroup, - $"Compound: {typeof(T).FullName}"); - } + GroupHashMap.RegisterGroup(group, name); + + _GroupsHashSet = new HashSet(_Groups.ToArrayFast(out _)); + } } //Each time a new combination of group tags is found a new group is added. @@ -289,6 +333,9 @@ namespace Svelto.ECS _GroupsHashSet.Add(group); } - public static bool Includes(ExclusiveGroupStruct @group) { return _GroupsHashSet.Contains(@group); } + public static bool Includes(ExclusiveGroupStruct @group) + { + return _GroupsHashSet.Contains(@group); + } } } \ No newline at end of file diff --git a/Core/Hybrid/ValueReference.cs b/Core/Hybrid/ValueReference.cs index ed5a9ac..c11990f 100644 --- a/Core/Hybrid/ValueReference.cs +++ b/Core/Hybrid/ValueReference.cs @@ -21,7 +21,7 @@ namespace Svelto.ECS.Hybrid public ValueReference(T obj) { _pointer = GCHandle.Alloc(obj, GCHandleType.Normal); } - public W Convert(W implementer) where W:T, new() + public W Convert(W implementer) where W:T { var pointerTarget = _pointer.Target; return (W)pointerTarget; diff --git a/DataStructures/Unmanaged/AtomicNativeBags.cs b/DataStructures/Unmanaged/AtomicNativeBags.cs index f7ce630..ee80a65 100644 --- a/DataStructures/Unmanaged/AtomicNativeBags.cs +++ b/DataStructures/Unmanaged/AtomicNativeBags.cs @@ -72,7 +72,7 @@ namespace Svelto.ECS.DataStructures } } -#if UNITY_COLLECTIONS +#if UNITY_COLLECTIONS || UNITY_JOBS || UNITY_BURST [global::Unity.Collections.LowLevel.Unsafe.NativeDisableUnsafePtrRestriction] #endif NativeBag* _data; diff --git a/DataStructures/Unmanaged/NativeBag.cs b/DataStructures/Unmanaged/NativeBag.cs index e2252fe..16478a4 100644 --- a/DataStructures/Unmanaged/NativeBag.cs +++ b/DataStructures/Unmanaged/NativeBag.cs @@ -273,7 +273,7 @@ namespace Svelto.ECS.DataStructures #if ENABLE_THREAD_SAFE_CHECKS int _threadSentinel; #endif -#if UNITY_COLLECTIONS +#if UNITY_COLLECTIONS || UNITY_JOBS || UNITY_BURST [global::Unity.Collections.LowLevel.Unsafe.NativeDisableUnsafePtrRestriction] #endif unsafe UnsafeBlob* _queue; diff --git a/DataStructures/Unmanaged/NativeDynamicArray.cs b/DataStructures/Unmanaged/NativeDynamicArray.cs index dd05cc7..b92dfec 100644 --- a/DataStructures/Unmanaged/NativeDynamicArray.cs +++ b/DataStructures/Unmanaged/NativeDynamicArray.cs @@ -377,7 +377,7 @@ namespace Svelto.ECS.DataStructures } } -#if UNITY_COLLECTIONS +#if UNITY_COLLECTIONS || UNITY_JOBS || UNITY_BURST [global::Unity.Burst.NoAlias] [global::Unity.Collections.LowLevel.Unsafe.NativeDisableUnsafePtrRestriction] #endif unsafe UnsafeArray* _list; diff --git a/DataStructures/Unmanaged/SharedNativeInt.cs b/DataStructures/Unmanaged/SharedNativeInt.cs index 60d82da..f5f9698 100644 --- a/DataStructures/Unmanaged/SharedNativeInt.cs +++ b/DataStructures/Unmanaged/SharedNativeInt.cs @@ -6,7 +6,7 @@ namespace Svelto.ECS.DataStructures { public struct SharedNativeInt: IDisposable { -#if UNITY_COLLECTIONS +#if UNITY_COLLECTIONS || UNITY_JOBS || UNITY_BURST [global::Unity.Collections.LowLevel.Unsafe.NativeDisableUnsafePtrRestriction] #endif unsafe int* data; diff --git a/DataStructures/Unmanaged/ThreadSafeNativeBag.cs b/DataStructures/Unmanaged/ThreadSafeNativeBag.cs index d5d7187..003f07c 100644 --- a/DataStructures/Unmanaged/ThreadSafeNativeBag.cs +++ b/DataStructures/Unmanaged/ThreadSafeNativeBag.cs @@ -183,7 +183,7 @@ namespace Svelto.ECS.DataStructures } } -#if UNITY_COLLECTIONS +#if UNITY_COLLECTIONS || UNITY_JOBS || UNITY_BURST [global::Unity.Collections.LowLevel.Unsafe.NativeDisableUnsafePtrRestriction] #endif unsafe UnsafeBlob* _queue; diff --git a/DataStructures/Unmanaged/UnsafeArray.cs b/DataStructures/Unmanaged/UnsafeArray.cs index 668d543..89dda8e 100644 --- a/DataStructures/Unmanaged/UnsafeArray.cs +++ b/DataStructures/Unmanaged/UnsafeArray.cs @@ -133,7 +133,7 @@ namespace Svelto.ECS.DataStructures _writeIndex = count; } -#if UNITY_COLLECTIONS +#if UNITY_COLLECTIONS || UNITY_JOBS || UNITY_BURST [global::Unity.Collections.LowLevel.Unsafe.NativeDisableUnsafePtrRestriction] #endif unsafe byte* _ptr; diff --git a/Extensions/Svelto/GroupsEnumerable.cs b/Extensions/Svelto/GroupsEnumerable.cs index f5fbfc5..6425531 100644 --- a/Extensions/Svelto/GroupsEnumerable.cs +++ b/Extensions/Svelto/GroupsEnumerable.cs @@ -148,6 +148,8 @@ namespace Svelto.ECS readonly EntitiesDB _entitiesDB; } + //todo: there is a steep cost to pay to copy these structs, one day I may need to investigate this more. + //the structs are quite big, in the order of 100+ bytes. public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); } readonly EntitiesDB _db; diff --git a/Extensions/Unity/DOTS/Native/NativeEGIDMapper.cs b/Extensions/Unity/DOTS/Native/NativeEGIDMapper.cs index cf953d8..628ef08 100644 --- a/Extensions/Unity/DOTS/Native/NativeEGIDMapper.cs +++ b/Extensions/Unity/DOTS/Native/NativeEGIDMapper.cs @@ -6,18 +6,28 @@ using Svelto.DataStructures; namespace Svelto.ECS.Native { - public readonly struct NativeEGIDMapper:IEGIDMapper where T : unmanaged, IEntityComponent + /// + /// Note: this class should really be ref struct by design. It holds the reference of a dictionary that can become + /// invalid. Unfortunately it can be a ref struct, because Jobs needs to hold if by paramater. So the deal is + /// that a job can use it as long as nothing else is modifying the entities database and the NativeEGIDMapper + /// is disposed right after the use. + /// + public readonly struct NativeEGIDMapper : IEGIDMapper where T : unmanaged, IEntityComponent { public NativeEGIDMapper - (ExclusiveGroupStruct groupStructId, SveltoDictionaryNative toNative) : this() + (ExclusiveGroupStruct groupStructId + , SveltoDictionary>, NativeStrategy, NativeStrategy> + toNative) : this() { groupID = groupStructId; - _map = toNative; + _map = new SveltoDictionaryNative(); + + _map.UnsafeCast(toNative); } - public int count => _map.count; - public Type entityType => TypeCache.type; - public ExclusiveGroupStruct groupID { get; } + public int count => _map.count; + public Type entityType => TypeCache.type; + public ExclusiveGroupStruct groupID { get; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref T Entity(uint entityID) @@ -35,14 +45,12 @@ namespace Svelto.ECS.Native public bool TryGetEntity(uint entityID, out T value) { if (_map.count > 0 && _map.TryFindIndex(entityID, out var index)) - { unsafe { value = Unsafe.AsRef(Unsafe.Add((void*) _map.GetValues(out _).ToNativeArray(out _) , (int) index)); return true; } - } value = default; return false; @@ -52,9 +60,7 @@ namespace Svelto.ECS.Native public NB GetArrayAndEntityIndex(uint entityID, out uint index) { if (_map.TryFindIndex(entityID, out index)) - { return new NB(_map.GetValues(out var count).ToNativeArray(out _), count); - } #if DEBUG throw new ECSException("Entity not found"); @@ -94,8 +100,8 @@ namespace Svelto.ECS.Native { return _map.TryFindIndex(valueKey, out index); } - - readonly ReadonlySveltoDictionaryNative _map; + + readonly SveltoDictionaryNative _map; } } #endif \ No newline at end of file diff --git a/Extensions/Unity/DOTS/Native/NativeEGIDMultiMapper.cs b/Extensions/Unity/DOTS/Native/NativeEGIDMultiMapper.cs index 94ba669..228cae0 100644 --- a/Extensions/Unity/DOTS/Native/NativeEGIDMultiMapper.cs +++ b/Extensions/Unity/DOTS/Native/NativeEGIDMultiMapper.cs @@ -4,6 +4,12 @@ using Svelto.DataStructures; namespace Svelto.ECS.Native { + /// + /// Note: this class should really be ref struct by design. It holds the reference of a dictionary that can become + /// invalid. Unfortunately it can be a ref struct, because Jobs needs to hold if by paramater. So the deal is + /// that a job can use it as long as nothing else is modifying the entities database and the NativeEGIDMultiMapper + /// is disposed right after the use. + /// public struct NativeEGIDMultiMapper : IDisposable where T : unmanaged, IEntityComponent { public NativeEGIDMultiMapper diff --git a/README.md b/README.md index 40d604f..97b0c0b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Svelto.ECS wasn't born just from the needs of a large team, but also as a result ## How to clone the repository: The folders Svelto.ECS and Svelto.Common, where present, are submodules pointing to the relative repositories. If you find them empty, you need to update them through the submodule command. Check some instructions here: https://github.com/sebas77/Svelto.ECS.Vanilla.Example/wiki -## Svelto is now distributed as Unity Package too [![openupm](https://img.shields.io/npm/v/com.sebaslab.svelto.ecs?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.com/packages/com.sebaslab.svelto.ecs/) +## Svelto distributed as Unity Package through OpenUPM [![openupm](https://img.shields.io/npm/v/com.sebaslab.svelto.ecs?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.com/packages/com.sebaslab.svelto.ecs/) read this article for more information: http://www.sebaslab.com/distributing-svelto-through-openupm/ or just install the package that comes from the link https://package-installer.glitch.me/v1/installer/OpenUPM/com.sebaslab.svelto.ecs?registry=https%3A%2F%2Fpackage.openupm.com @@ -17,6 +17,10 @@ read this article for more information: http://www.sebaslab.com/distributing-sve Unity Package System has a big deficiency when it comes to dll dependency solving: two packages cannot point to the same dependency from different sources. Since Unity Collection removed the Unsafe.dll dependency, I had to distribute my own package. This means that if you want to use Svelto from UPM, you will need Svelto unsafe dll to be the only unsafe dll in the project. Otherwise you just download the source code and solve dependencies manually. +## Svelto distributed as Nuget + +I am not a Nuget expert, but thanks to our contributors, Svelto.ECS can be found at https://www.nuget.org/packages/Svelto.ECS/ + ## Official Examples (A.K.A. where is the documentation?) Svelto doesn't have official documentation. The reason is that documentation is costly to mantain and...I reckon people don't need it, thanks to the highly documented and simple mini-examples. Please check and study them all regardless the platform you intend to use Svelto with. diff --git a/Svelto.ECS.csproj b/Svelto.ECS.csproj index 0644b97..982670d 100644 --- a/Svelto.ECS.csproj +++ b/Svelto.ECS.csproj @@ -3,6 +3,8 @@ Svelto.ECS 8 netstandard2.0 + Svelto + 3.2.1 Svelto.ECS @@ -23,6 +25,6 @@ - + \ No newline at end of file diff --git a/package.json b/package.json index b5abd7c..471ea37 100644 --- a/package.json +++ b/package.json @@ -3,13 +3,13 @@ "category": "Svelto", "description": "Svelto ECS C# Lightweight Data Oriented Entity Component System Framework", "dependencies": { - "com.sebaslab.svelto.common": "3.2.0" + "com.sebaslab.svelto.common": "3.2.1" }, "keywords": [ "svelto" ], "name": "com.sebaslab.svelto.ecs", - "version": "3.2.1", + "version": "3.2.2", "type": "library", "unity": "2019.3" } \ No newline at end of file