@@ -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; | |||
} | |||
} | |||
} | |||
} |
@@ -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()); | |||
@@ -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; | |||
} | |||
} |
@@ -16,6 +16,7 @@ namespace Svelto.ECS | |||
{ | |||
static EnginesRoot() | |||
{ | |||
EntityDescriptorsWarmup.Init(); | |||
GroupHashMap.Init(); | |||
//SharedDictonary.Init(); | |||
SerializationDescriptorMap.Init(); | |||
@@ -50,19 +51,21 @@ namespace Svelto.ECS | |||
_nativeAddOperationQueue = new AtomicNativeBags(Allocator.Persistent); | |||
#endif | |||
_serializationDescriptorMap = new SerializationDescriptorMap(); | |||
_reactiveEnginesAdd = new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>>(); | |||
_reactiveEnginesAdd = new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>>(); | |||
_reactiveEnginesAddEx = | |||
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>>(); | |||
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>>(); | |||
_reactiveEnginesRemove = | |||
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>>(); | |||
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>>(); | |||
_reactiveEnginesRemoveEx = | |||
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>>(); | |||
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>>(); | |||
_reactiveEnginesSwap = | |||
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>>(); | |||
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>>(); | |||
_reactiveEnginesSwapEx = | |||
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>>(); | |||
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>>(); | |||
_reactiveEnginesDispose = | |||
new FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>>(); | |||
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>>(); | |||
_reactiveEnginesDisposeEx = | |||
new FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>>(); | |||
_reactiveEnginesSubmission = new FasterList<IReactOnSubmission>(); | |||
_reactiveEnginesSubmissionStarted = new FasterList<IReactOnSubmissionStarted>(); | |||
@@ -71,14 +74,14 @@ namespace Svelto.ECS | |||
_disposableEngines = new FasterList<IDisposable>(); | |||
_groupEntityComponentsDB = | |||
new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>(); | |||
new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, ITypeSafeDictionary>>(); | |||
_groupsPerEntity = | |||
new FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>>(); | |||
new FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>>(); | |||
_groupedEntityToAdd = new DoubleBufferedEntitiesToAdd(); | |||
_entityStreams = EntitiesStreams.Create(); | |||
#if SVELTO_LEGACY_FILTERS | |||
_groupFilters = | |||
new FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>>(); | |||
new FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, LegacyGroupFilters>>(); | |||
#endif | |||
_entityLocator.InitEntityReferenceMap(); | |||
_entitiesDB = new EntitiesDB(this, _entityLocator); | |||
@@ -150,6 +153,10 @@ namespace Svelto.ECS | |||
if (engine is IReactOnDispose viewEngineDispose) | |||
CheckReactEngineComponents( | |||
typeof(IReactOnDispose<>), viewEngineDispose, _reactiveEnginesDispose, type.Name); | |||
if (engine is IReactOnDisposeEx viewEngineDisposeEx) | |||
CheckReactEngineComponents( | |||
typeof(IReactOnDisposeEx<>), viewEngineDisposeEx, _reactiveEnginesDisposeEx, type.Name); | |||
if (engine is IReactOnSwap viewEngineSwap) | |||
#pragma warning disable CS0612 | |||
@@ -198,18 +205,19 @@ namespace Svelto.ECS | |||
} | |||
static void AddEngineToList<T>(T engine, Type[] entityComponentTypes, | |||
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<T>>> engines, string typeName) | |||
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<T>>> engines, string typeName) | |||
where T : class, IReactEngine | |||
{ | |||
for (var i = 0; i < entityComponentTypes.Length; i++) | |||
{ | |||
var type = entityComponentTypes[i]; | |||
if (engines.TryGetValue(new RefWrapperType(type), out var list) == false) | |||
var componentID = ComponentTypeMap.FetchID(type); | |||
if (engines.TryGetValue(componentID, out var list) == false) | |||
{ | |||
list = new FasterList<ReactEngineContainer<T>>(); | |||
engines.Add(new RefWrapperType(type), list); | |||
engines.Add(componentID, list); | |||
} | |||
list.Add(new ReactEngineContainer<T>(engine, typeName)); | |||
@@ -217,7 +225,7 @@ namespace Svelto.ECS | |||
} | |||
void CheckReactEngineComponents<T>(Type genericDefinition, T engine, | |||
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<T>>> engines, string typeName) | |||
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<T>>> engines, string typeName) | |||
where T : class, IReactEngine | |||
{ | |||
var interfaces = engine.GetType().GetInterfaces(); | |||
@@ -226,7 +234,7 @@ namespace Svelto.ECS | |||
{ | |||
if (interf.IsGenericTypeEx() && interf.GetGenericTypeDefinition() == genericDefinition) | |||
{ | |||
var genericArguments = interf.GetGenericArgumentsEx(); | |||
Type[] genericArguments = interf.GetGenericArgumentsEx(); | |||
AddEngineToList(engine, genericArguments, engines, typeName); | |||
} | |||
@@ -261,7 +269,7 @@ namespace Svelto.ECS | |||
ITypeSafeDictionary typeSafeDictionary = entityList.value; | |||
typeSafeDictionary.ExecuteEnginesDisposeCallbacks_Group( | |||
_reactiveEnginesDispose, groups.key, | |||
_reactiveEnginesDispose, _reactiveEnginesDisposeEx, groups.key, | |||
profiler); | |||
} | |||
catch (Exception e) | |||
@@ -298,6 +306,7 @@ namespace Svelto.ECS | |||
_reactiveEnginesAdd.Clear(); | |||
_reactiveEnginesRemove.Clear(); | |||
_reactiveEnginesDispose.Clear(); | |||
_reactiveEnginesDisposeEx.Clear(); | |||
_reactiveEnginesSubmission.Clear(); | |||
_reactiveEnginesSubmissionStarted.Clear(); | |||
@@ -401,13 +410,14 @@ namespace Svelto.ECS | |||
readonly HashSet<Type> _enginesTypeSet; | |||
readonly EnginesReadyOption _enginesWaitForReady; | |||
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>> _reactiveEnginesAdd; | |||
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>> _reactiveEnginesAddEx; | |||
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> _reactiveEnginesRemove; | |||
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> _reactiveEnginesRemoveEx; | |||
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>> _reactiveEnginesSwap; | |||
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>> _reactiveEnginesSwapEx; | |||
readonly FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> _reactiveEnginesDispose; | |||
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>> _reactiveEnginesAdd; | |||
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>> _reactiveEnginesAddEx; | |||
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> _reactiveEnginesRemove; | |||
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> _reactiveEnginesRemoveEx; | |||
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>> _reactiveEnginesSwap; | |||
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>> _reactiveEnginesSwapEx; | |||
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> _reactiveEnginesDispose; | |||
readonly FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>> _reactiveEnginesDisposeEx; | |||
readonly FasterList<IReactOnSubmission> _reactiveEnginesSubmission; | |||
readonly FasterList<IReactOnSubmissionStarted> _reactiveEnginesSubmissionStarted; | |||
@@ -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 | |||
@@ -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 | |||
@@ -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]; | |||
@@ -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; | |||
@@ -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; | |||
@@ -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; | |||
@@ -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 | |||
@@ -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); | |||
} | |||
@@ -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; } | |||
@@ -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); | |||
@@ -1,5 +1,4 @@ | |||
using Svelto.ECS.Hybrid; | |||
using Svelto.ECS.Internal; | |||
namespace Svelto.ECS | |||
{ | |||
@@ -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,5 +1,4 @@ | |||
using System; | |||
using System.Runtime.CompilerServices; | |||
using System.Runtime.CompilerServices; | |||
using Svelto.Common; | |||
using Svelto.DataStructures; | |||
using Svelto.DataStructures.Native; | |||
@@ -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); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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,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 :)"); | |||
@@ -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; | |||
} | |||
} | |||
@@ -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 | |||
@@ -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); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -12,5 +12,6 @@ namespace Svelto.ECS | |||
Type GetEntityComponentType(); | |||
bool isUnmanaged { get; } | |||
ComponentID getComponentID { get; } | |||
} | |||
} |
@@ -40,6 +40,10 @@ namespace Svelto.ECS.Internal | |||
public interface IReactOnSwapEx : IReactEngine | |||
{ | |||
} | |||
public interface IReactOnDisposeEx : IReactEngine | |||
{ | |||
} | |||
public interface IReactOnDispose : IReactEngine | |||
{ | |||
@@ -132,6 +136,12 @@ namespace Svelto.ECS | |||
void MovedTo((uint start, uint end) rangeOfEntities, in EntityCollection<T> entities, | |||
ExclusiveGroupStruct fromGroup, ExclusiveGroupStruct toGroup); | |||
} | |||
public interface IReactOnDisposeEx<T> : IReactOnDisposeEx where T : struct, _IInternalEntityComponent | |||
{ | |||
void Remove((uint start, uint end) rangeOfEntities, in EntityCollection<T> entities, | |||
ExclusiveGroupStruct groupID); | |||
} | |||
/// <summary> | |||
/// Interface to mark an Engine as reacting after each entities submission phase | |||
@@ -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; | |||
} | |||
} |
@@ -39,11 +39,11 @@ namespace Svelto.ECS.Internal | |||
//This is now obsolete, but I cannot mark it as such because it's heavily used by legacy projects | |||
void ExecuteEnginesAddCallbacks | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDb | |||
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDb | |||
, ITypeSafeDictionary destinationDatabase, ExclusiveGroupStruct toGroup, in PlatformProfiler profiler); | |||
//Version to use | |||
void ExecuteEnginesAddEntityCallbacksFast( | |||
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd, | |||
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd, | |||
ExclusiveGroupStruct groupID, (uint, uint) rangeOfSubmittedEntitiesIndicies, in PlatformProfiler profiler); | |||
//------------ | |||
@@ -61,7 +61,7 @@ namespace Svelto.ECS.Internal | |||
//This is now obsolete, but I cannot mark it as such because it's heavily used by legacy projects | |||
void ExecuteEnginesRemoveCallbacks(FasterList<(uint, string)> infosToProcess, | |||
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove, | |||
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove, | |||
ExclusiveGroupStruct fromGroup, in PlatformProfiler sampler); | |||
//Version to use | |||
void ExecuteEnginesRemoveCallbacksFast(FasterList<ReactEngineContainer<IReactOnRemoveEx>> reactiveEnginesRemoveEx, | |||
@@ -71,17 +71,18 @@ namespace Svelto.ECS.Internal | |||
//------------ | |||
void ExecuteEnginesSwapCallbacks_Group( | |||
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap, | |||
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx, | |||
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap, | |||
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx, | |||
ITypeSafeDictionary toEntitiesDictionary, ExclusiveGroupStruct fromGroupId, ExclusiveGroupStruct toGroupId, | |||
in PlatformProfiler platformProfiler); | |||
void ExecuteEnginesRemoveCallbacks_Group( | |||
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> engines, | |||
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx, | |||
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove, | |||
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx, | |||
ExclusiveGroupStruct @group, in PlatformProfiler profiler); | |||
void ExecuteEnginesDisposeCallbacks_Group | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> engines | |||
, ExclusiveGroupStruct group, in PlatformProfiler profiler); | |||
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> reactiveEnginesDispose, | |||
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>> reactiveEnginesDisposeEx, | |||
ExclusiveGroupStruct group, in PlatformProfiler profiler); | |||
void IncreaseCapacityBy(uint size); | |||
void EnsureCapacity(uint size); | |||
@@ -9,13 +9,13 @@ namespace Svelto.ECS.Internal | |||
sealed class ManagedTypeSafeDictionary<TValue> : ITypeSafeDictionary<TValue> | |||
where TValue : struct, _IInternalEntityComponent | |||
{ | |||
//todo: would this be better to not be static to avoid overhead? | |||
static readonly ThreadLocal<IEntityIDs> cachedEntityIDM = | |||
new ThreadLocal<IEntityIDs>(() => new ManagedEntityIDs()); | |||
public ManagedTypeSafeDictionary(uint size) | |||
{ | |||
implMgd = | |||
new SveltoDictionary<uint, TValue, ManagedStrategy<SveltoDictionaryNode<uint>>, ManagedStrategy<TValue>, | |||
implMgd = new SveltoDictionary<uint, TValue, ManagedStrategy<SveltoDictionaryNode<uint>>, ManagedStrategy<TValue>, | |||
ManagedStrategy<int>>(size, Allocator.Managed); | |||
} | |||
@@ -181,7 +181,7 @@ namespace Svelto.ECS.Internal | |||
/// </summary> | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesAddCallbacks | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDB | |||
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDB | |||
, ITypeSafeDictionary toDic, ExclusiveGroupStruct toGroup, in PlatformProfiler profiler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesAddCallbacks(ref implMgd, (ITypeSafeDictionary<TValue>)toDic | |||
@@ -207,7 +207,7 @@ namespace Svelto.ECS.Internal | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesRemoveCallbacks | |||
(FasterList<(uint, string)> infosToProcess | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove | |||
, ExclusiveGroupStruct fromGroup, in PlatformProfiler sampler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesRemoveCallbacks(infosToProcess, ref implMgd, reactiveEnginesRemove | |||
@@ -219,7 +219,7 @@ namespace Svelto.ECS.Internal | |||
/// </summary> | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesAddEntityCallbacksFast | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd | |||
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd | |||
, ExclusiveGroupStruct groupID, (uint, uint) rangeOfSubmittedEntitiesIndicies, in PlatformProfiler profiler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesAddEntityCallbacksFast( | |||
@@ -257,14 +257,14 @@ namespace Svelto.ECS.Internal | |||
/// </summary> | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesSwapCallbacks_Group | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx | |||
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx | |||
, ITypeSafeDictionary toDictionary, ExclusiveGroupStruct fromGroup, ExclusiveGroupStruct toGroup | |||
, in PlatformProfiler profiler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesSwapCallbacks_Group( | |||
ref implMgd, (ITypeSafeDictionary<TValue>)toDictionary, toGroup, fromGroup, this, reactiveEnginesSwap | |||
, reactiveEnginesSwapEx, count, entityIDs, in profiler); | |||
ref implMgd, (ITypeSafeDictionary<TValue>)toDictionary, toGroup, fromGroup, reactiveEnginesSwap | |||
, reactiveEnginesSwapEx, entityIDs, in profiler); | |||
} | |||
/// <summary> | |||
@@ -273,12 +273,12 @@ namespace Svelto.ECS.Internal | |||
/// </summary> | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesRemoveCallbacks_Group | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx | |||
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx | |||
, ExclusiveGroupStruct group, in PlatformProfiler profiler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesRemoveCallbacks_Group( | |||
ref implMgd, this, reactiveEnginesRemove, reactiveEnginesRemoveEx, count, entityIDs, group | |||
ref implMgd, reactiveEnginesRemove, reactiveEnginesRemoveEx, entityIDs, group | |||
, in profiler); | |||
} | |||
@@ -287,10 +287,12 @@ namespace Svelto.ECS.Internal | |||
/// </summary> | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesDisposeCallbacks_Group | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> engines | |||
, ExclusiveGroupStruct group, in PlatformProfiler profiler) | |||
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> reactiveEnginesDispose, | |||
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>> reactiveEnginesDisposeEx, | |||
ExclusiveGroupStruct group, in PlatformProfiler profiler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesDisposeCallbacks_Group(ref implMgd, engines, group, in profiler); | |||
TypeSafeDictionaryMethods.ExecuteEnginesDisposeCallbacks_Group( | |||
ref implMgd, reactiveEnginesDispose, reactiveEnginesDisposeEx, entityIDs, group, in profiler); | |||
} | |||
SveltoDictionary<uint, TValue, ManagedStrategy<SveltoDictionaryNode<uint>>, ManagedStrategy<TValue>, | |||
@@ -57,7 +57,7 @@ namespace Svelto.ECS.Internal | |||
public static void ExecuteEnginesAddCallbacks<Strategy1, Strategy2, Strategy3, TValue>( | |||
ref SveltoDictionary<uint, TValue, Strategy1, Strategy2, Strategy3> fromDictionary | |||
, ITypeSafeDictionary<TValue> todic, ExclusiveGroupStruct togroup | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>> entitycomponentenginesdb | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>> entitycomponentenginesdb | |||
, in PlatformProfiler sampler) | |||
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>> | |||
where Strategy2 : struct, IBufferStrategy<TValue> | |||
@@ -65,7 +65,7 @@ namespace Svelto.ECS.Internal | |||
where TValue : struct, _IInternalEntityComponent | |||
{ | |||
if (entitycomponentenginesdb.TryGetValue( | |||
new RefWrapperType(TypeCache<TValue>.type) | |||
ComponentTypeID<TValue>.id | |||
, out var entityComponentsEngines)) | |||
{ | |||
if (entityComponentsEngines.count == 0) | |||
@@ -101,14 +101,15 @@ namespace Svelto.ECS.Internal | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public static void ExecuteEnginesDisposeCallbacks_Group<Strategy1, Strategy2, Strategy3, TValue>( | |||
ref SveltoDictionary<uint, TValue, Strategy1, Strategy2, Strategy3> fromDictionary | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> allEngines | |||
, ExclusiveGroupStruct inGroup, in PlatformProfiler sampler) | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> reactiveEnginesDispose | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>> reactiveEnginesDisposeEx | |||
, IEntityIDs entityids, ExclusiveGroupStruct group, in PlatformProfiler sampler) | |||
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>> | |||
where Strategy2 : struct, IBufferStrategy<TValue> | |||
where Strategy3 : struct, IBufferStrategy<int> | |||
where TValue : struct, _IInternalEntityComponent | |||
{ | |||
if (allEngines.TryGetValue(new RefWrapperType(TypeCache<TValue>.type), out var entityComponentsEngines) | |||
if (reactiveEnginesDispose.TryGetValue(ComponentTypeID<TValue>.id, out var entityComponentsEngines) | |||
== false) | |||
return; | |||
@@ -120,7 +121,7 @@ namespace Svelto.ECS.Internal | |||
foreach (var value in fromDictionary) | |||
{ | |||
ref var entity = ref value.value; | |||
var egid = new EGID(value.key, inGroup); | |||
var egid = new EGID(value.key, group); | |||
var reactOnRemove = (IReactOnDispose<TValue>)entityComponentsEngines[i].engine; | |||
reactOnRemove.Remove(ref entity, egid); | |||
} | |||
@@ -132,12 +133,41 @@ namespace Svelto.ECS.Internal | |||
throw; | |||
} | |||
var count = fromDictionary.count; | |||
if (reactiveEnginesDisposeEx.TryGetValue( | |||
ComponentTypeID<TValue>.id | |||
, out var reactiveEnginesDisposeExPerType)) | |||
{ | |||
var enginesCount = reactiveEnginesDisposeExPerType.count; | |||
for (var i = 0; i < enginesCount; i++) | |||
try | |||
{ | |||
using (sampler.Sample(reactiveEnginesDisposeExPerType[i].name)) | |||
{ | |||
((IReactOnDisposeEx<TValue>)reactiveEnginesDisposeExPerType[i].engine).Remove( | |||
(0, (uint)count) | |||
, new EntityCollection<TValue>( | |||
fromDictionary.UnsafeGetValues(out _), entityids | |||
, (uint)count), group); | |||
} | |||
} | |||
catch | |||
{ | |||
Console.LogError("Code crashed inside Remove callback ".FastConcat(reactiveEnginesDisposeExPerType[i].name)); | |||
throw; | |||
} | |||
} | |||
} | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public static void ExecuteEnginesRemoveCallbacks<Strategy1, Strategy2, Strategy3, TValue>(FasterList<(uint, string)> infostoprocess | |||
, ref SveltoDictionary<uint, TValue, Strategy1, Strategy2, Strategy3> fromDictionary | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveenginesremove | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveenginesremove | |||
, ExclusiveGroupStruct fromgroup, in PlatformProfiler profiler) | |||
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>> | |||
where Strategy2 : struct, IBufferStrategy<TValue> | |||
@@ -145,7 +175,7 @@ namespace Svelto.ECS.Internal | |||
where TValue : struct, _IInternalEntityComponent | |||
{ | |||
if (reactiveenginesremove.TryGetValue( | |||
new RefWrapperType(TypeCache<TValue>.type) | |||
ComponentTypeID<TValue>.id | |||
, out var entityComponentsEngines)) | |||
{ | |||
if (entityComponentsEngines.count == 0) | |||
@@ -185,17 +215,16 @@ namespace Svelto.ECS.Internal | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public static void ExecuteEnginesRemoveCallbacks_Group<Strategy1, Strategy2, Strategy3, TValue>( | |||
ref SveltoDictionary<uint, TValue, Strategy1, Strategy2, Strategy3> fromDictionary | |||
, ITypeSafeDictionary<TValue> typeSafeDictionary | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveenginesremove | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveenginesremoveex | |||
, int count, IEntityIDs entityids, ExclusiveGroupStruct group, in PlatformProfiler sampler) | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveenginesremove | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveenginesremoveex | |||
, IEntityIDs entityids, ExclusiveGroupStruct group, in PlatformProfiler sampler) | |||
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>> | |||
where Strategy2 : struct, IBufferStrategy<TValue> | |||
where Strategy3 : struct, IBufferStrategy<int> | |||
where TValue : struct, _IInternalEntityComponent | |||
{ | |||
if (reactiveenginesremove.TryGetValue( | |||
new RefWrapperType(TypeCache<TValue>.type) | |||
ComponentTypeID<TValue>.id | |||
, out var reactiveEnginesRemovePerType)) | |||
{ | |||
var enginesCount = reactiveEnginesRemovePerType.count; | |||
@@ -226,9 +255,10 @@ namespace Svelto.ECS.Internal | |||
} | |||
if (reactiveenginesremoveex.TryGetValue( | |||
new RefWrapperType(TypeCache<TValue>.type) | |||
ComponentTypeID<TValue>.id | |||
, out var reactiveEnginesRemoveExPerType)) | |||
{ | |||
var count = fromDictionary.count; | |||
var enginesCount = reactiveEnginesRemoveExPerType.count; | |||
for (var i = 0; i < enginesCount; i++) | |||
@@ -239,7 +269,7 @@ namespace Svelto.ECS.Internal | |||
((IReactOnRemoveEx<TValue>)reactiveEnginesRemoveExPerType[i].engine).Remove( | |||
(0, (uint)count) | |||
, new EntityCollection<TValue>( | |||
typeSafeDictionary.GetValues(out _), entityids | |||
fromDictionary.UnsafeGetValues(out _), entityids | |||
, (uint)count), group); | |||
} | |||
} | |||
@@ -300,10 +330,9 @@ namespace Svelto.ECS.Internal | |||
public static void ExecuteEnginesSwapCallbacks_Group<Strategy1, Strategy2, Strategy3, TValue>( | |||
ref SveltoDictionary<uint, TValue, Strategy1, Strategy2, Strategy3> fromDictionary | |||
, ITypeSafeDictionary<TValue> toDic, ExclusiveGroupStruct togroup, ExclusiveGroupStruct fromgroup | |||
, ITypeSafeDictionary<TValue> typeSafeDictionary | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveenginesswap | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveenginesswapex | |||
, int count, IEntityIDs entityids, in PlatformProfiler sampler) | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveenginesswap | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveenginesswapex | |||
, IEntityIDs entityids, in PlatformProfiler sampler) | |||
where Strategy1 : struct, IBufferStrategy<SveltoDictionaryNode<uint>> | |||
where Strategy2 : struct, IBufferStrategy<TValue> | |||
where Strategy3 : struct, IBufferStrategy<int> | |||
@@ -311,7 +340,7 @@ namespace Svelto.ECS.Internal | |||
{ | |||
//get all the engines linked to TValue | |||
if (!reactiveenginesswap.TryGetValue( | |||
new RefWrapperType(TypeCache<TValue>.type) | |||
ComponentTypeID<TValue>.id | |||
, out var reactiveEnginesSwapPerType)) | |||
return; | |||
@@ -342,10 +371,11 @@ namespace Svelto.ECS.Internal | |||
} | |||
if (reactiveenginesswapex.TryGetValue( | |||
new RefWrapperType(TypeCache<TValue>.type) | |||
ComponentTypeID<TValue>.id | |||
, out var reactiveEnginesRemoveExPerType)) | |||
{ | |||
var enginesCount = reactiveEnginesRemoveExPerType.count; | |||
var count = fromDictionary.count; | |||
for (var i = 0; i < enginesCount; i++) | |||
try | |||
@@ -355,7 +385,7 @@ namespace Svelto.ECS.Internal | |||
((IReactOnSwapEx<TValue>)reactiveEnginesRemoveExPerType[i].engine).MovedTo( | |||
(0, (uint)count) | |||
, new EntityCollection<TValue>( | |||
typeSafeDictionary.GetValues(out _), entityids | |||
fromDictionary.UnsafeGetValues(out _), entityids | |||
, (uint)count), fromgroup, togroup); | |||
} | |||
} | |||
@@ -467,14 +497,14 @@ namespace Svelto.ECS.Internal | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public static void ExecuteEnginesAddEntityCallbacksFast<TValue>( | |||
FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>> fasterDictionary | |||
FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>> fasterDictionary | |||
, ExclusiveGroupStruct groupId, (uint, uint) rangeTuple, IEntityIDs entityids | |||
, ITypeSafeDictionary<TValue> typeSafeDictionary, PlatformProfiler profiler) | |||
where TValue : struct, _IInternalEntityComponent | |||
{ | |||
//get all the engines linked to TValue | |||
if (!fasterDictionary.TryGetValue( | |||
new RefWrapperType(TypeCache<TValue>.type) | |||
ComponentTypeID<TValue>.id | |||
, out var entityComponentsEngines)) | |||
return; | |||
@@ -22,13 +22,13 @@ namespace Svelto.ECS.Internal | |||
sealed class UnmanagedTypeSafeDictionary<TValue> : ITypeSafeDictionary<TValue> | |||
where TValue : struct, _IInternalEntityComponent | |||
{ | |||
//todo: would this be better to not be static to avoid overhead? | |||
static readonly ThreadLocal<IEntityIDs> cachedEntityIDN = | |||
new ThreadLocal<IEntityIDs>(() => new NativeEntityIDs()); | |||
public UnmanagedTypeSafeDictionary(uint size) | |||
{ | |||
implUnmgd = | |||
new SharedSveltoDictionaryNative<uint, TValue>(size, Allocator.Persistent); | |||
implUnmgd = new SharedSveltoDictionaryNative<uint, TValue>(size, Allocator.Persistent); | |||
} | |||
public IEntityIDs entityIDs | |||
@@ -193,7 +193,7 @@ namespace Svelto.ECS.Internal | |||
/// </summary> | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesAddCallbacks | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDB | |||
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAdd>>> entityComponentEnginesDB | |||
, ITypeSafeDictionary toDic, ExclusiveGroupStruct toGroup, in PlatformProfiler profiler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesAddCallbacks(ref implUnmgd.dictionary, (ITypeSafeDictionary<TValue>)toDic | |||
@@ -219,7 +219,7 @@ namespace Svelto.ECS.Internal | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesRemoveCallbacks | |||
(FasterList<(uint, string)> infosToProcess | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove | |||
, ExclusiveGroupStruct fromGroup, in PlatformProfiler sampler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesRemoveCallbacks(infosToProcess, ref implUnmgd.dictionary | |||
@@ -231,7 +231,7 @@ namespace Svelto.ECS.Internal | |||
/// </summary> | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesAddEntityCallbacksFast | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd | |||
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnAddEx>>> reactiveEnginesAdd | |||
, ExclusiveGroupStruct groupID, (uint, uint) rangeOfSubmittedEntitiesIndicies, in PlatformProfiler profiler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesAddEntityCallbacksFast( | |||
@@ -269,14 +269,14 @@ namespace Svelto.ECS.Internal | |||
/// </summary> | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesSwapCallbacks_Group | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx | |||
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwap>>> reactiveEnginesSwap | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnSwapEx>>> reactiveEnginesSwapEx | |||
, ITypeSafeDictionary toDictionary, ExclusiveGroupStruct fromGroup, ExclusiveGroupStruct toGroup | |||
, in PlatformProfiler profiler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesSwapCallbacks_Group( | |||
ref implUnmgd.dictionary, (ITypeSafeDictionary<TValue>)toDictionary, toGroup, fromGroup, this | |||
, reactiveEnginesSwap, reactiveEnginesSwapEx, count, entityIDs, in profiler); | |||
ref implUnmgd.dictionary, (ITypeSafeDictionary<TValue>)toDictionary, toGroup, fromGroup | |||
, reactiveEnginesSwap, reactiveEnginesSwapEx, entityIDs, in profiler); | |||
} | |||
/// <summary> | |||
@@ -285,12 +285,12 @@ namespace Svelto.ECS.Internal | |||
/// </summary> | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesRemoveCallbacks_Group | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove | |||
, FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx | |||
(FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemove>>> reactiveEnginesRemove | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnRemoveEx>>> reactiveEnginesRemoveEx | |||
, ExclusiveGroupStruct group, in PlatformProfiler profiler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesRemoveCallbacks_Group( | |||
ref implUnmgd.dictionary, this, reactiveEnginesRemove, reactiveEnginesRemoveEx, count, entityIDs, group | |||
ref implUnmgd.dictionary, reactiveEnginesRemove, reactiveEnginesRemoveEx, entityIDs, group | |||
, in profiler); | |||
} | |||
@@ -299,11 +299,12 @@ namespace Svelto.ECS.Internal | |||
/// </summary> | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public void ExecuteEnginesDisposeCallbacks_Group | |||
(FasterDictionary<RefWrapperType, FasterList<ReactEngineContainer<IReactOnDispose>>> engines | |||
( FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDispose>>> reactiveEnginesDispose | |||
, FasterDictionary<ComponentID, FasterList<ReactEngineContainer<IReactOnDisposeEx>>> reactiveEnginesDisposeEx | |||
, ExclusiveGroupStruct group, in PlatformProfiler profiler) | |||
{ | |||
TypeSafeDictionaryMethods.ExecuteEnginesDisposeCallbacks_Group( | |||
ref implUnmgd.dictionary, engines, group, in profiler); | |||
ref implUnmgd.dictionary, reactiveEnginesDispose, reactiveEnginesDisposeEx, entityIDs, group, in profiler); | |||
} | |||
internal SharedSveltoDictionaryNative<uint, TValue> implUnmgd; | |||
@@ -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); | |||
} | |||
} | |||
} | |||
@@ -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 | |||
} |
@@ -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); | |||
@@ -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 | |||
@@ -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() | |||
@@ -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, | |||
@@ -1,5 +1,4 @@ | |||
using System.Runtime.CompilerServices; | |||
using Svelto.ECS.Internal; | |||
namespace Svelto.ECS.Serialization | |||
{ | |||
@@ -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; | |||
@@ -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> | |||
@@ -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,3 +1,3 @@ | |||
{ | |||
"version": "3.4.3" | |||
"version": "3.4.4" | |||
} |