Browse Source

move away from RefWrapperType to the new ComponentID key type. The former was GUID based the latter is counter based


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

+ 1
- 1
com.sebaslab.svelto.common

@@ -1 +1 @@
Subproject commit 13c4f38c44fac08914d3ed26723e6134a53c30c0
Subproject commit 9a74e5c70681d4f2f5156b48cdd578dfcf6cfc4e

+ 9
- 0
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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;
}
}

+ 24
- 22
com.sebaslab.svelto.ecs/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,19 @@ 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>>>();

_reactiveEnginesSubmission = new FasterList<IReactOnSubmission>();
_reactiveEnginesSubmissionStarted = new FasterList<IReactOnSubmissionStarted>();
@@ -71,14 +72,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);
@@ -198,18 +199,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 +219,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 +228,7 @@ namespace Svelto.ECS
{
if (interf.IsGenericTypeEx() && interf.GetGenericTypeDefinition() == genericDefinition)
{
var genericArguments = interf.GetGenericArgumentsEx();
Type[] genericArguments = interf.GetGenericArgumentsEx();

AddEngineToList(engine, genericArguments, engines, typeName);
}
@@ -401,13 +403,13 @@ 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 FasterList<IReactOnSubmission> _reactiveEnginesSubmission;
readonly FasterList<IReactOnSubmissionStarted> _reactiveEnginesSubmissionStarted;


+ 15
- 16
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/Core/EntityInfoView.cs View File

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

namespace Svelto.ECS
{


+ 7
- 7
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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);
}
}
}
}
}
}
}

+ 1
- 0
com.sebaslab.svelto.ecs/Core/IComponentBuilder.cs View File

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

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

+ 13
- 9
com.sebaslab.svelto.ecs/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;
}
}

+ 8
- 8
com.sebaslab.svelto.ecs/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,16 +71,16 @@ 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>>> engines,
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx,
ExclusiveGroupStruct @group, in PlatformProfiler profiler);
void ExecuteEnginesDisposeCallbacks_Group
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> engines
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> engines
, ExclusiveGroupStruct group, in PlatformProfiler profiler);

void IncreaseCapacityBy(uint size);


+ 10
- 10
com.sebaslab.svelto.ecs/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,8 +257,8 @@ 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)
{
@@ -273,8 +273,8 @@ 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(
@@ -287,7 +287,7 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesDisposeCallbacks_Group
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> engines
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> engines
, ExclusiveGroupStruct group, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesDisposeCallbacks_Group(ref implMgd, engines, group, in profiler);


+ 16
- 16
com.sebaslab.svelto.ecs/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,14 @@ 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
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> allEngines
, ExclusiveGroupStruct inGroup, 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 (allEngines.TryGetValue(ComponentTypeID<TValue>.id, out var entityComponentsEngines)
== false)
return;

@@ -137,7 +137,7 @@ namespace Svelto.ECS.Internal
[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 +145,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)
@@ -186,8 +186,8 @@ namespace Svelto.ECS.Internal
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
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveenginesremove
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveenginesremoveex
, int count, IEntityIDs entityids, ExclusiveGroupStruct group, in PlatformProfiler sampler)
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>>
where Strategy2 : struct, IBufferStrategy<TValue>
@@ -195,7 +195,7 @@ namespace Svelto.ECS.Internal
where TValue : struct, _IInternalEntityComponent
{
if (reactiveenginesremove.TryGetValue(
new RefWrapperType(TypeCache<TValue>.type)
ComponentTypeID<TValue>.id
, out var reactiveEnginesRemovePerType))
{
var enginesCount = reactiveEnginesRemovePerType.count;
@@ -226,7 +226,7 @@ namespace Svelto.ECS.Internal
}

if (reactiveenginesremoveex.TryGetValue(
new RefWrapperType(TypeCache<TValue>.type)
ComponentTypeID<TValue>.id
, out var reactiveEnginesRemoveExPerType))
{
var enginesCount = reactiveEnginesRemoveExPerType.count;
@@ -301,8 +301,8 @@ namespace Svelto.ECS.Internal
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
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveenginesswap
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveenginesswapex
, int count, IEntityIDs entityids, in PlatformProfiler sampler)
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>>
where Strategy2 : struct, IBufferStrategy<TValue>
@@ -311,7 +311,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,7 +342,7 @@ namespace Svelto.ECS.Internal
}

if (reactiveenginesswapex.TryGetValue(
new RefWrapperType(TypeCache<TValue>.type)
ComponentTypeID<TValue>.id
, out var reactiveEnginesRemoveExPerType))
{
var enginesCount = reactiveEnginesRemoveExPerType.count;
@@ -467,14 +467,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;



+ 10
- 10
com.sebaslab.svelto.ecs/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,8 +269,8 @@ 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)
{
@@ -285,8 +285,8 @@ 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(
@@ -299,7 +299,7 @@ namespace Svelto.ECS.Internal
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExecuteEnginesDisposeCallbacks_Group
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> engines
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> engines
, ExclusiveGroupStruct group, in PlatformProfiler profiler)
{
TypeSafeDictionaryMethods.ExecuteEnginesDisposeCallbacks_Group(


+ 2
- 2
com.sebaslab.svelto.ecs/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);
}
}
}


com.sebaslab.svelto.ecs/Core/GlobalTypeID.cs → com.sebaslab.svelto.ecs/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
}

+ 1
- 2
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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
- 3
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/Serialization/IEntitySerialization.cs View File

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

namespace Svelto.ECS.Serialization
{


+ 4
- 5
com.sebaslab.svelto.ecs/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
com.sebaslab.svelto.ecs/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.3</AssemblyVersion>
<PackageVersion>3.4.3</PackageVersion>
<AssemblyVersion>3.4</AssemblyVersion>
<PackageVersion></PackageVersion>
<IsPackable>true</IsPackable>
<Configurations>Debug;Release;SlowSubmissionRelease;SlowSubmissionDebug</Configurations>
<Platforms>AnyCPU</Platforms>


+ 2
- 2
com.sebaslab.svelto.ecs/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"
}

+ 1
- 1
com.sebaslab.svelto.ecs/version.json View File

@@ -1,3 +1,3 @@
{
"version": "3.4.3"
"version": "3.4.4"
}

Loading…
Cancel
Save