Browse Source

Fix compilation errors

Fix serious bug with GroupCompund generation
pull/70/head
sebas77 2 years ago
parent
commit
3d8196b781
19 changed files with 174 additions and 109 deletions
  1. +1
    -1
      Svelto.Common
  2. +1
    -0
      Svelto.ECS/Core/EntityReference/EnginesRoot.LocatorMap.cs
  3. +1
    -1
      Svelto.ECS/Core/GroupHashMap.cs
  4. +9
    -10
      Svelto.ECS/Core/Groups/ExclusiveGroup.cs
  5. +2
    -0
      Svelto.ECS/Core/Groups/ExclusiveGroupStruct.cs
  6. +121
    -74
      Svelto.ECS/Core/Groups/GroupCompound.cs
  7. +1
    -1
      Svelto.ECS/Core/Hybrid/ValueReference.cs
  8. +1
    -1
      Svelto.ECS/DataStructures/Unmanaged/AtomicNativeBags.cs
  9. +1
    -1
      Svelto.ECS/DataStructures/Unmanaged/NativeBag.cs
  10. +1
    -1
      Svelto.ECS/DataStructures/Unmanaged/NativeDynamicArray.cs
  11. +1
    -1
      Svelto.ECS/DataStructures/Unmanaged/SharedNativeInt.cs
  12. +1
    -1
      Svelto.ECS/DataStructures/Unmanaged/ThreadSafeNativeBag.cs
  13. +1
    -1
      Svelto.ECS/DataStructures/Unmanaged/UnsafeArray.cs
  14. +2
    -0
      Svelto.ECS/Extensions/Svelto/GroupsEnumerable.cs
  15. +18
    -12
      Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEGIDMapper.cs
  16. +6
    -0
      Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEGIDMultiMapper.cs
  17. +3
    -1
      Svelto.ECS/Svelto.ECS.csproj
  18. +2
    -2
      Svelto.ECS/package.json
  19. +1
    -1
      Svelto.ECS/version.json

+ 1
- 1
Svelto.Common

@@ -1 +1 @@
Subproject commit 656980d4e1026955f27e84f97b77339fd7cbd87c
Subproject commit ec2fd735014e3c54889dbad2a542515626d73a7f

+ 1
- 0
Svelto.ECS/Core/EntityReference/EnginesRoot.LocatorMap.cs View File

@@ -222,6 +222,7 @@ namespace Svelto.ECS
}

internal LocatorMap entityLocator => _entityLocator;
LocatorMap _entityLocator;
}
}

+ 1
- 1
Svelto.ECS/Core/GroupHashMap.cs View File

@@ -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);


+ 9
- 10
Svelto.ECS/Core/Groups/ExclusiveGroup.cs View File

@@ -18,20 +18,19 @@ namespace Svelto.ECS
/// public static ExclusiveGroup[] GroupOfGroups = { MyExclusiveGroup1, ...}; //for each on this!
/// }
/// </summary>

///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<string, ExclusiveGroupStruct> _knownGroups = new Dictionary<string,
ExclusiveGroupStruct>();
static readonly Dictionary<string, ExclusiveGroupStruct> _knownGroups =
new Dictionary<string, ExclusiveGroupStruct>();

#if DEBUG
readonly ushort _range;
#endif
ExclusiveGroupStruct _group;
}
}
}

+ 2
- 0
Svelto.ECS/Core/Groups/ExclusiveGroupStruct.cs View File

@@ -122,6 +122,8 @@ namespace Svelto.ECS

internal ExclusiveGroupStruct(uint groupID):this()
{
DBC.ECS.Check.Require(groupID < 0xFFFFFF);
_id = groupID;
}



+ 121
- 74
Svelto.ECS/Core/Groups/GroupCompound.cs View File

@@ -5,6 +5,19 @@ using Svelto.DataStructures;

