Browse Source

UPM package version 3.4.4

tags/3.4.4
GitHub 1 year ago
parent
commit
6dd6020d51
44 changed files with 760 additions and 464 deletions
  1. +9
    -0
      Core/ComponentBuilder.CheckFields.cs
  2. +81
    -10
      Core/ComponentBuilder.cs
  3. +12
    -14
      Core/EnginesRoot.DoubleBufferedEntitiesToAdd.cs
  4. +33
    -23
      Core/EnginesRoot.Engines.cs
  5. +15
    -16
      Core/EnginesRoot.Entities.cs
  6. +3
    -3
      Core/EnginesRoot.GenericEntityFactory.cs
  7. +1
    -1
      Core/EnginesRoot.GenericEntityFunctions.cs
  8. +21
    -24
      Core/EnginesRoot.Submission.cs
  9. +12
    -12
      Core/EntitiesDB.cs
  10. +18
    -18
      Core/EntitiesOperations.cs
  11. +2
    -2
      Core/EntityCollection.cs
  12. +2
    -2
      Core/EntityDescriptor/DynamicEntityDescriptor.cs
  13. +15
    -0
      Core/EntityDescriptor/IEntityDescriptor.cs
  14. +7
    -8
      Core/EntityFactory.cs
  15. +0
    -1
      Core/EntityInfoView.cs
  16. +7
    -7
      Core/EntityInitializer.cs
  17. +1
    -2
      Core/EntityReference/EnginesRoot.LocatorMap.cs
  18. +89
    -6
      Core/Filters/CombinedFilterID.cs
  19. +20
    -12
      Core/Filters/EnginesRoot.Filters.cs
  20. +167
    -128
      Core/Filters/EntitiesDB.Filters.cs
  21. +2
    -2
      Core/Filters/FilterContextID.cs
  22. +21
    -21
      Core/Filters/Legacy/EntitiesDB.LegacyFilters.cs
  23. +20
    -20
      Core/Groups/EntitiesDB.FindGroups.cs
  24. +50
    -0
      Core/Groups/EntityDescriptorsWarmup.cs
  25. +1
    -1
      Core/Groups/EntityDescriptorsWarmup.cs.meta
  26. +1
    -0
      Core/IComponentBuilder.cs
  27. +10
    -0
      Core/IEngine.cs
  28. +13
    -9
      Core/Streams/EntitiesStreams.cs
  29. +10
    -9
      DataStructures/ITypeSafeDictionary.cs
  30. +17
    -15
      DataStructures/ManagedTypeSafeDictionary.cs
  31. +54
    -24
      DataStructures/TypeSafeDictionaryMethods.cs
  32. +15
    -14
      DataStructures/UnmanagedTypeSafeDictionary.cs
  33. +2
    -2
      Extensions/Native/EnginesRoot.NativeOperation.cs
  34. +2
    -18
      Extensions/Native/NativeComponentFiller.cs
  35. +11
    -0
      Extensions/Native/NativeComponentFiller.cs.meta
  36. +1
    -2
      Extensions/Native/NativeEntityFactory.cs
  37. +1
    -1
      Extensions/Native/NativeEntityInitializer.cs
  38. +1
    -1
      Extensions/Svelto/AllGroupsEnumerable.cs
  39. +2
    -22
      README.md
  40. +2
    -3
      Serialization/EnginesRoot.GenericEntitySerialization.cs
  41. +0
    -1
      Serialization/IEntitySerialization.cs
  42. +4
    -5
      Serialization/SerializableEntityDescriptor.cs
  43. +3
    -3
      Svelto.ECS.csproj
  44. +2
    -2
      package.json

+ 9
- 0
Core/ComponentBuilder.CheckFields.cs View File

@@ -4,6 +4,7 @@ using System.Diagnostics;
#endif
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using Svelto.ECS.Hybrid;

namespace Svelto.ECS
@@ -153,5 +154,13 @@ namespace Svelto.ECS
static readonly Type STRINGBUILDERTYPE = typeof(System.Text.StringBuilder);

internal static readonly Type ENTITY_INFO_COMPONENT = typeof(EntityInfoComponent);
public static ComponentID ENTITY_INFO_COMPONENT_ID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return ComponentTypeID<EntityInfoComponent>.id;
}
}
}
}

+ 81
- 10
Core/ComponentBuilder.cs View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
using DBC.ECS;
using Svelto.Common;
@@ -28,14 +30,42 @@ namespace Svelto.ECS
{
public static int counter;
}
public class ComponentID<T> where T : struct, _IInternalEntityComponent

static public class ComponentTypeMap
{
static readonly FasterDictionary<RefWrapper<Type>, ComponentID> _componentTypeMap = new FasterDictionary<RefWrapper<Type>, ComponentID>();
static readonly FasterDictionary<ComponentID, Type> _reverseComponentTypeMap = new FasterDictionary<ComponentID, Type>();

public static void Add(Type type, ComponentID idData)
{
_componentTypeMap.Add(type, idData);
_reverseComponentTypeMap.Add(idData, type);
}

public static ComponentID FetchID(Type type)
{
return _componentTypeMap[type];
}

public static Type FetchType(ComponentID id)
{
return _reverseComponentTypeMap[id];
}
}

public class ComponentTypeID<T> where T : struct, _IInternalEntityComponent
{
public static readonly SharedStaticWrapper<int, ComponentID<T>> id;
static readonly SharedStaticWrapper<ComponentID, ComponentTypeID<T>> _id;

public static ComponentID id
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _id.Data;
}

//todo: any reason to not do this? If I don't, I cannot Create filters in ready functions and
//I have to remove the CreateFilter method
static ComponentID()
static ComponentTypeID()
{
Init();
}
@@ -46,10 +76,52 @@ namespace Svelto.ECS
#endif
static void Init()
{
id.Data = Interlocked.Increment(ref BurstCompatibleCounter.counter);
Check.Ensure(id.Data < ushort.MaxValue, "too many types registered, HOW :)");
_id.Data = Interlocked.Increment(ref BurstCompatibleCounter.counter);
ComponentTypeMap.Add(typeof(T), id);
}
}

sealed class ComponentIDDebugProxy
{
public ComponentIDDebugProxy(ComponentID id)
{
this._id = id;
}
public Type type => ComponentTypeMap.FetchType(_id);

readonly ComponentID _id;
}
[DebuggerTypeProxy(typeof(ComponentIDDebugProxy))]
public struct ComponentID: IEquatable<ComponentID>
{
public static implicit operator int(ComponentID id)
{
return id._id;
}
public static implicit operator uint(ComponentID id)
{
return (uint)id._id;
}
public static implicit operator ComponentID(int id)
{
return new ComponentID() {_id = id};
}

public bool Equals(ComponentID other)
{
return _id == other._id;
}

public override int GetHashCode()
{
return _id;
}
int _id;
}

public class ComponentBuilder<T> : IComponentBuilder where T : struct, _IInternalEntityComponent
@@ -57,7 +129,6 @@ namespace Svelto.ECS
internal static readonly Type ENTITY_COMPONENT_TYPE;
internal static readonly bool IS_ENTITY_VIEW_COMPONENT;

static readonly T DEFAULT_IT;
static readonly string ENTITY_COMPONENT_NAME;
static readonly bool IS_UNMANAGED;
#if SLOW_SVELTO_SUBMISSION
@@ -68,7 +139,6 @@ namespace Svelto.ECS
static ComponentBuilder()
{
ENTITY_COMPONENT_TYPE = typeof(T);
DEFAULT_IT = default;
IS_ENTITY_VIEW_COMPONENT = typeof(IEntityViewComponent).IsAssignableFrom(ENTITY_COMPONENT_TYPE);
#if SLOW_SVELTO_SUBMISSION
HAS_EGID = typeof(INeedEGID).IsAssignableFrom(ENTITY_COMPONENT_TYPE);
@@ -100,7 +170,7 @@ namespace Svelto.ECS

public ComponentBuilder()
{
_initializer = DEFAULT_IT;
_initializer = default;
}

public ComponentBuilder(in T initializer) : this()
@@ -109,6 +179,7 @@ namespace Svelto.ECS
}

public bool isUnmanaged => IS_UNMANAGED;
public ComponentID getComponentID => ComponentTypeID<T>.id;

static readonly ThreadLocal<EntityViewComponentCache> _localCache = new ThreadLocal<EntityViewComponentCache>(() => new EntityViewComponentCache());



+ 12
- 14
Core/EnginesRoot.DoubleBufferedEntitiesToAdd.cs View File

@@ -1,4 +1,5 @@
using Svelto.DataStructures;
using System;
using Svelto.DataStructures;
using Svelto.ECS.Internal;

namespace Svelto.ECS
@@ -18,9 +19,9 @@ namespace Svelto.ECS
var entitiesCreatedPerGroupA = new FasterDictionary<ExclusiveGroupStruct, uint>();
var entitiesCreatedPerGroupB = new FasterDictionary<ExclusiveGroupStruct, uint>();
var entityComponentsToAddBufferA =
new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>();
new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, ITypeSafeDictionary>>();
var entityComponentsToAddBufferB =
new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>();
new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, ITypeSafeDictionary>>();

_currentNumberEntitiesCreatedPerGroup = entitiesCreatedPerGroupA;
_lastNumberEntitiesCreatedPerGroup = entitiesCreatedPerGroupB;
@@ -149,17 +150,14 @@ namespace Svelto.ECS
(ExclusiveGroupStruct groupID, uint numberOfEntities, IComponentBuilder[] entityComponentsToBuild)
{
void PreallocateDictionaries
(FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>> dic)
(FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, ITypeSafeDictionary>> dic)
{
var group = dic.GetOrAdd(
groupID, () => new FasterDictionary<RefWrapperType, ITypeSafeDictionary>());
groupID, () => new FasterDictionary<ComponentID, ITypeSafeDictionary>());

foreach (var componentBuilder in entityComponentsToBuild)
{
var entityComponentType = componentBuilder.GetEntityComponentType();
var safeDictionary = group.GetOrAdd(new RefWrapperType(entityComponentType)
, () => componentBuilder
.CreateDictionary(numberOfEntities));
var safeDictionary = group.GetOrAdd(componentBuilder.getComponentID, () => componentBuilder.CreateDictionary(numberOfEntities));
componentBuilder.Preallocate(safeDictionary, numberOfEntities);
}
}
@@ -191,10 +189,10 @@ namespace Svelto.ECS
//Before I tried for the third time to use a SparseSet instead of FasterDictionary, remember that
//while group indices are sequential, they may not be used in a sequential order. Sparseset needs
//entities to be created sequentially (the index cannot be managed externally)
internal FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>
internal FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, ITypeSafeDictionary>>
currentComponentsToAddPerGroup;

FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>
FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, ITypeSafeDictionary>>
lastComponentsToAddPerGroup;