namespace Svelto.ECS
{
/// <summary>
/// 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)
/// </summary>
static class GroupCompoundInitializer
{
internal static readonly ThreadLocal<bool> skipStaticCompoundConstructorsWith4Tags = new ThreadLocal<bool>();
internal static readonly ThreadLocal<bool> skipStaticCompoundConstructorsWith3Tags = new ThreadLocal<bool>();
internal static readonly ThreadLocal<bool> skipStaticCompoundConstructorsWith2Tags = new ThreadLocal<bool>();
}

public abstract class GroupCompound<G1, G2, G3, G4> where G1 : GroupTag<G1>
where G2 : GroupTag<G2>
where G3 : GroupTag<G3>
@@ -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<ExclusiveGroupStruct>(1);

var Group = new ExclusiveGroup();
_Groups.Add(Group);
_GroupsHashSet = new HashSet<ExclusiveGroupStruct>(_Groups.ToArrayFast(out _));

GroupCompound<G1, G2, G3>.Add(Group);
GroupCompound<G1, G2, G4>.Add(Group);
GroupCompound<G1, G3, G4>.Add(Group);
GroupCompound<G2, G3, G4>.Add(Group);

GroupCompound<G1, G2>.Add(Group); //<G1/G2> and <G2/G1> must share the same array
GroupCompound<G1, G3>.Add(Group);
GroupCompound<G1, G4>.Add(Group);
GroupCompound<G2, G3>.Add(Group);
GroupCompound<G2, G4>.Add(Group);
GroupCompound<G3, G4>.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<G1>.Add(Group);
GroupTag<G2>.Add(Group);
GroupTag<G3>.Add(Group);
GroupTag<G4>.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<ExclusiveGroupStruct>(_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<G1, G2, G4, G3>._Groups = _Groups;
GroupCompound<G1, G3, G2, G4>._Groups = _Groups;
GroupCompound<G1, G3, G4, G2>._Groups = _Groups;
@@ -80,6 +80,9 @@ namespace Svelto.ECS
GroupCompound<G4, G2, G3, G1>._Groups = _Groups;
GroupCompound<G4, G3, G1, G2>._Groups = _Groups;
GroupCompound<G4, G3, G2, G1>._Groups = _Groups;
//all the permutations are warmed up now
GroupCompoundInitializer.skipStaticCompoundConstructorsWith4Tags.Value = false;

GroupCompound<G1, G2, G4, G3>._GroupsHashSet = _GroupsHashSet;
GroupCompound<G1, G3, G2, G4>._GroupsHashSet = _GroupsHashSet;
@@ -104,6 +107,25 @@ namespace Svelto.ECS
GroupCompound<G4, G2, G3, G1>._GroupsHashSet = _GroupsHashSet;
GroupCompound<G4, G3, G1, G2>._GroupsHashSet = _GroupsHashSet;
GroupCompound<G4, G3, G2, G1>._GroupsHashSet = _GroupsHashSet;
GroupCompound<G1, G2, G3>.Add(group);
GroupCompound<G1, G2, G4>.Add(group);
GroupCompound<G1, G3, G4>.Add(group);
GroupCompound<G2, G3, G4>.Add(group);

GroupCompound<G1, G2>.Add(group); //<G1/G2> and <G2/G1> must share the same array
GroupCompound<G1, G3>.Add(group);
GroupCompound<G1, G4>.Add(group);
GroupCompound<G2, G3>.Add(group);
GroupCompound<G2, G4>.Add(group);
GroupCompound<G3, G4>.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<G1>.Add(group);
GroupTag<G2>.Add(group);
GroupTag<G3>.Add(group);
GroupTag<G4>.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<G1, G2, G3>
@@ -130,7 +155,7 @@ namespace Svelto.ECS
new FasterReadOnlyList<ExclusiveGroupStruct>(_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<ExclusiveGroupStruct>(1);

var Group = new ExclusiveGroup();
_Groups.Add(Group);
_GroupsHashSet = new HashSet<ExclusiveGroupStruct>(_Groups.ToArrayFast(out _));

GroupCompound<G1, G2>.Add(Group); //<G1/G2> and <G2/G1> must share the same array
GroupCompound<G1, G3>.Add(Group);
GroupCompound<G2, G3>.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<G1>.Add(Group);
GroupTag<G2>.Add(Group);
GroupTag<G3>.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<ExclusiveGroupStruct>(_Groups.ToArrayFast(out _));

GroupCompoundInitializer.skipStaticCompoundConstructorsWith3Tags.Value = true;

//all the combinations must share the same group and group hashset
GroupCompound<G3, G1, G2>._Groups = _Groups;
GroupCompound<G2, G3, G1>._Groups = _Groups;
@@ -179,11 +200,24 @@ namespace Svelto.ECS
GroupCompound<G1, G3, G2>._Groups = _Groups;
GroupCompound<G2, G1, G3>._Groups = _Groups;

//all the constructor have been called now
GroupCompoundInitializer.skipStaticCompoundConstructorsWith3Tags.Value = false;

GroupCompound<G3, G1, G2>._GroupsHashSet = _GroupsHashSet;
GroupCompound<G2, G3, G1>._GroupsHashSet = _GroupsHashSet;
GroupCompound<G3, G2, G1>._GroupsHashSet = _GroupsHashSet;
GroupCompound<G1, G3, G2>._GroupsHashSet = _GroupsHashSet;
GroupCompound<G2, G1, G3>._GroupsHashSet = _GroupsHashSet;
GroupCompound<G1, G2>.Add(group); //<G1/G2> and <G2/G1> must share the same array
GroupCompound<G1, G3>.Add(group);
GroupCompound<G2, G3>.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<G1>.Add(group);
GroupTag<G2>.Add(group);
GroupTag<G3>.Add(group);
}
}
}
@@ -197,7 +231,7 @@ namespace Svelto.ECS
new FasterReadOnlyList<ExclusiveGroupStruct>(_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<ExclusiveGroupStruct>(1);
_Groups.Add(Group);
_GroupsHashSet = new HashSet<ExclusiveGroupStruct>(_Groups.ToArrayFast(out _));

//every abstract group preemptively adds this group, it may or may not be empty in future
GroupTag<G1>.Add(Group);
GroupTag<G2>.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<ExclusiveGroupStruct>(_Groups.ToArrayFast(out _));

GroupCompound<G2, G1>._Groups = _Groups;
GroupCompound<G2, G1>._GroupsHashSet = _GroupsHashSet;
GroupCompoundInitializer.skipStaticCompoundConstructorsWith2Tags.Value = true;
GroupCompound<G2, G1>._Groups = _Groups;
GroupCompoundInitializer.skipStaticCompoundConstructorsWith2Tags.Value = false;
GroupCompound<G2, G1>._GroupsHashSet = _GroupsHashSet;
//every abstract group preemptively adds this group, it may or may not be empty in future
GroupTag<G1>.Add(group);
GroupTag<G2>.Add(group);
}
}
}
@@ -254,7 +295,7 @@ namespace Svelto.ECS
new FasterReadOnlyList<ExclusiveGroupStruct>(_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<ExclusiveGroupStruct>(_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<ExclusiveGroupStruct>(_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);
}
}
}

+ 1
- 1
Svelto.ECS/Core/Hybrid/ValueReference.cs View File

@@ -21,7 +21,7 @@ namespace Svelto.ECS.Hybrid

public ValueReference(T obj) { _pointer = GCHandle.Alloc(obj, GCHandleType.Normal); }

public W Convert<W>(W implementer) where W:T, new()
public W Convert<W>(W implementer) where W:T
{
var pointerTarget = _pointer.Target;
return (W)pointerTarget;


+ 1
- 1
Svelto.ECS/DataStructures/Unmanaged/AtomicNativeBags.cs View File

@@ -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;


+ 1
- 1
Svelto.ECS/DataStructures/Unmanaged/NativeBag.cs View File

@@ -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;


+ 1
- 1
Svelto.ECS/DataStructures/Unmanaged/NativeDynamicArray.cs View File

@@ -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;


+ 1
- 1
Svelto.ECS/DataStructures/Unmanaged/SharedNativeInt.cs View File

@@ -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;


+ 1
- 1
Svelto.ECS/DataStructures/Unmanaged/ThreadSafeNativeBag.cs View File

@@ -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;


+ 1
- 1
Svelto.ECS/DataStructures/Unmanaged/UnsafeArray.cs View File

@@ -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;


+ 2
- 0
Svelto.ECS/Extensions/Svelto/GroupsEnumerable.cs View File

@@ -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;


+ 18
- 12
Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEGIDMapper.cs View File

@@ -6,18 +6,28 @@ using Svelto.DataStructures;

namespace Svelto.ECS.Native
{
public readonly struct NativeEGIDMapper<T>:IEGIDMapper where T : unmanaged, IEntityComponent
/// <summary>
/// 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.
/// </summary>
public readonly struct NativeEGIDMapper<T> : IEGIDMapper where T : unmanaged, IEntityComponent
{
public NativeEGIDMapper
(ExclusiveGroupStruct groupStructId, SveltoDictionaryNative<uint, T> toNative) : this()
(ExclusiveGroupStruct groupStructId
, SveltoDictionary<uint, T, NativeStrategy<SveltoDictionaryNode<uint>>, NativeStrategy<T>, NativeStrategy<int>>
toNative) : this()
{
groupID = groupStructId;
_map = toNative;
_map = new SveltoDictionaryNative<uint, T>();
_map.UnsafeCast(toNative);
}

public int count => _map.count;
public Type entityType => TypeCache<T>.type;
public ExclusiveGroupStruct groupID { get; }
public int count => _map.count;
public Type entityType => TypeCache<T>.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<T>(Unsafe.Add<T>((void*) _map.GetValues(out _).ToNativeArray(out _)
, (int) index));
return true;
}
}

value = default;
return false;
@@ -52,9 +60,7 @@ namespace Svelto.ECS.Native
public NB<T> GetArrayAndEntityIndex(uint entityID, out uint index)
{
if (_map.TryFindIndex(entityID, out index))
{
return new NB<T>(_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<uint, T> _map;
readonly SveltoDictionaryNative<uint, T> _map;
}
}
#endif

+ 6
- 0
Svelto.ECS/Extensions/Unity/DOTS/Native/NativeEGIDMultiMapper.cs View File

@@ -4,6 +4,12 @@ using Svelto.DataStructures;

namespace Svelto.ECS.Native
{
/// <summary>
/// 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.
/// </summary>
public struct NativeEGIDMultiMapper<T> : IDisposable where T : unmanaged, IEntityComponent
{
public NativeEGIDMultiMapper


+ 3
- 1
Svelto.ECS/Svelto.ECS.csproj View File

@@ -3,6 +3,8 @@
<AssemblyName>Svelto.ECS</AssemblyName>
<LangVersion>8</LangVersion>
<TargetFramework>netstandard2.0</TargetFramework>
<Company>Svelto</Company>
<AssemblyVersion>3.2.1</AssemblyVersion>
</PropertyGroup>
<PropertyGroup>
<PackageId>Svelto.ECS</PackageId>
@@ -23,6 +25,6 @@
<PackageReference Include="System.Memory" Version="4.5.2" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.6.0-preview8.19405.3" />
<None Remove="**\*.meta" />
<ProjectReference Include="..\Svelto.Common\Svelto.Common.csproj" />
<ProjectReference Include="..\com.sebaslab.svelto.common\Svelto.Common.csproj" />
</ItemGroup>
</Project>

+ 2
- 2
Svelto.ECS/package.json View File

@@ -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"
}

+ 1
- 1
Svelto.ECS/version.json View File

@@ -1,3 +1,3 @@
{
"version": "3.2.1"
"version": "3.2.2"
}

Loading…
Cancel
Save