/// <summary>
@@ -212,7 +210,7 @@ namespace Svelto.ECS
struct OtherComponentsToAddPerGroupEnumerator
{
public OtherComponentsToAddPerGroupEnumerator
(FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>
(FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, ITypeSafeDictionary>>
lastComponentsToAddPerGroup
, FasterDictionary<ExclusiveGroupStruct, uint> otherNumberEntitiesCreatedPerGroup)
{
@@ -246,7 +244,7 @@ namespace Svelto.ECS
public GroupInfo Current { get; private set; }

//cannot be read only as they will be modified by MoveNext
readonly FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>
readonly FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, ITypeSafeDictionary>>
_lastComponentsToAddPerGroup;

SveltoDictionaryKeyValueEnumerator<ExclusiveGroupStruct, uint,
@@ -258,6 +256,6 @@ namespace Svelto.ECS
struct GroupInfo
{
public ExclusiveGroupStruct group;
public FasterDictionary<RefWrapperType, ITypeSafeDictionary> components;
public FasterDictionary<ComponentID, ITypeSafeDictionary> components;
}
}

+ 33
- 23
Core/EnginesRoot.Engines.cs View File

@@ -16,6 +16,7 @@ namespace Svelto.ECS
{
static EnginesRoot()
{
EntityDescriptorsWarmup.Init();
GroupHashMap.Init();
//SharedDictonary.Init();
SerializationDescriptorMap.Init();
@@ -50,19 +51,21 @@ namespace Svelto.ECS
_nativeAddOperationQueue = new AtomicNativeBags(Allocator.Persistent);
#endif
_serializationDescriptorMap = new SerializationDescriptorMap();
_reactiveEnginesAdd = new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>>();
_reactiveEnginesAdd = new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>>();
_reactiveEnginesAddEx =
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>>();
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>>();
_reactiveEnginesRemove =
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>>();
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>>();
_reactiveEnginesRemoveEx =
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>>();
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>>();
_reactiveEnginesSwap =
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>>();
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>>();
_reactiveEnginesSwapEx =
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>>();
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>>();
_reactiveEnginesDispose =
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>>();
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>>();
_reactiveEnginesDisposeEx =
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>>();

_reactiveEnginesSubmission = new FasterList<IReactOnSubmission>();
_reactiveEnginesSubmissionStarted = new FasterList<IReactOnSubmissionStarted>();
@@ -71,14 +74,14 @@ namespace Svelto.ECS
_disposableEngines = new FasterList<IDisposable>();

_groupEntityComponentsDB =
new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>();
new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, ITypeSafeDictionary>>();
_groupsPerEntity =
new FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>>();
new FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>>();
_groupedEntityToAdd = new DoubleBufferedEntitiesToAdd();
_entityStreams = EntitiesStreams.Create();
#if SVELTO_LEGACY_FILTERS
_groupFilters =
new FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>>();
new FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>>();
#endif
_entityLocator.InitEntityReferenceMap();
_entitiesDB = new EntitiesDB(this, _entityLocator);
@@ -150,6 +153,10 @@ namespace Svelto.ECS
if (engine is IReactOnDispose viewEngineDispose)
CheckReactEngineComponents(
typeof(IReactOnDispose<>), viewEngineDispose, _reactiveEnginesDispose, type.Name);
if (engine is IReactOnDisposeEx viewEngineDisposeEx)
CheckReactEngineComponents(
typeof(IReactOnDisposeEx<>), viewEngineDisposeEx, _reactiveEnginesDisposeEx, type.Name);

if (engine is IReactOnSwap viewEngineSwap)
#pragma warning disable CS0612
@@ -198,18 +205,19 @@ namespace Svelto.ECS
}

static void AddEngineToList<T>(T engine, Type[] entityComponentTypes,
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<T>>> engines, string typeName)
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<T>>> engines, string typeName)
where T : class, IReactEngine
{
for (var i = 0; i < entityComponentTypes.Length; i++)
{
var type = entityComponentTypes[i];

if (engines.TryGetValue(new RefWrapperType(type), out var list) == false)
var componentID = ComponentTypeMap.FetchID(type);
if (engines.TryGetValue(componentID, out var list) == false)
{
list = new FasterList<ReactEngineContainer<T>>();

engines.Add(new RefWrapperType(type), list);
engines.Add(componentID, list);
}

list.Add(new ReactEngineContainer<T>(engine, typeName));
@@ -217,7 +225,7 @@ namespace Svelto.ECS
}

void CheckReactEngineComponents<T>(Type genericDefinition, T engine,
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<T>>> engines, string typeName)
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<T>>> engines, string typeName)
where T : class, IReactEngine
{
var interfaces = engine.GetType().GetInterfaces();
@@ -226,7 +234,7 @@ namespace Svelto.ECS
{
if (interf.IsGenericTypeEx() && interf.GetGenericTypeDefinition() == genericDefinition)
{
var genericArguments = interf.GetGenericArgumentsEx();
Type[] genericArguments = interf.GetGenericArgumentsEx();

AddEngineToList(engine, genericArguments, engines, typeName);
}
@@ -261,7 +269,7 @@ namespace Svelto.ECS
ITypeSafeDictionary typeSafeDictionary = entityList.value;

typeSafeDictionary.ExecuteEnginesDisposeCallbacks_Group(
_reactiveEnginesDispose, groups.key,
_reactiveEnginesDispose, _reactiveEnginesDisposeEx, groups.key,
profiler);
}
catch (Exception e)
@@ -298,6 +306,7 @@ namespace Svelto.ECS
_reactiveEnginesAdd.Clear();
_reactiveEnginesRemove.Clear();
_reactiveEnginesDispose.Clear();
_reactiveEnginesDisposeEx.Clear();
_reactiveEnginesSubmission.Clear();
_reactiveEnginesSubmissionStarted.Clear();

@@ -401,13 +410,14 @@ namespace Svelto.ECS
readonly HashSet<Type> _enginesTypeSet;
readonly EnginesReadyOption _enginesWaitForReady;

readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>> _reactiveEnginesAdd;
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>> _reactiveEnginesAddEx;
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> _reactiveEnginesRemove;
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> _reactiveEnginesRemoveEx;
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>> _reactiveEnginesSwap;
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>> _reactiveEnginesSwapEx;
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> _reactiveEnginesDispose;
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>> _reactiveEnginesAdd;
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>> _reactiveEnginesAddEx;
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> _reactiveEnginesRemove;
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> _reactiveEnginesRemoveEx;
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>> _reactiveEnginesSwap;
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>> _reactiveEnginesSwapEx;
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> _reactiveEnginesDispose;
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>> _reactiveEnginesDisposeEx;

readonly FasterList<IReactOnSubmission> _reactiveEnginesSubmission;
readonly FasterList<IReactOnSubmissionStarted> _reactiveEnginesSubmissionStarted;


+ 15
- 16
Core/EnginesRoot.Entities.cs View File

@@ -62,19 +62,18 @@ namespace Svelto.ECS
void PreallocateDBGroup()
{
var numberOfEntityComponents = entityComponentsToBuild.Length;
FasterDictionary<RefWrapperType, ITypeSafeDictionary> group = GetOrAddDBGroup(groupID);
FasterDictionary<ComponentID, ITypeSafeDictionary> group = GetOrAddDBGroup(groupID);

for (var index = 0; index < numberOfEntityComponents; index++)
{
var entityComponentBuilder = entityComponentsToBuild[index];
var entityComponentType = entityComponentBuilder.GetEntityComponentType();
var entityComponentType = entityComponentBuilder.getComponentID;

var refWrapper = new RefWrapperType(entityComponentType);
var dbList = group.GetOrAdd(refWrapper, () => entityComponentBuilder.CreateDictionary(size));
var dbList = group.GetOrAdd(entityComponentType, () => entityComponentBuilder.CreateDictionary(size));
entityComponentBuilder.Preallocate(dbList, size);

if (_groupsPerEntity.TryGetValue(refWrapper, out var groupedGroup) == false)
groupedGroup = _groupsPerEntity[refWrapper] =
if (_groupsPerEntity.TryGetValue(entityComponentType, out var groupedGroup) == false)
groupedGroup = _groupsPerEntity[entityComponentType] =
new FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>();

groupedGroup[groupID] = dbList;
@@ -87,27 +86,27 @@ namespace Svelto.ECS
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
FasterDictionary<RefWrapperType, ITypeSafeDictionary> GetDBGroup(ExclusiveGroupStruct fromIdGroupId)
FasterDictionary<ComponentID, ITypeSafeDictionary> GetDBGroup(ExclusiveGroupStruct fromIdGroupId)
{
if (_groupEntityComponentsDB.TryGetValue(fromIdGroupId,
out FasterDictionary<RefWrapperType, ITypeSafeDictionary> fromGroup) == false)
out FasterDictionary<ComponentID, ITypeSafeDictionary> fromGroup) == false)
throw new ECSException("Group doesn't exist: ".FastConcat(fromIdGroupId.ToName()));

return fromGroup;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
FasterDictionary<RefWrapperType, ITypeSafeDictionary> GetOrAddDBGroup(ExclusiveGroupStruct toGroupId)
FasterDictionary<ComponentID, ITypeSafeDictionary> GetOrAddDBGroup(ExclusiveGroupStruct toGroupId)
{
return _groupEntityComponentsDB.GetOrAdd(toGroupId,
() => new FasterDictionary<RefWrapperType, ITypeSafeDictionary>());
() => new FasterDictionary<ComponentID, ITypeSafeDictionary>());
}

IComponentBuilder[] FindRealComponents<T>(EGID fromEntityGID) where T : IEntityDescriptor, new()
{
var fromGroup = GetDBGroup(fromEntityGID.groupID);

if (fromGroup.TryGetValue(new RefWrapperType(ComponentBuilderUtilities.ENTITY_INFO_COMPONENT),
if (fromGroup.TryGetValue(ComponentBuilderUtilities.ENTITY_INFO_COMPONENT_ID,
out var entityInfoDic) //<entity ID, EntityInfoComponent>
&& ((ITypeSafeDictionary<EntityInfoComponent>)entityInfoDic).TryGetValue(fromEntityGID.entityID,
out var entityInfo)) //there could be multiple entity descriptors registered in the same group, so it's necessary to check if the entity registered in the group has entityInfoComponent
@@ -129,14 +128,14 @@ namespace Svelto.ECS
return entityInfo.componentsToBuild;
}

return EntityDescriptorTemplate<T>.descriptor.componentsToBuild;
return EntityDescriptorTemplate<T>.realDescriptor.componentsToBuild;
}

IComponentBuilder[] FindRealComponents(EGID fromEntityGID, IComponentBuilder[] baseComponents)
{
var fromGroup = GetDBGroup(fromEntityGID.groupID);

if (fromGroup.TryGetValue(new RefWrapperType(ComponentBuilderUtilities.ENTITY_INFO_COMPONENT),
if (fromGroup.TryGetValue(ComponentBuilderUtilities.ENTITY_INFO_COMPONENT_ID,
out var entityInfoDic) //<entity ID, EntityInfoComponent>
&& ((ITypeSafeDictionary<EntityInfoComponent>)entityInfoDic).TryGetValue(fromEntityGID.entityID,
out var entityInfo)) //there could be multiple entity descriptors registered in the same group, so it's necessary to check if the entity registered in the group has entityInfoComponent
@@ -168,18 +167,18 @@ namespace Svelto.ECS
//ID. This ID doesn't need to be the EGID, it can be just the entityID
//for each group id, save a dictionary indexed by entity type of entities indexed by id
// group EntityComponentType entityID, EntityComponent
internal readonly FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>
internal readonly FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, ITypeSafeDictionary>>
_groupEntityComponentsDB;

//for each entity view type, return the groups (dictionary of entities indexed by entity id) where they are
//found indexed by group id. TypeSafeDictionary are never created, they instead point to the ones hold
//by _groupEntityComponentsDB
// <EntityComponentType <groupID <entityID, EntityComponent>>>
internal readonly FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>>
internal readonly FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>>
_groupsPerEntity;
#if SVELTO_LEGACY_FILTERS
//The filters stored for each component and group
internal readonly FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>>
internal readonly FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>>
_groupFilters;
#endif



+ 3
- 3
Core/EnginesRoot.GenericEntityFactory.cs View File

@@ -20,7 +20,7 @@ namespace Svelto.ECS
, [CallerMemberName] string caller = null) where T : IEntityDescriptor, new()
{
return _enginesRoot.Target.BuildEntity(new EGID(entityID, groupStructId)
, EntityDescriptorTemplate<T>.descriptor.componentsToBuild
, EntityDescriptorTemplate<T>.realDescriptor.componentsToBuild
, TypeCache<T>.type, implementors, caller);
}

@@ -29,7 +29,7 @@ namespace Svelto.ECS
(EGID egid, IEnumerable<object> implementors = null
, [CallerMemberName] string caller = null) where T : IEntityDescriptor, new()
{
return _enginesRoot.Target.BuildEntity(egid, EntityDescriptorTemplate<T>.descriptor.componentsToBuild
return _enginesRoot.Target.BuildEntity(egid, EntityDescriptorTemplate<T>.realDescriptor.componentsToBuild
, TypeCache<T>.type, implementors, caller);
}

@@ -65,7 +65,7 @@ namespace Svelto.ECS
where T : IEntityDescriptor, new()
{
_enginesRoot.Target.Preallocate(groupStructId, numberOfEntities
, EntityDescriptorTemplate<T>.descriptor.componentsToBuild);
, EntityDescriptorTemplate<T>.realDescriptor.componentsToBuild);
}

#if UNITY_NATIVE


+ 1
- 1
Core/EnginesRoot.GenericEntityFunctions.cs View File

@@ -48,7 +48,7 @@ namespace Svelto.ECS
{
if (_enginesRoot.Target._groupEntityComponentsDB.TryGetValue(
fromGroupID.group
, out FasterDictionary<RefWrapperType, ITypeSafeDictionary> entitiesInGroupPerType) == true)
, out FasterDictionary<ComponentID, ITypeSafeDictionary> entitiesInGroupPerType) == true)
{
#if DEBUG && !PROFILE_SVELTO
ITypeSafeDictionary dictionary = entitiesInGroupPerType.unsafeValues[0];


+ 21
- 24
Core/EnginesRoot.Submission.cs View File

@@ -46,7 +46,7 @@ namespace Svelto.ECS
}

static void RemoveEntities(
FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, FasterList<(uint, string)>>>
FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, FasterList<(uint, string)>>>
removeOperations, FasterList<EGID> entitiesRemoved, EnginesRoot enginesRoot)
{
using (var sampler = new PlatformProfiler("remove Entities"))
@@ -94,7 +94,7 @@ namespace Svelto.ECS

foreach (var groupedEntitiesToRemove in entitiesToRemove.value)
{
RefWrapperType componentType = groupedEntitiesToRemove.key;
ComponentID componentType = groupedEntitiesToRemove.key;
ITypeSafeDictionary fromComponentsDictionary = fromGroupDictionary[componentType];

FasterList<(uint, string)> entityIDsToRemove = groupedEntitiesToRemove.value;
@@ -161,7 +161,7 @@ namespace Svelto.ECS
}
}

static void SwapEntities(FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType,
static void SwapEntities(FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID,
FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>> swapEntitiesOperations,
FasterList<(EGID, EGID)> entitiesIDSwaps, EnginesRoot enginesRoot)
{
@@ -262,7 +262,7 @@ namespace Svelto.ECS

//get all the engines linked to TValue
if (!enginesRoot._reactiveEnginesSwap.TryGetValue(
new RefWrapperType(componentType),
componentType,
out var entityComponentsEngines))
continue;

@@ -304,8 +304,7 @@ namespace Svelto.ECS

//get all the engines linked to TValue
if (!enginesRoot._reactiveEnginesSwapEx.TryGetValue(
new RefWrapperType(componentType),
out var entityComponentsEngines))
componentType, out var entityComponentsEngines))
continue;

ExclusiveGroupStruct toGroup = entitiesInfoToSwap.key;
@@ -354,9 +353,8 @@ namespace Svelto.ECS
{
var type = entityComponentsToSubmit.key;
var fromDictionary = entityComponentsToSubmit.value;
var wrapper = new RefWrapperType(type);

var toDictionary = GetOrAddTypeSafeDictionary(groupID, groupDB, wrapper, fromDictionary);
var toDictionary = GetOrAddTypeSafeDictionary(groupID, groupDB, type, fromDictionary);

//all the new entities are added at the end of each dictionary list, so we can
//just iterate the list using the indices ranges added in the _cachedIndices
@@ -385,9 +383,8 @@ namespace Svelto.ECS
foreach (var entityComponentsToSubmit in groupToSubmit.components)
{
var type = entityComponentsToSubmit.key;
var wrapper = new RefWrapperType(type);

var toDictionary = GetTypeSafeDictionary(groupID, groupDB, wrapper);
var toDictionary = GetTypeSafeDictionary(groupID, groupDB, type);
enumerator.MoveNext();
toDictionary.ExecuteEnginesAddEntityCallbacksFast(_reactiveEnginesAddEx, groupID, enumerator.Current, in sampler);
}
@@ -465,15 +462,15 @@ namespace Svelto.ECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void SwapEntitiesBetweenGroups(ExclusiveGroupStruct fromGroupId, ExclusiveGroupStruct toGroupId, PlatformProfiler platformProfiler)
{
FasterDictionary<RefWrapperType, ITypeSafeDictionary> fromGroup = GetDBGroup(fromGroupId);
FasterDictionary<RefWrapperType, ITypeSafeDictionary> toGroup = GetOrAddDBGroup(toGroupId);
FasterDictionary<ComponentID, ITypeSafeDictionary> fromGroup = GetDBGroup(fromGroupId);
FasterDictionary<ComponentID, ITypeSafeDictionary> toGroup = GetOrAddDBGroup(toGroupId);

_entityLocator.UpdateAllGroupReferenceLocators(fromGroupId, toGroupId);

//remove entities from dictionaries
foreach (var dictionaryOfEntities in fromGroup)
{
RefWrapperType refWrapperType = dictionaryOfEntities.key;
var refWrapperType = dictionaryOfEntities.key;

ITypeSafeDictionary fromDictionary = dictionaryOfEntities.value;
ITypeSafeDictionary toDictionary = GetOrAddTypeSafeDictionary(toGroupId, toGroup, refWrapperType, fromDictionary);
@@ -488,7 +485,7 @@ namespace Svelto.ECS
//Call all the callbacks
foreach (var dictionaryOfEntities in fromGroup)
{
RefWrapperType refWrapperType = dictionaryOfEntities.key;
var refWrapperType = dictionaryOfEntities.key;

ITypeSafeDictionary fromDictionary = dictionaryOfEntities.value;
ITypeSafeDictionary toDictionary = GetTypeSafeDictionary(toGroupId, toGroup, refWrapperType);
@@ -509,20 +506,20 @@ namespace Svelto.ECS

[MethodImpl(MethodImplOptions.AggressiveInlining)]
ITypeSafeDictionary GetOrAddTypeSafeDictionary(ExclusiveGroupStruct groupId,
FasterDictionary<RefWrapperType, ITypeSafeDictionary> groupPerComponentType, RefWrapperType type,
FasterDictionary<ComponentID, ITypeSafeDictionary> groupPerComponentType, ComponentID typeID,
ITypeSafeDictionary fromDictionary)
{
//be sure that the TypeSafeDictionary for the entity Type exists
if (groupPerComponentType.TryGetValue(type, out ITypeSafeDictionary toEntitiesDictionary) == false)
if (groupPerComponentType.TryGetValue(typeID, out ITypeSafeDictionary toEntitiesDictionary) == false)
{
toEntitiesDictionary = fromDictionary.Create();
groupPerComponentType.Add(type, toEntitiesDictionary);
groupPerComponentType.Add(typeID, toEntitiesDictionary);
}

{
//update GroupsPerEntity
if (_groupsPerEntity.TryGetValue(type, out var groupedGroup) == false)
groupedGroup = _groupsPerEntity[type] =
if (_groupsPerEntity.TryGetValue(typeID, out var groupedGroup) == false)
groupedGroup = _groupsPerEntity[typeID] =
new FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>();

groupedGroup[groupId] = toEntitiesDictionary;
@@ -533,7 +530,7 @@ namespace Svelto.ECS

[MethodImpl(MethodImplOptions.AggressiveInlining)]
static ITypeSafeDictionary GetTypeSafeDictionary(ExclusiveGroupStruct groupID,
FasterDictionary<RefWrapperType, ITypeSafeDictionary> @group, RefWrapperType refWrapper)
FasterDictionary<ComponentID, ITypeSafeDictionary> @group, ComponentID refWrapper)
{
if (@group.TryGetValue(refWrapper, out ITypeSafeDictionary fromTypeSafeDictionary) == false)
{
@@ -553,12 +550,12 @@ namespace Svelto.ECS
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

static readonly
Action<FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType,
Action<FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID,
FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>>, FasterList<(EGID, EGID)>
, EnginesRoot> _swapEntities;

static readonly Action<
FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, FasterList<(uint, string)>>>,
FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, FasterList<(uint, string)>>>,
FasterList<EGID>, EnginesRoot> _removeEntities;

static readonly Action<ExclusiveGroupStruct, EnginesRoot> _removeGroup;


+ 12
- 12
Core/EntitiesDB.cs View File

@@ -19,7 +19,7 @@ namespace Svelto.ECS
}

EntityCollection<T> InternalQueryEntities<T>
(FasterDictionary<RefWrapperType, ITypeSafeDictionary> entitiesInGroupPerType)
(FasterDictionary<ComponentID, ITypeSafeDictionary> entitiesInGroupPerType)
where T : struct, _IInternalEntityComponent
{
uint count = 0;
@@ -236,7 +236,7 @@ namespace Svelto.ECS
public bool ExistsAndIsNotEmpty(ExclusiveGroupStruct gid)
{
if (groupEntityComponentsDB.TryGetValue(
gid, out FasterDictionary<RefWrapperType, ITypeSafeDictionary> group) == true)
gid, out FasterDictionary<ComponentID, ITypeSafeDictionary> group) == true)
{
return group.count > 0;
}
@@ -265,17 +265,17 @@ namespace Svelto.ECS
return (int)typeSafeDictionary.count;
}

public bool FoundInGroups<T1>() where T1 : _IInternalEntityComponent
public bool FoundInGroups<T>() where T : struct, _IInternalEntityComponent
{
return groupsPerComponent.ContainsKey(TypeRefWrapper<T1>.wrapper);
return groupsPerComponent.ContainsKey(ComponentTypeID<T>.id);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
bool SafeQueryEntityDictionary<T>
(out ITypeSafeDictionary typeSafeDictionary
, FasterDictionary<RefWrapperType, ITypeSafeDictionary> entitiesInGroupPerType) where T : _IInternalEntityComponent
, FasterDictionary<ComponentID, ITypeSafeDictionary> entitiesInGroupPerType) where T : struct, _IInternalEntityComponent
{
if (entitiesInGroupPerType.TryGetValue(new RefWrapperType(TypeCache<T>.type), out var safeDictionary)
if (entitiesInGroupPerType.TryGetValue(ComponentTypeID<T>.id, out var safeDictionary)
== false)
{
typeSafeDictionary = default;
@@ -290,9 +290,9 @@ namespace Svelto.ECS

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal bool SafeQueryEntityDictionary<T>
(ExclusiveGroupStruct group, out ITypeSafeDictionary typeSafeDictionary) where T : _IInternalEntityComponent
(ExclusiveGroupStruct group, out ITypeSafeDictionary typeSafeDictionary) where T : struct, _IInternalEntityComponent
{
if (UnsafeQueryEntityDictionary(group, TypeCache<T>.type, out var safeDictionary) == false)
if (UnsafeQueryEntityDictionary(group, ComponentTypeID<T>.id, out var safeDictionary) == false)
{
typeSafeDictionary = default;
return false;
@@ -306,7 +306,7 @@ namespace Svelto.ECS

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal bool UnsafeQueryEntityDictionary
(ExclusiveGroupStruct group, Type type, out ITypeSafeDictionary typeSafeDictionary)
(ExclusiveGroupStruct group, ComponentID id, out ITypeSafeDictionary typeSafeDictionary)
{
//search for the group
if (groupEntityComponentsDB.TryGetValue(group, out var entitiesInGroupPerType) == false)
@@ -316,7 +316,7 @@ namespace Svelto.ECS
}

//search for the indexed entities in the group
return entitiesInGroupPerType.TryGetValue(new RefWrapperType(type), out typeSafeDictionary);
return entitiesInGroupPerType.TryGetValue(id, out typeSafeDictionary);
}

static readonly FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> _emptyDictionary =
@@ -330,14 +330,14 @@ namespace Svelto.ECS
//group, then indexable per type, then indexable per EGID. however the TypeSafeDictionary can return an array of
//values directly, that can be iterated over, so that is possible to iterate over all the entity components of
//a specific type inside a specific group.
FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>
FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, ITypeSafeDictionary>>
groupEntityComponentsDB => _enginesRoot._groupEntityComponentsDB;

//for each entity view type, return the groups (dictionary of entities indexed by entity id) where they are
//found indexed by group id. TypeSafeDictionary are never created, they instead point to the ones hold
//by _groupEntityComponentsDB
// <EntityComponentType <groupID <entityID, EntityComponent>>>
FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>> groupsPerComponent =>
FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>> groupsPerComponent =>
_enginesRoot._groupsPerEntity;

EnginesRoot.EntityReferenceMap _entityReferencesMap;


+ 18
- 18
Core/EntitiesOperations.cs View File

@@ -43,7 +43,7 @@ namespace Svelto.ECS
foreach (var operation in componentBuilders)
{
removedComponentsPerType //recycle or create dictionaries per component type
.RecycleOrAdd(new RefWrapperType(operation.GetEntityComponentType()), _newList, _clearList)
.RecycleOrAdd(operation.getComponentID, _newList, _clearList)
//add entity to remove
.Add((entityEgid.entityID, caller));
}
@@ -72,7 +72,7 @@ namespace Svelto.ECS
//Get the dictionary for each component that holds the list of entities to swap
swappedComponentsPerType //recycle or create dictionaries per component type
.RecycleOrAdd(new RefWrapperType(operation.GetEntityComponentType()), _newGroupDictionary, _recycleDicitionaryWithCaller)
.RecycleOrAdd(operation.getComponentID, _newGroupDictionary, _recycleDicitionaryWithCaller)
//recycle or create list of entities to swap
.RecycleOrAdd(toID.groupID, _newListWithCaller, _clearListWithCaller)
//add entity to swap
@@ -86,9 +86,9 @@ namespace Svelto.ECS
return _thisSubmissionInfo.AnyOperationQueued();
}

public void ExecuteRemoveAndSwappingOperations(Action<FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType,
public void ExecuteRemoveAndSwappingOperations(Action<FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID,
FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>>, FasterList<(EGID, EGID)>,
EnginesRoot> swapEntities, Action<FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, FasterList<(uint, string)>>>,
EnginesRoot> swapEntities, Action<FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, FasterList<(uint, string)>>>,
FasterList<EGID>, EnginesRoot> removeEntities, Action<ExclusiveGroupStruct, EnginesRoot> removeGroup,
Action<ExclusiveGroupStruct, ExclusiveGroupStruct, EnginesRoot> swapGroup, EnginesRoot enginesRoot)
{
@@ -137,12 +137,12 @@ namespace Svelto.ECS
_lastSubmittedInfo.Clear();
}
FasterDictionary<RefWrapperType, FasterList<(uint, string)>> NewGroupsDictionary()
FasterDictionary<ComponentID, FasterList<(uint, string)>> NewGroupsDictionary()
{
return new FasterDictionary<RefWrapperType, FasterList<(uint, string)>>();
return new FasterDictionary<ComponentID, FasterList<(uint, string)>>();
}
void RecycleDictionary(ref FasterDictionary<RefWrapperType, FasterList<(uint, string)>> recycled)
void RecycleDictionary(ref FasterDictionary<ComponentID, FasterList<(uint, string)>> recycled)
{
recycled.Recycle();
}
@@ -172,13 +172,13 @@ namespace Svelto.ECS
return new FasterList<(uint, uint, string)>();
}

FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>> NewGroupsDictionaryWithCaller()
FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>> NewGroupsDictionaryWithCaller()
{
return new FasterDictionary<RefWrapperType, //add case
return new FasterDictionary<ComponentID, //add case
FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>();
}

void RecycleGroupDictionaryWithCaller(ref FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>> recycled)
void RecycleGroupDictionaryWithCaller(ref FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>> recycled)
{
recycled.Recycle();
}
@@ -191,13 +191,13 @@ namespace Svelto.ECS
struct Info
{
//from group //actual component type
internal FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType,
internal FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID,
// to group ID //entityIDs , debugInfo
FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>>
_currentSwapEntitiesOperations;

internal FasterDictionary<ExclusiveGroupStruct,
FasterDictionary<RefWrapperType, FasterList<(uint, string)>>> _currentRemoveEntitiesOperations;
FasterDictionary<ComponentID, FasterList<(uint, string)>>> _currentRemoveEntitiesOperations;

internal FasterList<(EGID, EGID)> _entitiesSwapped;
internal FasterList<EGID> _entitiesRemoved;
@@ -229,11 +229,11 @@ namespace Svelto.ECS
_groupsToSwap = new FasterList<(ExclusiveBuildGroup, ExclusiveBuildGroup, string)>();

_currentSwapEntitiesOperations =
new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType,
new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID,
FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>>();
_currentRemoveEntitiesOperations =
new FasterDictionary<ExclusiveGroupStruct,
FasterDictionary<RefWrapperType, FasterList<(uint, string)>>>();
FasterDictionary<ComponentID, FasterList<(uint, string)>>>();
}
}

@@ -241,12 +241,12 @@ namespace Svelto.ECS
Info _thisSubmissionInfo;

readonly Func<FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>> _newGroupDictionary;
readonly Func<FasterDictionary<RefWrapperType, FasterList<(uint, string)>>> _newGroupsDictionary;
readonly ActionRef<FasterDictionary<RefWrapperType, FasterList<(uint, string)>>> _recycleDictionary;
readonly Func<FasterDictionary<ComponentID, FasterList<(uint, string)>>> _newGroupsDictionary;
readonly ActionRef<FasterDictionary<ComponentID, FasterList<(uint, string)>>> _recycleDictionary;
readonly Func<FasterList<(uint, string)>> _newList;
readonly ActionRef<FasterList<(uint, string)>> _clearList;
readonly Func<FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>> _newGroupsDictionaryWithCaller;
readonly ActionRef<FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>> _recycleGroupDictionaryWithCaller;
readonly Func<FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>> _newGroupsDictionaryWithCaller;
readonly ActionRef<FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>> _recycleGroupDictionaryWithCaller;
readonly ActionRef<FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>> _recycleDicitionaryWithCaller;
readonly Func<FasterList<(uint, uint, string)>> _newListWithCaller;
readonly ActionRef<FasterList<(uint, uint, string)>> _clearListWithCaller;


+ 2
- 2
Core/EntityCollection.cs View File

@@ -17,8 +17,8 @@ namespace Svelto.ECS

public uint count { get; }

internal readonly IBufferBase _buffer;
internal readonly IEntityIDs _entityIDs;
public readonly IBufferBase _buffer;
public readonly IEntityIDs _entityIDs;
}

public readonly ref struct EntityCollection<T1, T2> where T1 : struct, _IInternalEntityComponent


+ 2
- 2
Core/EntityDescriptor/DynamicEntityDescriptor.cs View File

@@ -16,7 +16,7 @@ namespace Svelto.ECS
{
internal DynamicEntityDescriptor(bool isExtendible) : this()
{
var defaultEntities = EntityDescriptorTemplate<TType>.descriptor.componentsToBuild;
var defaultEntities = EntityDescriptorTemplate<TType>.realDescriptor.componentsToBuild;
var length = defaultEntities.Length;

if (FetchEntityInfoComponent(defaultEntities) == -1)
@@ -56,7 +56,7 @@ namespace Svelto.ECS

public void ExtendWith<T>() where T : IEntityDescriptor, new()
{
var extraEntities = EntityDescriptorTemplate<T>.descriptor.componentsToBuild;
var extraEntities = EntityDescriptorTemplate<T>.realDescriptor.componentsToBuild;

_componentsToBuild = Construct(extraEntities.Length, extraEntities);
}


+ 15
- 0
Core/EntityDescriptor/IEntityDescriptor.cs View File

@@ -1,5 +1,20 @@
namespace Svelto.ECS
{
/// <summary>
/// When implementing IEntityDescriptor directly the pattern to use is the following:
///
/// class DoofusEntityDescriptor: IEntityDescriptor
/// {
/// public IComponentBuilder[] componentsToBuild { get; } =
/// {
/// new ComponentBuilder<PositionEntityComponent>()
/// , new ComponentBuilder<DOTSEntityComponent>()
/// , new ComponentBuilder<VelocityEntityComponent>()
/// , new ComponentBuilder<SpeedEntityComponent>()
/// , ...
/// };
/// }
/// </summary>
public interface IEntityDescriptor
{
IComponentBuilder[] componentsToBuild { get; }


+ 7
- 8
Core/EntityFactory.cs View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using Svelto.DataStructures;

@@ -5,7 +6,7 @@ namespace Svelto.ECS.Internal
{
static class EntityFactory
{
public static FasterDictionary<RefWrapperType, ITypeSafeDictionary> BuildGroupedEntities
public static FasterDictionary<ComponentID, ITypeSafeDictionary> BuildGroupedEntities
(EGID egid, EnginesRoot.DoubleBufferedEntitiesToAdd groupEntitiesToAdd, IComponentBuilder[] componentsToBuild
, IEnumerable<object> implementors
#if DEBUG && !PROFILE_SVELTO
@@ -14,7 +15,7 @@ namespace Svelto.ECS.Internal
)
{
var group = groupEntitiesToAdd.currentComponentsToAddPerGroup.GetOrAdd(
egid.groupID, () => new FasterDictionary<RefWrapperType, ITypeSafeDictionary>());
egid.groupID, () => new FasterDictionary<ComponentID, ITypeSafeDictionary>());

//track the number of entities created so far in the group.
groupEntitiesToAdd.IncrementEntityCount(egid.groupID);
@@ -29,7 +30,7 @@ namespace Svelto.ECS.Internal
}

static void BuildEntitiesAndAddToGroup
(EGID entityID, FasterDictionary<RefWrapperType, ITypeSafeDictionary> @group
(EGID entityID, FasterDictionary<ComponentID, ITypeSafeDictionary> @group
, IComponentBuilder[] componentBuilders, IEnumerable<object> implementors
#if DEBUG && !PROFILE_SVELTO
, System.Type descriptorType
@@ -64,12 +65,10 @@ namespace Svelto.ECS.Internal
}
}

static void BuildEntity
(EGID entityID, FasterDictionary<RefWrapperType, ITypeSafeDictionary> group
, IComponentBuilder componentBuilder, IEnumerable<object> implementors)
static void BuildEntity(EGID entityID, FasterDictionary<ComponentID, ITypeSafeDictionary> group,
IComponentBuilder componentBuilder, IEnumerable<object> implementors)
{
var entityComponentType = componentBuilder.GetEntityComponentType();
ITypeSafeDictionary safeDictionary = group.GetOrAdd(new RefWrapperType(entityComponentType)
ITypeSafeDictionary safeDictionary = group.GetOrAdd(componentBuilder.getComponentID
, (ref IComponentBuilder cb) => cb.CreateDictionary(1)
, ref componentBuilder);



+ 0
- 1
Core/EntityInfoView.cs View File

@@ -1,5 +1,4 @@
using Svelto.ECS.Hybrid;
using Svelto.ECS.Internal;

namespace Svelto.ECS
{


+ 7
- 7
Core/EntityInitializer.cs View File

@@ -6,7 +6,7 @@ namespace Svelto.ECS
{
public readonly ref struct EntityInitializer
{
public EntityInitializer(EGID id, FasterDictionary<RefWrapperType, ITypeSafeDictionary> group,
public EntityInitializer(EGID id, FasterDictionary<ComponentID, ITypeSafeDictionary> group,
in EntityReference reference)
{
_group = group;
@@ -20,7 +20,7 @@ namespace Svelto.ECS
public void Init<T>(T initializer) where T : struct, _IInternalEntityComponent
{
if (_group.TryGetValue(
new RefWrapperType(TypeCache<T>.type),
ComponentTypeID<T>.id,
out var typeSafeDictionary) == false)
return;

@@ -34,10 +34,10 @@ namespace Svelto.ECS
dictionary.GetDirectValueByRef(findElementIndex) = initializer;
}

internal ref T GetOrAdd<T>() where T : unmanaged, IEntityComponent
internal ref T GetOrAdd<T>() where T : struct, _IInternalEntityComponent
{
ref var entityDictionary = ref _group.GetOrAdd(
new RefWrapperType(ComponentBuilder<T>.ENTITY_COMPONENT_TYPE),
ComponentTypeID<T>.id,
() => new UnmanagedTypeSafeDictionary<T>(1));
var dictionary = (ITypeSafeDictionary<T>)entityDictionary;

@@ -46,14 +46,14 @@ namespace Svelto.ECS

public ref T Get<T>() where T : struct, _IInternalEntityComponent
{
return ref (_group[new RefWrapperType(TypeCache<T>.type)] as ITypeSafeDictionary<T>)
return ref (_group[ComponentTypeID<T>.id] as ITypeSafeDictionary<T>)
.GetValueByRef(_ID.entityID);
}

public bool Has<T>() where T : struct, _IInternalEntityComponent
{
if (_group.TryGetValue(
new RefWrapperType(TypeCache<T>.type),
ComponentTypeID<T>.id,
out var typeSafeDictionary))
{
var dictionary = (ITypeSafeDictionary<T>)typeSafeDictionary;
@@ -66,6 +66,6 @@ namespace Svelto.ECS
}

readonly EGID _ID;
readonly FasterDictionary<RefWrapperType, ITypeSafeDictionary> _group;
readonly FasterDictionary<ComponentID, ITypeSafeDictionary> _group;
}
}

+ 1
- 2
Core/EntityReference/EnginesRoot.LocatorMap.cs View File

@@ -1,5 +1,4 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.CompilerServices;
using Svelto.Common;
using Svelto.DataStructures;
using Svelto.DataStructures.Native;


+ 89
- 6
Core/Filters/CombinedFilterID.cs View File

@@ -1,15 +1,30 @@
namespace Svelto.ECS
using System;
using System.Runtime.CompilerServices;
using Svelto.ECS.Internal;

namespace Svelto.ECS
{
public readonly struct CombinedFilterID
{
internal readonly long id;
public FilterContextID contextID => new FilterContextID((uint)((id & 0xFFFF0000) >> 16));
public uint filterID => (uint)(id >> 32);
//filter (32) | contextID (16) | component type (16)
readonly long id;

//a context ID is 16bit
public FilterContextID contextID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new FilterContextID((ushort)((id & 0xFFFF0000) >> 16));
}

public uint filterID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => (uint)(id >> 32);
}

public CombinedFilterID(int filterID, FilterContextID contextID)
{
id = (long)filterID << 32 | (uint)contextID.id << 16;
id = (long)filterID << 32 | (long)contextID.id << 16;
}

public static implicit operator CombinedFilterID((int filterID, FilterContextID contextID) data)
@@ -17,4 +32,72 @@
return new CombinedFilterID(data.filterID, data.contextID);
}
}

readonly struct CombinedFilterComponentID: IEquatable<CombinedFilterComponentID>
{
//filter (32) | contextID (16) | component type (16)
internal readonly long id;

//a context ID is 16bit
public FilterContextID contextID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return new FilterContextID((ushort)((id & 0xFFFF0000) >> 16));
}
}

public uint filterID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return (uint)(id >> 32);
}
}
public uint contextComponentID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return (uint)(id & 0xFFFF);
}
}

public CombinedFilterComponentID(int filterID, FilterContextID contextID)
{
id = (long)filterID << 32 | (uint)contextID.id << 16;
}

public CombinedFilterComponentID(uint filterIdFilterId, FilterContextID filterIdContextId, ComponentID componentid)
{
id = (long)filterIdFilterId << 32 | (long)filterIdContextId.id << 16 | (long)(uint)componentid;
}

public bool Equals(CombinedFilterComponentID other)
{
return id == other.id;
}

public override int GetHashCode()
{
return id.GetHashCode();
}
}

public static class CombinedFilterIDExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static CombinedFilterComponentID CombineComponent<T>(this CombinedFilterID filterID)
where T : struct, _IInternalEntityComponent
{
var componentid = ComponentTypeID<T>.id;

DBC.ECS.Check.Require(componentid < ushort.MaxValue, "too many component types registered, HOW :)");

return new CombinedFilterComponentID(filterID.filterID, filterID.contextID, componentid);
}
}
}

+ 20
- 12
Core/Filters/EnginesRoot.Filters.cs View File

@@ -8,10 +8,12 @@ namespace Svelto.ECS
{
void InitFilters()
{
_transientEntityFilters = new SharedSveltoDictionaryNative<long, EntityFilterCollection>(0);
_persistentEntityFilters = new SharedSveltoDictionaryNative<long, EntityFilterCollection>(0);
_transientEntityFilters = new SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection>(0);
_persistentEntityFilters = new SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection>(0);
_indicesOfPersistentFiltersUsedByThisComponent =
new SharedSveltoDictionaryNative<NativeRefWrapperType, NativeDynamicArrayCast<int>>(0);
new SharedSveltoDictionaryNative<ComponentID, NativeDynamicArrayCast<int>>(0);
_indicesOfTransientFiltersUsedByThisComponent =
new SharedSveltoDictionaryNative<ComponentID, NativeDynamicArrayCast<int>>(0);
}

void DisposeFilters()
@@ -20,7 +22,12 @@ namespace Svelto.ECS
{
filter.value.Dispose();
}

foreach (var filter in _indicesOfTransientFiltersUsedByThisComponent)
{
filter.value.Dispose();
}
foreach (var filter in _persistentEntityFilters)
{
filter.value.Dispose();
@@ -34,6 +41,7 @@ namespace Svelto.ECS
_transientEntityFilters.Dispose();
_persistentEntityFilters.Dispose();
_indicesOfPersistentFiltersUsedByThisComponent.Dispose();
_indicesOfTransientFiltersUsedByThisComponent.Dispose();
}

void ClearTransientFilters()
@@ -54,12 +62,12 @@ namespace Svelto.ECS
/// <param name="fromDic"></param>
/// <param name="entityIDsLeftAndAffectedByRemoval"></param>
void RemoveEntitiesFromPersistentFilters
(FasterList<(uint entityID, string)> entityIDsRemoved, ExclusiveGroupStruct fromGroup, RefWrapperType refWrapperType
(FasterList<(uint entityID, string)> entityIDsRemoved, ExclusiveGroupStruct fromGroup, ComponentID refWrapperType
, ITypeSafeDictionary fromDic, FasterList<uint> entityIDsLeftAndAffectedByRemoval)
{
//is there any filter used by this component?
if (_indicesOfPersistentFiltersUsedByThisComponent.TryGetValue(
new NativeRefWrapperType(refWrapperType), out NativeDynamicArrayCast<int> listOfFilters) == true)
refWrapperType, out NativeDynamicArrayCast<int> listOfFilters) == true)
{
var numberOfFilters = listOfFilters.count;
var filters = _persistentEntityFilters.unsafeValues;
@@ -117,11 +125,11 @@ namespace Svelto.ECS
void SwapEntityBetweenPersistentFilters
(FasterList<(uint, uint, string)> fromEntityToEntityIDs, ITypeSafeDictionary fromDic
, ITypeSafeDictionary toDic, ExclusiveGroupStruct fromGroup, ExclusiveGroupStruct toGroup
, RefWrapperType refWrapperType, FasterList<uint> entityIDsLeftAndAffectedByRemoval)
, ComponentID refWrapperType, FasterList<uint> entityIDsLeftAndAffectedByRemoval)
{
//is there any filter used by this component?
if (_indicesOfPersistentFiltersUsedByThisComponent.TryGetValue(
new NativeRefWrapperType(refWrapperType), out NativeDynamicArrayCast<int> listOfFilters) == true)
refWrapperType, out NativeDynamicArrayCast<int> listOfFilters) == true)
{
DBC.ECS.Check.Require(listOfFilters.count > 0, "why are you calling this with an empty list?");
var numberOfFilters = listOfFilters.count;
@@ -181,10 +189,10 @@ namespace Svelto.ECS
}
}

internal SharedSveltoDictionaryNative<long, EntityFilterCollection> _transientEntityFilters;
internal SharedSveltoDictionaryNative<long, EntityFilterCollection> _persistentEntityFilters;
internal SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection> _transientEntityFilters;
internal SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection> _persistentEntityFilters;

internal SharedSveltoDictionaryNative<NativeRefWrapperType, NativeDynamicArrayCast<int>>
_indicesOfPersistentFiltersUsedByThisComponent;
internal SharedSveltoDictionaryNative<ComponentID, NativeDynamicArrayCast<int>> _indicesOfPersistentFiltersUsedByThisComponent;
public SharedSveltoDictionaryNative<ComponentID, NativeDynamicArrayCast<int>> _indicesOfTransientFiltersUsedByThisComponent;
}
}

+ 167
- 128
Core/Filters/EntitiesDB.Filters.cs View File

@@ -13,15 +13,12 @@ namespace Svelto.ECS
{
//since the user can choose their own filterID, in order to avoid collisions between
//filters of the same type, the FilterContext is provided. The type is identified through
//TypeCounter
public static long CombineFilterIDs<T>(CombinedFilterID combinedFilterID)
//ComponentTypeID<T>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static CombinedFilterComponentID CombineFilterIDWithComponentID<T>(CombinedFilterID combinedFilterID)
where T : struct, _IInternalEntityComponent
{
var id = (uint)ComponentID<T>.id.Data;
var combineFilterIDs = (long)combinedFilterID.id | id;

return combineFilterIDs;
return combinedFilterID.CombineComponent<T>();
}
}

@@ -31,7 +28,9 @@ namespace Svelto.ECS
{
return new SveltoFilters(
_enginesRoot._persistentEntityFilters,
_enginesRoot._indicesOfPersistentFiltersUsedByThisComponent, _enginesRoot._transientEntityFilters);
_enginesRoot._indicesOfPersistentFiltersUsedByThisComponent,
_enginesRoot._transientEntityFilters,
_enginesRoot._indicesOfTransientFiltersUsedByThisComponent);
}

/// <summary>
@@ -47,45 +46,45 @@ namespace Svelto.ECS
#endif
public static FilterContextID GetNewContextID()
{
return new FilterContextID((uint)Interlocked.Increment(ref uniqueContextID.Data));
return new FilterContextID((ushort)Interlocked.Increment(ref uniqueContextID.Data));
}

public SveltoFilters(SharedSveltoDictionaryNative<long, EntityFilterCollection> persistentEntityFilters,
SharedSveltoDictionaryNative<NativeRefWrapperType, NativeDynamicArrayCast<int>>
indicesOfPersistentFiltersUsedByThisComponent,
SharedSveltoDictionaryNative<long, EntityFilterCollection> transientEntityFilters)
internal SveltoFilters(SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection> persistentEntityFilters,
SharedSveltoDictionaryNative<ComponentID, NativeDynamicArrayCast<int>> indicesOfPersistentFiltersUsedByThisComponent,
SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection> transientEntityFilters,
SharedSveltoDictionaryNative<ComponentID, NativeDynamicArrayCast<int>> indicesOfTransientFiltersUsedByThisComponent)
{
_persistentEntityFilters = persistentEntityFilters;
_indicesOfPersistentFiltersUsedByThisComponent = indicesOfPersistentFiltersUsedByThisComponent;
_transientEntityFilters = transientEntityFilters;
_indicesOfTransientFiltersUsedByThisComponent = indicesOfTransientFiltersUsedByThisComponent;
}

#if UNITY_BURST //the following methods do not make sense without burst as they are workaround for burst
public ref EntityFilterCollection GetOrCreatePersistentFilter<T>(int filterID,
FilterContextID filterContextId, NativeRefWrapperType typeRef)
where T : unmanaged, IEntityComponent
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityFilterCollection GetOrCreatePersistentFilter<T>(int filterID, FilterContextID filterContextId)
where T : struct, _IInternalEntityComponent
{
return ref GetOrCreatePersistentFilter<T>(new CombinedFilterID(filterID, filterContextId), typeRef);
return ref GetOrCreatePersistentFilter<T>(new CombinedFilterID(filterID, filterContextId));
}

public ref EntityFilterCollection GetOrCreatePersistentFilter<T>(CombinedFilterID filterID,
NativeRefWrapperType typeRef)
where T : unmanaged, IEntityComponent
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityFilterCollection GetOrCreatePersistentFilter<T>(CombinedFilterID filterID) where T : struct, _IInternalEntityComponent
{
long combineFilterIDs = Internal_FilterHelper.CombineFilterIDs<T>(filterID);
var componentAndFilterID = Internal_FilterHelper.CombineFilterIDWithComponentID<T>(filterID);

if (_persistentEntityFilters.TryFindIndex(combineFilterIDs, out var index) == true)
if (_persistentEntityFilters.TryFindIndex(componentAndFilterID, out var index) == true)
return ref _persistentEntityFilters.GetDirectValueByRef(index);

_persistentEntityFilters.Add(combineFilterIDs, new EntityFilterCollection(filterID));
_persistentEntityFilters.Add(componentAndFilterID, new EntityFilterCollection(filterID));

var lastIndex = _persistentEntityFilters.count - 1;

if (_indicesOfPersistentFiltersUsedByThisComponent.TryFindIndex(typeRef, out var getIndex) == false)
var componentId = ComponentTypeID<T>.id;
if (_indicesOfPersistentFiltersUsedByThisComponent.TryFindIndex(componentId, out var getIndex) == false)
{
var newArray = new NativeDynamicArrayCast<int>(1, Allocator.Persistent);
newArray.Add(lastIndex);
_indicesOfPersistentFiltersUsedByThisComponent.Add(typeRef, newArray);
_indicesOfPersistentFiltersUsedByThisComponent.Add(componentId, newArray);
}
else
{
@@ -95,7 +94,6 @@ namespace Svelto.ECS

return ref _persistentEntityFilters.GetDirectValueByRef((uint)lastIndex);
}
#endif

/// <summary>
/// Create a persistent filter. Persistent filters are not deleted after each submission,
@@ -104,57 +102,26 @@ namespace Svelto.ECS
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>

#if UNITY_BURST && UNITY_COLLECTIONS
[Unity.Burst.BurstDiscard] //not burst compatible because of TypeRefWrapper<T>.wrapper;
[Unity.Burst.BurstDiscard] //not burst compatible because of ComponentTypeID<T>.id and GetOrAdd callback;
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityFilterCollection GetOrCreatePersistentFilter<T>(int filterID,
FilterContextID filterContextId)
where T : unmanaged, _IInternalEntityComponent
{
return ref GetOrCreatePersistentFilter<T>(new CombinedFilterID(filterID, filterContextId));
}
#if UNITY_BURST && UNITY_COLLECTIONS
[Unity.Burst.BurstDiscard] //not burst compatible because of TypeRefWrapper<T>.wrapper and GetOrAdd callback;
#endif
public ref EntityFilterCollection GetOrCreatePersistentFilter<T>(CombinedFilterID filterID)
where T : unmanaged, _IInternalEntityComponent
{
long combineFilterIDs = Internal_FilterHelper.CombineFilterIDs<T>(filterID);

if (_persistentEntityFilters.TryFindIndex(combineFilterIDs, out var index) == true)
return ref _persistentEntityFilters.GetDirectValueByRef(index);

var typeRef = TypeRefWrapper<T>.wrapper;
var filterCollection = new EntityFilterCollection(filterID);

_persistentEntityFilters.Add(combineFilterIDs, filterCollection);

var lastIndex = _persistentEntityFilters.count - 1;

_indicesOfPersistentFiltersUsedByThisComponent.GetOrAdd(new NativeRefWrapperType(typeRef), _builder).Add(lastIndex);

return ref _persistentEntityFilters.GetDirectValueByRef((uint)lastIndex);
}
#if UNITY_BURST && UNITY_COLLECTIONS
[Unity.Burst.BurstDiscard] //not burst compatible because of TypeRefWrapper<T>.wrapper and GetOrAdd callback;
#endif
public ref EntityFilterCollection CreatePersistentFilter<T>(CombinedFilterID filterID)
where T : unmanaged, _IInternalEntityComponent
where T : struct, _IInternalEntityComponent
{
long combineFilterIDs = Internal_FilterHelper.CombineFilterIDs<T>(filterID);
var componentAndFilterID = Internal_FilterHelper.CombineFilterIDWithComponentID<T>(filterID);

if (_persistentEntityFilters.TryFindIndex(combineFilterIDs, out var index) == true)
if (_persistentEntityFilters.TryFindIndex(componentAndFilterID, out var index) == true)
throw new ECSException("filter already exists");

var typeRef = TypeRefWrapper<T>.wrapper;
var filterCollection = new EntityFilterCollection(filterID);

_persistentEntityFilters.Add(combineFilterIDs, filterCollection);
_persistentEntityFilters.Add(componentAndFilterID, filterCollection);

var lastIndex = _persistentEntityFilters.count - 1;

_indicesOfPersistentFiltersUsedByThisComponent.GetOrAdd(new NativeRefWrapperType(typeRef), _builder).Add(lastIndex);
_indicesOfPersistentFiltersUsedByThisComponent.GetOrAdd(ComponentTypeID<T>.id, _builder).Add(lastIndex);

return ref _persistentEntityFilters.GetDirectValueByRef((uint)lastIndex);
}
@@ -166,18 +133,18 @@ namespace Svelto.ECS

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityFilterCollection GetPersistentFilter<T>(int filterID, FilterContextID filterContextId)
where T : unmanaged, _IInternalEntityComponent
where T : struct, _IInternalEntityComponent
{
return ref GetPersistentFilter<T>(new CombinedFilterID(filterID, filterContextId));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityFilterCollection GetPersistentFilter<T>(CombinedFilterID filterID)
where T : unmanaged, _IInternalEntityComponent
where T : struct, _IInternalEntityComponent
{
long combineFilterIDs = Internal_FilterHelper.CombineFilterIDs<T>(filterID);
var componentAndFilterID = Internal_FilterHelper.CombineFilterIDWithComponentID<T>(filterID);

if (_persistentEntityFilters.TryFindIndex(combineFilterIDs, out var index) == true)
if (_persistentEntityFilters.TryFindIndex(componentAndFilterID, out var index) == true)
return ref _persistentEntityFilters.GetDirectValueByRef(index);

throw new ECSException("filter not found");
@@ -186,11 +153,11 @@ namespace Svelto.ECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetPersistentFilter<T>(CombinedFilterID combinedFilterID,
out EntityFilterCollection entityCollection)
where T : unmanaged, _IInternalEntityComponent
where T : struct, _IInternalEntityComponent
{
long combineFilterIDs = Internal_FilterHelper.CombineFilterIDs<T>(combinedFilterID);
var componentAndFilterID = Internal_FilterHelper.CombineFilterIDWithComponentID<T>(combinedFilterID);

if (_persistentEntityFilters.TryFindIndex(combineFilterIDs, out var index) == true)
if (_persistentEntityFilters.TryFindIndex(componentAndFilterID, out var index) == true)
{
entityCollection = _persistentEntityFilters.GetDirectValueByRef(index);
return true;
@@ -200,12 +167,15 @@ namespace Svelto.ECS
return false;
}

/// <summary>
/// Svelto.ECS tracks the filters linked to each
/// component. This allows to iterate over all the filters of a given filter context linked to a component.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EntityFilterCollectionsEnumerator GetPersistentFilters<T>()
where T : unmanaged, _IInternalEntityComponent
where T : struct, _IInternalEntityComponent
{
if (_indicesOfPersistentFiltersUsedByThisComponent.TryFindIndex(
new NativeRefWrapperType(new RefWrapperType(typeof(T))), out var index) == true)
if (_indicesOfPersistentFiltersUsedByThisComponent.TryFindIndex(ComponentTypeID<T>.id, out var index) == true)
return new EntityFilterCollectionsEnumerator(
_indicesOfPersistentFiltersUsedByThisComponent.GetDirectValueByRef(index),
_persistentEntityFilters);
@@ -215,9 +185,9 @@ namespace Svelto.ECS

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EntityFilterCollectionsWithContextEnumerator GetPersistentFilters<T>(FilterContextID filterContextId)
where T : struct, _IInternalEntityComponent
{
if (_indicesOfPersistentFiltersUsedByThisComponent.TryFindIndex(
new NativeRefWrapperType(new RefWrapperType(typeof(T))), out var index) == true)
if (_indicesOfPersistentFiltersUsedByThisComponent.TryFindIndex(ComponentTypeID<T>.id, out var index) == true)
return new EntityFilterCollectionsWithContextEnumerator(
_indicesOfPersistentFiltersUsedByThisComponent.GetDirectValueByRef(index),
_persistentEntityFilters, filterContextId);
@@ -228,13 +198,12 @@ namespace Svelto.ECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetPersistentFilters<T>(FilterContextID filterContextId,
out EntityFilterCollectionsWithContextEnumerator enumerator)
where T : struct, _IInternalEntityComponent
{
if (_indicesOfPersistentFiltersUsedByThisComponent.TryFindIndex(
new NativeRefWrapperType(new RefWrapperType(typeof(T))), out var index) == true)
if (_indicesOfPersistentFiltersUsedByThisComponent.TryFindIndex(ComponentTypeID<T>.id, out var index) == true)
{
enumerator = new EntityFilterCollectionsWithContextEnumerator(
_indicesOfPersistentFiltersUsedByThisComponent.GetDirectValueByRef(index),
_persistentEntityFilters, filterContextId);
ref var filterIndices = ref _indicesOfPersistentFiltersUsedByThisComponent.GetDirectValueByRef(index);
enumerator = new EntityFilterCollectionsWithContextEnumerator(filterIndices, _persistentEntityFilters, filterContextId);

return true;
}
@@ -245,32 +214,49 @@ namespace Svelto.ECS

/// <summary>
/// Creates a transient filter. Transient filters are deleted after each submission
/// transient filters are identified by filterID and Context and can be linked to several groups.
/// So for each group there can be as many as necessary transient filters with different ID and contextID
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityFilterCollection GetOrCreateTransientFilter<T>(CombinedFilterID filterID)
where T : unmanaged, _IInternalEntityComponent
public ref EntityFilterCollection GetOrCreateTransientFilter<T>(CombinedFilterID combinedFilterID, bool trackFilter = false)
where T : struct, _IInternalEntityComponent
{
var combineFilterIDs = Internal_FilterHelper.CombineFilterIDs<T>(filterID);
var componentAndFilterID = Internal_FilterHelper.CombineFilterIDWithComponentID<T>(combinedFilterID);

if (_transientEntityFilters.TryFindIndex(combineFilterIDs, out var index))
if (_transientEntityFilters.TryFindIndex(componentAndFilterID, out var index))
return ref _transientEntityFilters.GetDirectValueByRef(index);

var filterCollection = new EntityFilterCollection(filterID);
return ref InternalCreateTransientFilter<T>(combinedFilterID, componentAndFilterID, trackFilter);
}

_transientEntityFilters.Add(combineFilterIDs, filterCollection);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityFilterCollection GetOrCreateTransientFilter<T>(int filterID, FilterContextID filterContextId)
where T : struct, _IInternalEntityComponent
{
return ref GetOrCreateTransientFilter<T>(new CombinedFilterID(filterID, filterContextId));
}

return ref _transientEntityFilters.GetDirectValueByRef((uint)(_transientEntityFilters.count - 1));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityFilterCollection CreateTransientFilter<T>(CombinedFilterID combinedFilterID, bool trackFilter = false)
where T : struct, _IInternalEntityComponent
{
CombinedFilterComponentID componentAndFilterID = Internal_FilterHelper.CombineFilterIDWithComponentID<T>(combinedFilterID);
#if DEBUG && !PROFILE_SVELTO
if (_transientEntityFilters.TryFindIndex(componentAndFilterID, out _))
throw new ECSException($"filter already exists {TypeCache<T>.name}");
#endif
return ref InternalCreateTransientFilter<T>(combinedFilterID, componentAndFilterID, trackFilter);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetTransientFilter<T>(CombinedFilterID filterID, out EntityFilterCollection entityCollection)
where T : unmanaged, _IInternalEntityComponent
where T : struct, _IInternalEntityComponent
{
var combineFilterIDs = Internal_FilterHelper.CombineFilterIDs<T>(filterID);
var componentAndFilterID = Internal_FilterHelper.CombineFilterIDWithComponentID<T>(filterID);

if (_transientEntityFilters.TryFindIndex(combineFilterIDs, out var index))
if (_transientEntityFilters.TryFindIndex(componentAndFilterID, out var index))
{
entityCollection = _transientEntityFilters.GetDirectValueByRef(index);
return true;
@@ -279,37 +265,89 @@ namespace Svelto.ECS
entityCollection = default;
return false;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityFilterCollection GetTransientFilter<T>(CombinedFilterID filterID)
where T : unmanaged, _IInternalEntityComponent
where T : struct, _IInternalEntityComponent
{
var combineFilterIDs = Internal_FilterHelper.CombineFilterIDs<T>(filterID);
var componentAndFilterID = Internal_FilterHelper.CombineFilterIDWithComponentID<T>(filterID);

if (_transientEntityFilters.TryFindIndex(combineFilterIDs, out var index))
if (_transientEntityFilters.TryFindIndex(componentAndFilterID, out var index))
{
return ref _transientEntityFilters.GetDirectValueByRef(index);
}
throw new ECSException($"no filters associated with the type {TypeCache<T>.name}");
}
public void CreateTransientFilter<T>(CombinedFilterID filterID)

/// <summary>
/// Svelto.ECS tracks the filters linked to each
/// component. This allows to iterate over all the filters of a given filter context linked to a component.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EntityFilterCollectionsEnumerator GetTransientFilters<T>()
where T : struct, _IInternalEntityComponent
{
if (_indicesOfTransientFiltersUsedByThisComponent.TryFindIndex(ComponentTypeID<T>.id, out var index) == true)
return new EntityFilterCollectionsEnumerator(
_indicesOfTransientFiltersUsedByThisComponent.GetDirectValueByRef(index),
_transientEntityFilters);

throw new ECSException($"no filters associated with the type {TypeCache<T>.name}");
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EntityFilterCollectionsWithContextEnumerator GetTransientFilters<T>(FilterContextID filterContextId)
where T : struct, _IInternalEntityComponent
{
if (_indicesOfTransientFiltersUsedByThisComponent.TryFindIndex(ComponentTypeID<T>.id, out var index) == true)
return new EntityFilterCollectionsWithContextEnumerator(
_indicesOfTransientFiltersUsedByThisComponent.GetDirectValueByRef(index),
_transientEntityFilters, filterContextId);

throw new ECSException($"no filters associated with the type {TypeCache<T>.name}");
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetTransientFilters<T>(FilterContextID filterContextId, out EntityFilterCollectionsWithContextEnumerator enumerator)
where T : struct, _IInternalEntityComponent
{
if (_indicesOfTransientFiltersUsedByThisComponent.TryFindIndex(ComponentTypeID<T>.id, out var index) == true)
{
enumerator = new EntityFilterCollectionsWithContextEnumerator(
_indicesOfTransientFiltersUsedByThisComponent.GetDirectValueByRef(index),
_transientEntityFilters, filterContextId);

return true;
}

enumerator = default;
return false;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
ref EntityFilterCollection InternalCreateTransientFilter<T>(CombinedFilterID filterID, CombinedFilterComponentID componentAndFilterID,
bool trackFilter)
where T : struct, _IInternalEntityComponent
{
var combineFilterIDs = Internal_FilterHelper.CombineFilterIDs<T>(filterID);
#if DEBUG && !PROFILE_SVELTO
if (_transientEntityFilters.TryFindIndex(combineFilterIDs, out _))
throw new ECSException($"filter already exists {TypeCache<T>.name}");
#endif
var filterCollection = new EntityFilterCollection(filterID);

_transientEntityFilters.Add(combineFilterIDs, filterCollection);
_transientEntityFilters.Add(componentAndFilterID, filterCollection);

if (trackFilter)
{
var typeRef = ComponentTypeID<T>.id;
var lastIndex = _transientEntityFilters.count - 1;
_indicesOfTransientFiltersUsedByThisComponent.GetOrAdd(ComponentTypeID<T>.id, _builder).Add(lastIndex);
}

return ref _transientEntityFilters.GetDirectValueByRef((uint)(_transientEntityFilters.count - 1));
}
public struct EntityFilterCollectionsEnumerator
{
public EntityFilterCollectionsEnumerator(NativeDynamicArrayCast<int> getDirectValueByRef,
SharedSveltoDictionaryNative<long, EntityFilterCollection> sharedSveltoDictionaryNative): this()
internal EntityFilterCollectionsEnumerator(NativeDynamicArrayCast<int> getDirectValueByRef,
SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection> sharedSveltoDictionaryNative): this()
{
_getDirectValueByRef = getDirectValueByRef;
_sharedSveltoDictionaryNative = sharedSveltoDictionaryNative;
@@ -336,24 +374,24 @@ namespace Svelto.ECS
public ref EntityFilterCollection Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return ref _sharedSveltoDictionaryNative.GetDirectValueByRef((uint)_currentIndex - 1);
}
get => ref _sharedSveltoDictionaryNative.GetDirectValueByRef((uint)_currentIndex - 1);
}

readonly NativeDynamicArrayCast<int> _getDirectValueByRef;
readonly SharedSveltoDictionaryNative<long, EntityFilterCollection> _sharedSveltoDictionaryNative;
readonly SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection> _sharedSveltoDictionaryNative;
int _currentIndex;
}

/// <summary>
/// TODO: ABSOLUTELY UNIT TEST THIS AS THE CODE WAS WRONG!!!
/// </summary>
public struct EntityFilterCollectionsWithContextEnumerator
{
public EntityFilterCollectionsWithContextEnumerator(NativeDynamicArrayCast<int> getDirectValueByRef,
SharedSveltoDictionaryNative<long, EntityFilterCollection> sharedSveltoDictionaryNative,
internal EntityFilterCollectionsWithContextEnumerator(NativeDynamicArrayCast<int> filterIndices,
SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection> sharedSveltoDictionaryNative,
FilterContextID filterContextId): this()
{
_getDirectValueByRef = getDirectValueByRef;
_filterIndices = filterIndices;
_sharedSveltoDictionaryNative = sharedSveltoDictionaryNative;
_filterContextId = filterContextId;
}
@@ -366,11 +404,11 @@ namespace Svelto.ECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext()
{
while (_currentIndex++ < _getDirectValueByRef.count &&
_sharedSveltoDictionaryNative.GetDirectValueByRef((uint)_currentIndex - 1).combinedFilterID
.contextID.id != _filterContextId.id) ;
while (_currentIndex++ < _filterIndices.count &&
_sharedSveltoDictionaryNative.GetDirectValueByRef((uint)_filterIndices[(uint)_currentIndex - 1]).combinedFilterID
.contextID.id != _filterContextId.id);

if (_currentIndex - 1 < _getDirectValueByRef.count)
if (_currentIndex - 1 < _filterIndices.count)
return true;

return false;
@@ -379,24 +417,25 @@ namespace Svelto.ECS
public ref EntityFilterCollection Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return ref _sharedSveltoDictionaryNative.GetDirectValueByRef((uint)_currentIndex - 1);
}
get => ref _sharedSveltoDictionaryNative.GetDirectValueByRef((uint)_filterIndices[(uint)_currentIndex - 1]);
}

readonly NativeDynamicArrayCast<int> _getDirectValueByRef;
readonly SharedSveltoDictionaryNative<long, EntityFilterCollection> _sharedSveltoDictionaryNative;
readonly NativeDynamicArrayCast<int> _filterIndices;
readonly SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection> _sharedSveltoDictionaryNative;
readonly FilterContextID _filterContextId;
int _currentIndex;
}

readonly SharedSveltoDictionaryNative<long, EntityFilterCollection> _persistentEntityFilters;
readonly SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection> _persistentEntityFilters;

readonly SharedSveltoDictionaryNative<NativeRefWrapperType, NativeDynamicArrayCast<int>>
readonly SharedSveltoDictionaryNative<ComponentID, NativeDynamicArrayCast<int>>
_indicesOfPersistentFiltersUsedByThisComponent;

readonly SharedSveltoDictionaryNative<long, EntityFilterCollection> _transientEntityFilters;
readonly SharedSveltoDictionaryNative<CombinedFilterComponentID, EntityFilterCollection> _transientEntityFilters;

readonly SharedSveltoDictionaryNative<ComponentID, NativeDynamicArrayCast<int>>
_indicesOfTransientFiltersUsedByThisComponent;

static readonly Func<NativeDynamicArrayCast<int>> _builder = Builder;
}
}

+ 2
- 2
Core/Filters/FilterContextID.cs View File

@@ -2,9 +2,9 @@
{
public struct FilterContextID
{
public readonly uint id;
public readonly ushort id;

internal FilterContextID(uint id)
internal FilterContextID(ushort id)
{
DBC.ECS.Check.Require(id < ushort.MaxValue, "too many types registered, HOW :)");



+ 21
- 21
Core/Filters/Legacy/EntitiesDB.LegacyFilters.cs View File

@@ -16,7 +16,7 @@ namespace Svelto.ECS
/// </summary>
public partial class EntitiesDB
{
FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>> _filters =>
FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>> _filters =>
_enginesRoot._groupFilters;

public LegacyFilters GetLegacyFilters()
@@ -27,7 +27,7 @@ namespace Svelto.ECS
public readonly struct LegacyFilters
{
public LegacyFilters(
FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>>
FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>>
filtersLegacy)
{
_filtersLegacy = filtersLegacy;
@@ -36,14 +36,14 @@ namespace Svelto.ECS
public ref LegacyFilterGroup CreateOrGetFilterForGroup<T>(int filterID, ExclusiveGroupStruct groupID)
where T : struct, _IInternalEntityComponent
{
var refWrapper = TypeRefWrapper<T>.wrapper;
var refWrapper = ComponentTypeID<T>.id;

return ref CreateOrGetFilterForGroup(filterID, groupID, refWrapper);
}

public bool HasFiltersForGroup<T>(ExclusiveGroupStruct groupID) where T : struct, _IInternalEntityComponent
{
if (_filtersLegacy.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == false)
if (_filtersLegacy.TryGetValue(ComponentTypeID<T>.id, out var fasterDictionary) == false)
return false;

return fasterDictionary.ContainsKey(groupID);
@@ -52,7 +52,7 @@ namespace Svelto.ECS
public bool HasFilterForGroup<T>(int filterID, ExclusiveGroupStruct groupID)
where T : struct, _IInternalEntityComponent
{
if (_filtersLegacy.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == false)
if (_filtersLegacy.TryGetValue(ComponentTypeID<T>.id, out var fasterDictionary) == false)
return false;

if (fasterDictionary.TryGetValue(groupID, out var result))
@@ -64,7 +64,7 @@ namespace Svelto.ECS
public ref LegacyGroupFilters CreateOrGetFiltersForGroup<T>(ExclusiveGroupStruct groupID)
where T : struct, _IInternalEntityComponent
{
var fasterDictionary = _filtersLegacy.GetOrAdd(TypeRefWrapper<T>.wrapper,
var fasterDictionary = _filtersLegacy.GetOrAdd(ComponentTypeID<T>.id,
() => new FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>());

return ref fasterDictionary.GetOrAdd(groupID,
@@ -75,27 +75,27 @@ namespace Svelto.ECS
where T : struct, _IInternalEntityComponent
{
#if DEBUG && !PROFILE_SVELTO
if (_filtersLegacy.ContainsKey(TypeRefWrapper<T>.wrapper) == false)
if (_filtersLegacy.ContainsKey(ComponentTypeID<T>.id) == false)
throw new ECSException($"trying to fetch not existing filters, type {typeof(T)}");
if (_filtersLegacy[TypeRefWrapper<T>.wrapper].ContainsKey(groupID) == false)
if (_filtersLegacy[ComponentTypeID<T>.id].ContainsKey(groupID) == false)
throw new ECSException(
$"trying to fetch not existing filters, type {typeof(T)} group {groupID.ToName()}");
#endif

return ref _filtersLegacy[TypeRefWrapper<T>.wrapper].GetValueByRef(groupID);
return ref _filtersLegacy[ComponentTypeID<T>.id].GetValueByRef(groupID);
}

public ref LegacyFilterGroup GetFilterForGroup<T>(int filterId, ExclusiveGroupStruct groupID)
where T : struct, _IInternalEntityComponent
{
#if DEBUG && !PROFILE_SVELTO
if (_filtersLegacy.ContainsKey(TypeRefWrapper<T>.wrapper) == false)
if (_filtersLegacy.ContainsKey(ComponentTypeID<T>.id) == false)
throw new ECSException($"trying to fetch not existing filters, type {typeof(T)}");
if (_filtersLegacy[TypeRefWrapper<T>.wrapper].ContainsKey(groupID) == false)
if (_filtersLegacy[ComponentTypeID<T>.id].ContainsKey(groupID) == false)
throw new ECSException(
$"trying to fetch not existing filters, type {typeof(T)} group {groupID.ToName()}");
#endif
return ref _filtersLegacy[TypeRefWrapper<T>.wrapper][groupID].GetFilter(filterId);
return ref _filtersLegacy[ComponentTypeID<T>.id][groupID].GetFilter(filterId);
}

public bool TryGetFilterForGroup<T>(int filterId, ExclusiveGroupStruct groupID,
@@ -103,7 +103,7 @@ namespace Svelto.ECS
{
groupLegacyFilter = default;

if (_filtersLegacy.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == false)
if (_filtersLegacy.TryGetValue(ComponentTypeID<T>.id, out var fasterDictionary) == false)
return false;

if (fasterDictionary.TryGetValue(groupID, out var groupFilters) == false)
@@ -120,7 +120,7 @@ namespace Svelto.ECS
{
legacyGroupFilters = default;

if (_filtersLegacy.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == false)
if (_filtersLegacy.TryGetValue(ComponentTypeID<T>.id, out var fasterDictionary) == false)
return false;

return fasterDictionary.TryGetValue(groupID, out legacyGroupFilters);
@@ -128,7 +128,7 @@ namespace Svelto.ECS

public void ClearFilter<T>(int filterID, ExclusiveGroupStruct exclusiveGroupStruct)
{
if (_filtersLegacy.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary))
if (_filtersLegacy.TryGetValue(ComponentTypeID<T>.id, out var fasterDictionary))
{
Check.Require(fasterDictionary.ContainsKey(exclusiveGroupStruct),
$"trying to clear filter not present in group {exclusiveGroupStruct}");
@@ -139,14 +139,14 @@ namespace Svelto.ECS

public void ClearFilters<T>(int filterID)
{
if (_filtersLegacy.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary))
if (_filtersLegacy.TryGetValue(ComponentTypeID<T>.id, out var fasterDictionary))
foreach (var filtersPerGroup in fasterDictionary)
filtersPerGroup.value.ClearFilter(filterID);
}

public void DisposeFilters<T>(ExclusiveGroupStruct exclusiveGroupStruct)
{
if (_filtersLegacy.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary))
if (_filtersLegacy.TryGetValue(ComponentTypeID<T>.id, out var fasterDictionary))
{
fasterDictionary[exclusiveGroupStruct].DisposeFilters();
fasterDictionary.Remove(exclusiveGroupStruct);
@@ -155,16 +155,16 @@ namespace Svelto.ECS

public void DisposeFilters<T>()
{
if (_filtersLegacy.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary))
if (_filtersLegacy.TryGetValue(ComponentTypeID<T>.id, out var fasterDictionary))
foreach (var filtersPerGroup in fasterDictionary)
filtersPerGroup.value.DisposeFilters();

_filtersLegacy.Remove(TypeRefWrapper<T>.wrapper);
_filtersLegacy.Remove(ComponentTypeID<T>.id);
}

public void DisposeFilterForGroup<T>(int resetFilterID, ExclusiveGroupStruct group)
{
if (_filtersLegacy.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary))
if (_filtersLegacy.TryGetValue(ComponentTypeID<T>.id, out var fasterDictionary))
fasterDictionary[@group].DisposeFilter(resetFilterID);
}

@@ -205,7 +205,7 @@ namespace Svelto.ECS
return ref filters.CreateOrGetFilter(filterID);
}

readonly FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>>
readonly FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>>
_filtersLegacy;
}
}


+ 20
- 20
Core/Groups/EntitiesDB.FindGroups.cs View File

@@ -7,11 +7,11 @@ namespace Svelto.ECS
{
public partial class EntitiesDB
{
public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1>(bool ignoreDisabledBit = false) where T1 : _IInternalEntityComponent
public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1>(bool ignoreDisabledBit = false) where T1 : struct, _IInternalEntityComponent
{
FasterList<ExclusiveGroupStruct> result = localgroups.Value.groupArray;
result.Clear();
if (groupsPerComponent.TryGetValue(TypeRefWrapper<T1>.wrapper
if (groupsPerComponent.TryGetValue(ComponentTypeID<T1>.id
, out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> result1)
== false)
return result;
@@ -31,15 +31,15 @@ namespace Svelto.ECS
}

public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1, T2>(bool ignoreDisabledBit = false)
where T1 : _IInternalEntityComponent where T2 : _IInternalEntityComponent
where T1 : struct, _IInternalEntityComponent where T2 : struct, _IInternalEntityComponent
{
FasterList<ExclusiveGroupStruct> result = localgroups.Value.groupArray;
result.Clear();
if (groupsPerComponent.TryGetValue(TypeRefWrapper<T1>.wrapper
if (groupsPerComponent.TryGetValue(ComponentTypeID<T1>.id
, out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> result1)
== false)
return result;
if (groupsPerComponent.TryGetValue(TypeRefWrapper<T2>.wrapper
if (groupsPerComponent.TryGetValue(ComponentTypeID<T2>.id
, out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> result2)
== false)
return result;
@@ -82,18 +82,18 @@ namespace Svelto.ECS
/// <typeparam name="T3"></typeparam>
/// <returns></returns>
public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1, T2, T3>(bool ignoreDisabledBit = false)
where T1 : _IInternalEntityComponent where T2 : _IInternalEntityComponent where T3 : _IInternalEntityComponent
where T1 : struct, _IInternalEntityComponent where T2 : struct, _IInternalEntityComponent where T3 : struct, _IInternalEntityComponent
{
FasterList<FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>> localArray =
localgroups.Value.listOfGroups;

if (groupsPerComponent.TryGetValue(TypeRefWrapper<T1>.wrapper, out localArray[0]) == false || localArray[0].count == 0)
if (groupsPerComponent.TryGetValue(ComponentTypeID<T1>.id, out localArray[0]) == false || localArray[0].count == 0)
return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
if (groupsPerComponent.TryGetValue(TypeRefWrapper<T2>.wrapper, out localArray[1]) == false || localArray[1].count == 0)
if (groupsPerComponent.TryGetValue(ComponentTypeID<T2>.id, out localArray[1]) == false || localArray[1].count == 0)
return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
if (groupsPerComponent.TryGetValue(TypeRefWrapper<T3>.wrapper, out localArray[2]) == false || localArray[2].count == 0)
if (groupsPerComponent.TryGetValue(ComponentTypeID<T3>.id, out localArray[2]) == false || localArray[2].count == 0)
return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);

@@ -131,24 +131,24 @@ namespace Svelto.ECS
}

public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1, T2, T3, T4>(bool ignoreDisabledBit = false)
where T1 : _IInternalEntityComponent
where T2 : _IInternalEntityComponent
where T3 : _IInternalEntityComponent
where T4 : _IInternalEntityComponent
where T1 : struct, _IInternalEntityComponent
where T2 : struct, _IInternalEntityComponent
where T3 : struct, _IInternalEntityComponent
where T4 : struct, _IInternalEntityComponent
{
FasterList<FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>> localArray =
localgroups.Value.listOfGroups;

if (groupsPerComponent.TryGetValue(TypeRefWrapper<T1>.wrapper, out localArray[0]) == false || localArray[0].count == 0)
if (groupsPerComponent.TryGetValue(ComponentTypeID<T1>.id, out localArray[0]) == false || localArray[0].count == 0)
return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
if (groupsPerComponent.TryGetValue(TypeRefWrapper<T2>.wrapper, out localArray[1]) == false || localArray[1].count == 0)
if (groupsPerComponent.TryGetValue(ComponentTypeID<T2>.id, out localArray[1]) == false || localArray[1].count == 0)
return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
if (groupsPerComponent.TryGetValue(TypeRefWrapper<T3>.wrapper, out localArray[2]) == false || localArray[2].count == 0)
if (groupsPerComponent.TryGetValue(ComponentTypeID<T3>.id, out localArray[2]) == false || localArray[2].count == 0)
return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
if (groupsPerComponent.TryGetValue(TypeRefWrapper<T4>.wrapper, out localArray[3]) == false || localArray[3].count == 0)
if (groupsPerComponent.TryGetValue(ComponentTypeID<T4>.id, out localArray[3]) == false || localArray[3].count == 0)
return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);

@@ -192,12 +192,12 @@ namespace Svelto.ECS
, (uint) localGroups.count);
}

internal FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> FindGroups_INTERNAL(Type type)
internal FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> FindGroups_INTERNAL(ComponentID type)
{
if (groupsPerComponent.ContainsKey(new RefWrapperType(type)) == false)
if (groupsPerComponent.ContainsKey(type) == false)
return _emptyDictionary;

return groupsPerComponent[new RefWrapperType(type)];
return groupsPerComponent[type];
}

struct GroupsList


+ 50
- 0
Core/Groups/EntityDescriptorsWarmup.cs View File

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Reflection;

namespace Svelto.ECS
{
public static class EntityDescriptorsWarmup
{
/// <summary>
/// c# Static constructors are guaranteed to be thread safe
/// Warmup all EntityDescriptors and ComponentTypeID classes to avoid huge overheads when they are first used
/// </summary>
internal static void Init()
{
List<Assembly> assemblies = AssemblyUtility.GetCompatibleAssemblies();
foreach (Assembly assembly in assemblies)
{
var typeOfEntityDescriptors = typeof(IEntityDescriptor);

foreach (Type type in AssemblyUtility.GetTypesSafe(assembly))
{
if (typeOfEntityDescriptors.IsAssignableFrom(type)) //IsClass and IsSealed and IsAbstract means only static classes
{
var warmup = typeof(EntityDescriptorTemplate<>).MakeGenericType(type);
try
{
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(warmup.TypeHandle);
}
catch
{
continue;
}

PropertyInfo field = warmup.GetProperty("descriptor", BindingFlags.Static | BindingFlags.Public);
object value = field.GetValue(null); // pass null because the field is static

// cast the value to your descriptor type
IEntityDescriptor descriptor = (IEntityDescriptor)value;
foreach (IComponentBuilder component in descriptor.componentsToBuild)
{
var typeArguments = component.GetEntityComponentType();
var warmup2 = typeof(ComponentTypeID<>).MakeGenericType(typeArguments);
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(warmup2.TypeHandle);
}
}
}
}
}
}
}

Core/GlobalTypeID.cs.meta → Core/Groups/EntityDescriptorsWarmup.cs.meta View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 37971713191c36abbf22e12726eac5b1
guid: 0abcbdd66d64357796e4b06b85b4c726
MonoImporter:
externalObjects: {}
serializedVersion: 2

+ 1
- 0
Core/IComponentBuilder.cs View File

@@ -12,5 +12,6 @@ namespace Svelto.ECS

Type GetEntityComponentType();
bool isUnmanaged { get; }
ComponentID getComponentID { get; }
}
}

+ 10
- 0
Core/IEngine.cs View File

@@ -40,6 +40,10 @@ namespace Svelto.ECS.Internal
public interface IReactOnSwapEx : IReactEngine
{
}
public interface IReactOnDisposeEx : IReactEngine
{
}

public interface IReactOnDispose : IReactEngine
{
@@ -132,6 +136,12 @@ namespace Svelto.ECS
void MovedTo((uint start, uint end) rangeOfEntities, in EntityCollection<T> entities,
ExclusiveGroupStruct fromGroup, ExclusiveGroupStruct toGroup);
}
public interface IReactOnDisposeEx<T> : IReactOnDisposeEx where T : struct, _IInternalEntityComponent
{
void Remove((uint start, uint end) rangeOfEntities, in EntityCollection<T> entities,
ExclusiveGroupStruct groupID);
}

/// <summary>
/// Interface to mark an Engine as reacting after each entities submission phase


+ 13
- 9
Core/Streams/EntitiesStreams.cs View File

@@ -18,25 +18,29 @@ namespace Svelto.ECS
internal Consumer<T> GenerateConsumer<T>(string name, uint capacity)
where T : unmanaged, _IInternalEntityComponent
{
if (_streams.ContainsKey(TypeRefWrapper<T>.wrapper) == false)
_streams[TypeRefWrapper<T>.wrapper] = new EntityStream<T>();
var componentId = ComponentTypeID<T>.id;
if (_streams.ContainsKey(componentId) == false)
_streams[componentId] = new EntityStream<T>();

return (_streams[TypeRefWrapper<T>.wrapper] as EntityStream<T>).GenerateConsumer(name, capacity);
return (_streams[componentId] as EntityStream<T>).GenerateConsumer(name, capacity);
}

public Consumer<T> GenerateConsumer<T>(ExclusiveGroupStruct group, string name, uint capacity)
where T : unmanaged, _IInternalEntityComponent
{
if (_streams.ContainsKey(TypeRefWrapper<T>.wrapper) == false)
_streams[TypeRefWrapper<T>.wrapper] = new EntityStream<T>();
var componentId = ComponentTypeID<T>.id;
if (_streams.ContainsKey(componentId) == false)
_streams[componentId] = new EntityStream<T>();

var typeSafeStream = (EntityStream<T>) _streams[TypeRefWrapper<T>.wrapper];
var typeSafeStream = (EntityStream<T>) _streams[componentId];
return typeSafeStream.GenerateConsumer(group, name, capacity);
}

internal void PublishEntity<T>(ref T entity, EGID egid) where T : unmanaged, _IInternalEntityComponent
{
if (_streams.TryGetValue(TypeRefWrapper<T>.wrapper, out var typeSafeStream))
if (_streams.TryGetValue(ComponentTypeID<T>.id, out var typeSafeStream))
(typeSafeStream as EntityStream<T>).PublishEntity(ref entity, egid);
else
Console.LogDebug($"No Consumers are waiting for this entity to change {typeof(T)}");
@@ -51,11 +55,11 @@ namespace Svelto.ECS
public static EntitiesStreams Create()
{
var stream = new EntitiesStreams();
stream._streams = FasterDictionary<RefWrapperType, ITypeSafeStream>.Construct();
stream._streams = FasterDictionary<ComponentID, ITypeSafeStream>.Construct();

return stream;
}

FasterDictionary<RefWrapperType, ITypeSafeStream> _streams;
FasterDictionary<ComponentID, ITypeSafeStream> _streams;
}
}

+ 10
- 9
DataStructures/ITypeSafeDictionary.cs View File

@@ -39,11 +39,11 @@ namespace Svelto.ECS.Internal

//This is now obsolete, but I cannot mark it as such because it's heavily used by legacy projects
void ExecuteEnginesAddCallbacks
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDb
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDb
, ITypeSafeDictionary destinationDatabase, ExclusiveGroupStruct toGroup, in PlatformProfiler profiler);
//Version to use
void ExecuteEnginesAddEntityCallbacksFast(
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd,
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd,
ExclusiveGroupStruct groupID, (uint, uint) rangeOfSubmittedEntitiesIndicies, in PlatformProfiler profiler);

//------------
@@ -61,7 +61,7 @@ namespace Svelto.ECS.Internal
//This is now obsolete, but I cannot mark it as such because it's heavily used by legacy projects
void ExecuteEnginesRemoveCallbacks(FasterList<(uint, string)> infosToProcess,
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove,
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove,
ExclusiveGroupStruct fromGroup, in PlatformProfiler sampler);
//Version to use
void ExecuteEnginesRemoveCallbacksFast(FasterList<ReactEngineContainer<IReactOnRemoveEx>> reactiveEnginesRemoveEx,
@@ -71,17 +71,18 @@ namespace Svelto.ECS.Internal
//------------

void ExecuteEnginesSwapCallbacks_Group(
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap,
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx,
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap,
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx,
ITypeSafeDictionary toEntitiesDictionary, ExclusiveGroupStruct fromGroupId, ExclusiveGroupStruct toGroupId,
in PlatformProfiler platformProfiler);
void ExecuteEnginesRemoveCallbacks_Group(
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> engines,
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx,
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove,
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx,
ExclusiveGroupStruct @group, in PlatformProfiler profiler);
void ExecuteEnginesDisposeCallbacks_Group
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> engines
, ExclusiveGroupStruct group, in PlatformProfiler profiler);
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> reactiveEnginesDispose,
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>> reactiveEnginesDisposeEx,
ExclusiveGroupStruct group, in PlatformProfiler profiler);

void IncreaseCapacityBy(uint size);
void EnsureCapacity(uint size);


+ 17
- 15
DataStructures/ManagedTypeSafeDictionary.cs View File

@@ -9,13 +9,13 @@ namespace Svelto.ECS.Internal
sealed class ManagedTypeSafeDictionary<TValue> : ITypeSafeDictionary<TValue>
where TValue : struct, _IInternalEntityComponent
{
//todo: would this be better to not be static to avoid overhead?
static readonly ThreadLocal<IEntityIDs> cachedEntityIDM =
new ThreadLocal<IEntityIDs>(() => new ManagedEntityIDs());

public ManagedTypeSafeDictionary(uint size)
{
implMgd =
new SveltoDictionary<uint, TValue, ManagedStrategy<SveltoDictionaryNode<uint>>, ManagedStrategy<TValue>,
implMgd = new SveltoDictionary<uint, TValue, ManagedStrategy<SveltoDictionaryNode<uint>>, ManagedStrategy<TValue>,
ManagedStrategy<int>>(size, Allocator.Managed);
}
@@ -181,7 +181,7 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesAddCallbacks
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDB
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDB
, ITypeSafeDictionary toDic, ExclusiveGroupStruct toGroup, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesAddCallbacks(ref implMgd, (ITypeSafeDictionary<TValue>)toDic
@@ -207,7 +207,7 @@ namespace Svelto.ECS.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesRemoveCallbacks
(FasterList<(uint, string)> infosToProcess
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove
, ExclusiveGroupStruct fromGroup, in PlatformProfiler sampler)
{
TypeSafeDictionaryMethods.ExecuteEnginesRemoveCallbacks(infosToProcess, ref implMgd, reactiveEnginesRemove
@@ -219,7 +219,7 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesAddEntityCallbacksFast
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd
, ExclusiveGroupStruct groupID, (uint, uint) rangeOfSubmittedEntitiesIndicies, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesAddEntityCallbacksFast(
@@ -257,14 +257,14 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesSwapCallbacks_Group
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx
, ITypeSafeDictionary toDictionary, ExclusiveGroupStruct fromGroup, ExclusiveGroupStruct toGroup
, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesSwapCallbacks_Group(
ref implMgd, (ITypeSafeDictionary<TValue>)toDictionary, toGroup, fromGroup, this, reactiveEnginesSwap
, reactiveEnginesSwapEx, count, entityIDs, in profiler);
ref implMgd, (ITypeSafeDictionary<TValue>)toDictionary, toGroup, fromGroup, reactiveEnginesSwap
, reactiveEnginesSwapEx, entityIDs, in profiler);
}

/// <summary>
@@ -273,12 +273,12 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesRemoveCallbacks_Group
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx
, ExclusiveGroupStruct group, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesRemoveCallbacks_Group(
ref implMgd, this, reactiveEnginesRemove, reactiveEnginesRemoveEx, count, entityIDs, group
ref implMgd, reactiveEnginesRemove, reactiveEnginesRemoveEx, entityIDs, group
, in profiler);
}

@@ -287,10 +287,12 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesDisposeCallbacks_Group
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> engines
, ExclusiveGroupStruct group, in PlatformProfiler profiler)
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> reactiveEnginesDispose,
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>> reactiveEnginesDisposeEx,
ExclusiveGroupStruct group, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesDisposeCallbacks_Group(ref implMgd, engines, group, in profiler);
TypeSafeDictionaryMethods.ExecuteEnginesDisposeCallbacks_Group(
ref implMgd, reactiveEnginesDispose, reactiveEnginesDisposeEx, entityIDs, group, in profiler);
}

SveltoDictionary<uint, TValue, ManagedStrategy<SveltoDictionaryNode<uint>>, ManagedStrategy<TValue>,


+ 54
- 24
DataStructures/TypeSafeDictionaryMethods.cs View File

@@ -57,7 +57,7 @@ namespace Svelto.ECS.Internal
public static void ExecuteEnginesAddCallbacks<Strategy1, Strategy2, Strategy3, TValue>(
ref SveltoDictionary<uint, TValue, Strategy1, Strategy2, Strategy3> fromDictionary
, ITypeSafeDictionary<TValue> todic, ExclusiveGroupStruct togroup
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>> entitycomponentenginesdb
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>> entitycomponentenginesdb
, in PlatformProfiler sampler)
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>>
where Strategy2 : struct, IBufferStrategy<TValue>
@@ -65,7 +65,7 @@ namespace Svelto.ECS.Internal
where TValue : struct, _IInternalEntityComponent
{
if (entitycomponentenginesdb.TryGetValue(
new RefWrapperType(TypeCache<TValue>.type)
ComponentTypeID<TValue>.id
, out var entityComponentsEngines))
{
if (entityComponentsEngines.count == 0)
@@ -101,14 +101,15 @@ namespace Svelto.ECS.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ExecuteEnginesDisposeCallbacks_Group<Strategy1, Strategy2, Strategy3, TValue>(
ref SveltoDictionary<uint, TValue, Strategy1, Strategy2, Strategy3> fromDictionary
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> allEngines
, ExclusiveGroupStruct inGroup, in PlatformProfiler sampler)
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> reactiveEnginesDispose
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>> reactiveEnginesDisposeEx
, IEntityIDs entityids, ExclusiveGroupStruct group, in PlatformProfiler sampler)
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>>
where Strategy2 : struct, IBufferStrategy<TValue>
where Strategy3 : struct, IBufferStrategy<int>
where TValue : struct, _IInternalEntityComponent
{
if (allEngines.TryGetValue(new RefWrapperType(TypeCache<TValue>.type), out var entityComponentsEngines)
if (reactiveEnginesDispose.TryGetValue(ComponentTypeID<TValue>.id, out var entityComponentsEngines)
== false)
return;

@@ -120,7 +121,7 @@ namespace Svelto.ECS.Internal
foreach (var value in fromDictionary)
{
ref var entity = ref value.value;
var egid = new EGID(value.key, inGroup);
var egid = new EGID(value.key, group);
var reactOnRemove = (IReactOnDispose<TValue>)entityComponentsEngines[i].engine;
reactOnRemove.Remove(ref entity, egid);
}
@@ -132,12 +133,41 @@ namespace Svelto.ECS.Internal

throw;
}
var count = fromDictionary.count;
if (reactiveEnginesDisposeEx.TryGetValue(
ComponentTypeID<TValue>.id
, out var reactiveEnginesDisposeExPerType))
{
var enginesCount = reactiveEnginesDisposeExPerType.count;

for (var i = 0; i < enginesCount; i++)
try
{
using (sampler.Sample(reactiveEnginesDisposeExPerType[i].name))
{
((IReactOnDisposeEx<TValue>)reactiveEnginesDisposeExPerType[i].engine).Remove(
(0, (uint)count)
, new EntityCollection<TValue>(
fromDictionary.UnsafeGetValues(out _), entityids
, (uint)count), group);
}
}
catch
{
Console.LogError("Code crashed inside Remove callback ".FastConcat(reactiveEnginesDisposeExPerType[i].name));

throw;
}
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ExecuteEnginesRemoveCallbacks<Strategy1, Strategy2, Strategy3, TValue>(FasterList<(uint, string)> infostoprocess
, ref SveltoDictionary<uint, TValue, Strategy1, Strategy2, Strategy3> fromDictionary
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveenginesremove
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveenginesremove
, ExclusiveGroupStruct fromgroup, in PlatformProfiler profiler)
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>>
where Strategy2 : struct, IBufferStrategy<TValue>
@@ -145,7 +175,7 @@ namespace Svelto.ECS.Internal
where TValue : struct, _IInternalEntityComponent
{
if (reactiveenginesremove.TryGetValue(
new RefWrapperType(TypeCache<TValue>.type)
ComponentTypeID<TValue>.id
, out var entityComponentsEngines))
{
if (entityComponentsEngines.count == 0)
@@ -185,17 +215,16 @@ namespace Svelto.ECS.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ExecuteEnginesRemoveCallbacks_Group<Strategy1, Strategy2, Strategy3, TValue>(
ref SveltoDictionary<uint, TValue, Strategy1, Strategy2, Strategy3> fromDictionary
, ITypeSafeDictionary<TValue> typeSafeDictionary
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveenginesremove
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveenginesremoveex
, int count, IEntityIDs entityids, ExclusiveGroupStruct group, in PlatformProfiler sampler)
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveenginesremove
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveenginesremoveex
, IEntityIDs entityids, ExclusiveGroupStruct group, in PlatformProfiler sampler)
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>>
where Strategy2 : struct, IBufferStrategy<TValue>
where Strategy3 : struct, IBufferStrategy<int>
where TValue : struct, _IInternalEntityComponent
{
if (reactiveenginesremove.TryGetValue(
new RefWrapperType(TypeCache<TValue>.type)
ComponentTypeID<TValue>.id
, out var reactiveEnginesRemovePerType))
{
var enginesCount = reactiveEnginesRemovePerType.count;
@@ -226,9 +255,10 @@ namespace Svelto.ECS.Internal
}

if (reactiveenginesremoveex.TryGetValue(
new RefWrapperType(TypeCache<TValue>.type)
ComponentTypeID<TValue>.id
, out var reactiveEnginesRemoveExPerType))
{
var count = fromDictionary.count;
var enginesCount = reactiveEnginesRemoveExPerType.count;

for (var i = 0; i < enginesCount; i++)
@@ -239,7 +269,7 @@ namespace Svelto.ECS.Internal
((IReactOnRemoveEx<TValue>)reactiveEnginesRemoveExPerType[i].engine).Remove(
(0, (uint)count)
, new EntityCollection<TValue>(
typeSafeDictionary.GetValues(out _), entityids
fromDictionary.UnsafeGetValues(out _), entityids
, (uint)count), group);
}
}
@@ -300,10 +330,9 @@ namespace Svelto.ECS.Internal
public static void ExecuteEnginesSwapCallbacks_Group<Strategy1, Strategy2, Strategy3, TValue>(
ref SveltoDictionary<uint, TValue, Strategy1, Strategy2, Strategy3> fromDictionary
, ITypeSafeDictionary<TValue> toDic, ExclusiveGroupStruct togroup, ExclusiveGroupStruct fromgroup
, ITypeSafeDictionary<TValue> typeSafeDictionary
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveenginesswap
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveenginesswapex
, int count, IEntityIDs entityids, in PlatformProfiler sampler)
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveenginesswap
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveenginesswapex
, IEntityIDs entityids, in PlatformProfiler sampler)
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>>
where Strategy2 : struct, IBufferStrategy<TValue>
where Strategy3 : struct, IBufferStrategy<int>
@@ -311,7 +340,7 @@ namespace Svelto.ECS.Internal
{
//get all the engines linked to TValue
if (!reactiveenginesswap.TryGetValue(
new RefWrapperType(TypeCache<TValue>.type)
ComponentTypeID<TValue>.id
, out var reactiveEnginesSwapPerType))
return;

@@ -342,10 +371,11 @@ namespace Svelto.ECS.Internal
}

if (reactiveenginesswapex.TryGetValue(
new RefWrapperType(TypeCache<TValue>.type)
ComponentTypeID<TValue>.id
, out var reactiveEnginesRemoveExPerType))
{
var enginesCount = reactiveEnginesRemoveExPerType.count;
var count = fromDictionary.count;

for (var i = 0; i < enginesCount; i++)
try
@@ -355,7 +385,7 @@ namespace Svelto.ECS.Internal
((IReactOnSwapEx<TValue>)reactiveEnginesRemoveExPerType[i].engine).MovedTo(
(0, (uint)count)
, new EntityCollection<TValue>(
typeSafeDictionary.GetValues(out _), entityids
fromDictionary.UnsafeGetValues(out _), entityids
, (uint)count), fromgroup, togroup);
}
}
@@ -467,14 +497,14 @@ namespace Svelto.ECS.Internal

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ExecuteEnginesAddEntityCallbacksFast<TValue>(
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>> fasterDictionary
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>> fasterDictionary
, ExclusiveGroupStruct groupId, (uint, uint) rangeTuple, IEntityIDs entityids
, ITypeSafeDictionary<TValue> typeSafeDictionary, PlatformProfiler profiler)
where TValue : struct, _IInternalEntityComponent
{
//get all the engines linked to TValue
if (!fasterDictionary.TryGetValue(
new RefWrapperType(TypeCache<TValue>.type)
ComponentTypeID<TValue>.id
, out var entityComponentsEngines))
return;



+ 15
- 14
DataStructures/UnmanagedTypeSafeDictionary.cs View File

@@ -22,13 +22,13 @@ namespace Svelto.ECS.Internal
sealed class UnmanagedTypeSafeDictionary<TValue> : ITypeSafeDictionary<TValue>
where TValue : struct, _IInternalEntityComponent
{
//todo: would this be better to not be static to avoid overhead?
static readonly ThreadLocal<IEntityIDs> cachedEntityIDN =
new ThreadLocal<IEntityIDs>(() => new NativeEntityIDs());

public UnmanagedTypeSafeDictionary(uint size)
{
implUnmgd =
new SharedSveltoDictionaryNative<uint, TValue>(size, Allocator.Persistent);
implUnmgd = new SharedSveltoDictionaryNative<uint, TValue>(size, Allocator.Persistent);
}

public IEntityIDs entityIDs
@@ -193,7 +193,7 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesAddCallbacks
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDB
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDB
, ITypeSafeDictionary toDic, ExclusiveGroupStruct toGroup, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesAddCallbacks(ref implUnmgd.dictionary, (ITypeSafeDictionary<TValue>)toDic
@@ -219,7 +219,7 @@ namespace Svelto.ECS.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesRemoveCallbacks
(FasterList<(uint, string)> infosToProcess
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove
, ExclusiveGroupStruct fromGroup, in PlatformProfiler sampler)
{
TypeSafeDictionaryMethods.ExecuteEnginesRemoveCallbacks(infosToProcess, ref implUnmgd.dictionary
@@ -231,7 +231,7 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesAddEntityCallbacksFast
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd
, ExclusiveGroupStruct groupID, (uint, uint) rangeOfSubmittedEntitiesIndicies, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesAddEntityCallbacksFast(
@@ -269,14 +269,14 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesSwapCallbacks_Group
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx
, ITypeSafeDictionary toDictionary, ExclusiveGroupStruct fromGroup, ExclusiveGroupStruct toGroup
, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesSwapCallbacks_Group(
ref implUnmgd.dictionary, (ITypeSafeDictionary<TValue>)toDictionary, toGroup, fromGroup, this
, reactiveEnginesSwap, reactiveEnginesSwapEx, count, entityIDs, in profiler);
ref implUnmgd.dictionary, (ITypeSafeDictionary<TValue>)toDictionary, toGroup, fromGroup
, reactiveEnginesSwap, reactiveEnginesSwapEx, entityIDs, in profiler);
}

/// <summary>
@@ -285,12 +285,12 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesRemoveCallbacks_Group
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx
, ExclusiveGroupStruct group, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesRemoveCallbacks_Group(
ref implUnmgd.dictionary, this, reactiveEnginesRemove, reactiveEnginesRemoveEx, count, entityIDs, group
ref implUnmgd.dictionary, reactiveEnginesRemove, reactiveEnginesRemoveEx, entityIDs, group
, in profiler);
}

@@ -299,11 +299,12 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesDisposeCallbacks_Group
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> engines
( FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> reactiveEnginesDispose
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>> reactiveEnginesDisposeEx
, ExclusiveGroupStruct group, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesDisposeCallbacks_Group(
ref implUnmgd.dictionary, engines, group, in profiler);
ref implUnmgd.dictionary, reactiveEnginesDispose, reactiveEnginesDisposeEx, entityIDs, group, in profiler);
}

internal SharedSveltoDictionaryNative<uint, TValue> implUnmgd;


+ 2
- 2
Extensions/Native/EnginesRoot.NativeOperation.cs View File

@@ -143,9 +143,9 @@ namespace Svelto.ECS

var typeID = buffer.Dequeue<uint>();

IFiller entityBuilder = EntityComponentIDMap.GetTypeFromID(typeID);
IFiller componentBuilder = EntityComponentIDMap.GetBuilderFromID(typeID);
//after the typeID, I expect the serialized component
entityBuilder.FillFromByteArray(init, buffer);
componentBuilder.FillFromByteArray(init, buffer);
}
}
}


Core/GlobalTypeID.cs → Extensions/Native/NativeComponentFiller.cs View File

@@ -1,19 +1,9 @@
using System.Threading;
using Svelto.Common;
using Svelto.DataStructures;
using Svelto.ECS.Internal;

namespace Svelto.ECS
{
public class GlobalTypeID
{
internal static uint NextID<T>() { return (uint) (Interlocked.Increment(ref value) - 1); }

static GlobalTypeID() { value = 0; }

static int value;
}

interface IFiller
{
void FillFromByteArray(EntityInitializer init, NativeBag buffer);
@@ -36,12 +26,6 @@ namespace Svelto.ECS
}

#if UNITY_NATIVE //at the moment I am still considering NativeOperations useful only for Unity
static class EntityComponentID<T>
{
internal static readonly Unity.Burst.SharedStatic<uint> ID =
Unity.Burst.SharedStatic<uint>.GetOrCreate<GlobalTypeID, T>();
}

static class EntityComponentIDMap
{
static readonly Svelto.DataStructures.FasterList<IFiller> TYPE_IDS;
@@ -53,11 +37,11 @@ namespace Svelto.ECS

internal static void Register<T>(IFiller entityBuilder) where T : struct, _IInternalEntityComponent
{
var location = EntityComponentID<T>.ID.Data = GlobalTypeID.NextID<T>();
ComponentID location = ComponentTypeID<T>.id;
TYPE_IDS.AddAt(location, entityBuilder);
}

internal static IFiller GetTypeFromID(uint typeId) { return TYPE_IDS[typeId]; }
internal static IFiller GetBuilderFromID(uint typeId) { return TYPE_IDS[typeId]; }
}
#endif
}

+ 11
- 0
Extensions/Native/NativeComponentFiller.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 357c48224c5333668fa774ec516825de
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 1
- 2
Extensions/Native/NativeEntityFactory.cs View File

@@ -32,8 +32,7 @@ namespace Svelto.ECS.Native
EntityReference reference = _entityLocator.ClaimReference();
NativeBag bagPerEntityPerThread = _addOperationQueue.GetBag(threadIndex + 1);

bagPerEntityPerThread.Enqueue(
_operationIndex); //each native operation is stored in an array, each request to perform a native operation in a queue. _index is the index of the operation in the array that will be dequeued later
bagPerEntityPerThread.Enqueue(_operationIndex); //each native operation is stored in an array, each request to perform a native operation in a queue. _index is the index of the operation in the array that will be dequeued later
bagPerEntityPerThread.Enqueue(new EGID(eindex, exclusiveBuildGroup));
bagPerEntityPerThread.Enqueue(reference);



+ 1
- 1
Extensions/Native/NativeEntityInitializer.cs View File

@@ -20,7 +20,7 @@ namespace Svelto.ECS.Native
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T Init<T>(in T component) where T : unmanaged, IEntityComponent
{
uint componentID = EntityComponentID<T>.ID.Data;
uint componentID = ComponentTypeID<T>.id;

_unsafeBuffer.AccessReserved<uint>(_componentsToInitializeCounterRef)++; //increase the number of components that have been initialised by the user



+ 1
- 1
Extensions/Svelto/AllGroupsEnumerable.cs View File

@@ -35,7 +35,7 @@ namespace Svelto.ECS
{
public GroupsIterator(EntitiesDB db) : this()
{
_db = db.FindGroups_INTERNAL(TypeCache<T1>.type).GetEnumerator();
_db = db.FindGroups_INTERNAL(ComponentTypeID<T1>.id).GetEnumerator();
}

public bool MoveNext()


+ 2
- 22
README.md View File

@@ -3,7 +3,7 @@
Real ECS framework for c\#. Enables to write encapsulated, decoupled, maintainable, highly efficient, data oriented, cache friendly, code without pain. Although the framework is platform agnostic \(compatible with c\# 7 and above and .net standard 2.0 and above\), it comes with several Unity extensions.

## Svelto.ECS in pills
Svelto.ECS is easy to start with, but full of tricks for expert users. The hardest problem to overcome is usually to shift mentality from OOP programming to ECS programming more than using the framework itself. If you want to read an ECS faq, you can check this article: https://github.com/SanderMertens/ecs-faq
Svelto.ECS is easy to start with, but full of tricks for expert users. The hardest problem to overcome is usually to shift mentality from OOP programming to ECS programming rather than using the framework itself. If you would like to read an ECS faq, you can check this article: https://github.com/SanderMertens/ecs-faq

### Svelto.ECS at glance

@@ -144,6 +144,7 @@ https://github.com/sebas77/Svelto.ECS/discussions

**Practical articles**

* [Svelto ECS 3.4 internals: How to integrate ComputeSharp](https://www.sebaslab.com/svelto-ecs-3-4-internals-how-to-integrate-computesharp/)
* [Svelto.ECS 3.4 – Svelto On DOTS ECS update](https://www.sebaslab.com/svelto-ecs-3-4-svelto-on-dots-ecs-update/)
* [Svelto.ECS 3.3 and the new Filters API](https://www.sebaslab.com/svelto-ecs-3-3-and-the-new-filters-api/)
* [What’s new in Svelto.ECS 3.0](https://www.sebaslab.com/whats-new-in-svelto-ecs-3-0/)
@@ -174,27 +175,6 @@ The folders Svelto.ECS and Svelto.Common, where present, are submodules pointing

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

**Note on the System.Runtime.CompilerServices.Unsafe.dll dependency and the bit of a mess that Unity Package Dependency System is:**

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. For this reason I decided to let my packages to point to the unsafe dll distribution from openUPM

to solve the unsafe dependency you need to add the following scopedRegistries in manifest.json:
```
{
"scopedRegistries": [
{
"name": "package.openupm.com",
"url": "https://package.openupm.com",
"scopes": [
"com.sebaslab.svelto.common",
"com.sebaslab.svelto.ecs",
"org.nuget.system.runtime.compilerservices.unsafe"
]
}
]
}
```

this is shown in this example too: https://github.com/sebas77/Svelto.MiniExamples/tree/master/UPM-Integration/UPM

## Svelto distributed as Nuget


+ 2
- 3
Serialization/EnginesRoot.GenericEntitySerialization.cs View File

@@ -1,7 +1,6 @@
using System;
using System.Runtime.CompilerServices;
using Svelto.DataStructures;
using Svelto.ECS.Internal;
using Svelto.ECS.Serialization;

namespace Svelto.ECS
@@ -208,7 +207,7 @@ namespace Svelto.ECS
ISerializationData serializationData, int serializationType)
{
ExclusiveGroupStruct groupId = entityGID.groupID;
Type entityType = componentBuilder.GetEntityComponentType();
var entityType = componentBuilder.getComponentID;
if (!_enginesRoot._entitiesDB.UnsafeQueryEntityDictionary(groupId, entityType, out var safeDictionary))
{
throw new Exception("Entity Serialization failed");
@@ -230,7 +229,7 @@ namespace Svelto.ECS
foreach (var serializableEntityBuilder in entityDescriptor.componentsToSerialize)
{
entitiesInGroupPerType.TryGetValue(
new RefWrapperType(serializableEntityBuilder.GetEntityComponentType()), out var safeDictionary);
serializableEntityBuilder.getComponentID, out var safeDictionary);

serializationData.BeginNextEntityComponent();
serializableEntityBuilder.Deserialize(egid.entityID, safeDictionary, serializationData,


+ 0
- 1
Serialization/IEntitySerialization.cs View File

@@ -1,5 +1,4 @@
using System.Runtime.CompilerServices;
using Svelto.ECS.Internal;

namespace Svelto.ECS.Serialization
{


+ 4
- 5
Serialization/SerializableEntityDescriptor.cs View File

@@ -16,7 +16,7 @@ namespace Svelto.ECS.Serialization
{
static SerializableEntityDescriptor()
{
IComponentBuilder[] defaultEntities = EntityDescriptorTemplate<TType>.descriptor.componentsToBuild;
IComponentBuilder[] defaultEntities = EntityDescriptorTemplate<TType>.realDescriptor.componentsToBuild;

var hashNameAttribute = Type.GetCustomAttribute<HashNameAttribute>();
if (hashNameAttribute == null)
@@ -49,13 +49,12 @@ namespace Svelto.ECS.Serialization

/////
var entitiesToSerialize = new FasterList<ISerializableComponentBuilder>();
EntityComponentsToSerializeMap = new FasterDictionary<RefWrapperType, ISerializableComponentBuilder>();
EntityComponentsToSerializeMap = new FasterDictionary<ComponentID, ISerializableComponentBuilder>();
foreach (IComponentBuilder e in defaultEntities)
{
if (e is ISerializableComponentBuilder serializableEntityBuilder)
{
var entityType = serializableEntityBuilder.GetEntityComponentType();
EntityComponentsToSerializeMap[new RefWrapperType(entityType)] = serializableEntityBuilder;
EntityComponentsToSerializeMap[serializableEntityBuilder.getComponentID] = serializableEntityBuilder;
entitiesToSerialize.Add(serializableEntityBuilder);
}
}
@@ -99,7 +98,7 @@ namespace Svelto.ECS.Serialization
public ISerializableComponentBuilder[] componentsToSerialize => EntitiesToSerialize;

static readonly IComponentBuilder[] ComponentsToBuild;
static readonly FasterDictionary<RefWrapperType, ISerializableComponentBuilder> EntityComponentsToSerializeMap;
static readonly FasterDictionary<ComponentID, ISerializableComponentBuilder> EntityComponentsToSerializeMap;
static readonly ISerializableComponentBuilder[] EntitiesToSerialize;

static readonly uint Hash;


+ 3
- 3
Svelto.ECS.csproj View File

@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>Svelto.ECS</AssemblyName>
<LangVersion>9</LangVersion>
<LangVersion>10</LangVersion>
<TargetFramework>netstandard2.1</TargetFramework>
<Company>Svelto</Company>
<AssemblyVersion>3.4.1</AssemblyVersion>
<PackageVersion>3.4.1</PackageVersion>
<AssemblyVersion>3.4</AssemblyVersion>
<PackageVersion></PackageVersion>
<IsPackable>true</IsPackable>
<Configurations>Debug;Release;SlowSubmissionRelease;SlowSubmissionDebug</Configurations>
<Platforms>AnyCPU</Platforms>


+ 2
- 2
package.json View File

@@ -11,7 +11,7 @@
"url": "https://github.com/sebas77/Svelto.ECS.git"
},
"dependencies": {
"com.sebaslab.svelto.common": "3.4.1"
"com.sebaslab.svelto.common": "3.4.2"
},
"keywords": [
"svelto",
@@ -19,7 +19,7 @@
"svelto.ecs"
],
"name": "com.sebaslab.svelto.ecs",
"version": "3.4.3",
"version": "3.4.4",
"type": "library",
"unity": "2020.3"
}

Loading…
Cancel
Save