From ab5e5c94bd13a6051cf79e27b9ec68f7657e6517 Mon Sep 17 00:00:00 2001 From: sebas77 Date: Fri, 20 Apr 2018 00:08:39 +0100 Subject: [PATCH] mega refactoring, now EntityView and EntityStructs use almost exactly the same code introduced EntityViewStruct cut a lot of code not needed anymore breaking change engines add and remove callback now accept only ref params breaking change QueryEntityViewsAsArray renamed in to QueryEntityViewsCacheFriendly --- Svelto.Common | 2 +- Svelto.ECS.csproj | 3 +- .../DataStructures/TypeSafeDictionary.cs | 76 ++++-- .../TypeSafeFasterListForECS.cs | 225 ------------------ .../TypeSafeFasterListForECSException.cs | 10 - Svelto.ECS/EGID.cs | 15 +- .../EnginesRoot.GenericEntityFactory.cs | 8 +- .../EnginesRoot.GenericEntityFunctions.cs | 4 +- Svelto.ECS/EnginesRootEngines.cs | 13 +- Svelto.ECS/EnginesRootEntities.cs | 147 +++--------- Svelto.ECS/EnginesRootSubmission.cs | 61 ++--- Svelto.ECS/EntityFactory.cs | 39 +-- Svelto.ECS/EntityViewBuilder.cs | 67 ++++-- Svelto.ECS/EntityViewStructBuilder.cs | 56 ----- ...FillEntityView.cs => EntityViewUtility.cs} | 29 ++- Svelto.ECS/EntityViewsDB.cs | 72 +++--- Svelto.ECS/ExclusiveGroups.cs | 2 +- Svelto.ECS/IEngine.cs | 6 +- Svelto.ECS/IEntityView.cs | 29 ++- Svelto.ECS/IEntityViewBuilder.cs | 8 +- Svelto.ECS/IEntityViewsDB.cs | 10 +- Svelto.ECS/MixedEntityDescriptor.cs | 107 --------- Svelto.ECS/MultiEntityViewsEngine.cs | 75 +----- Svelto.ECS/Profiler/EngineProfiler.cs | 6 +- Svelto.ECS/SingleEntityViewEngine.cs | 18 +- 25 files changed, 273 insertions(+), 815 deletions(-) delete mode 100644 Svelto.ECS/DataStructures/TypeSafeFasterListForECS.cs delete mode 100644 Svelto.ECS/DataStructures/TypeSafeFasterListForECSException.cs delete mode 100644 Svelto.ECS/EntityViewStructBuilder.cs rename Svelto.ECS/{FillEntityView.cs => EntityViewUtility.cs} (82%) delete mode 100644 Svelto.ECS/MixedEntityDescriptor.cs diff --git a/Svelto.Common b/Svelto.Common index 460c008..3c1360f 160000 --- a/Svelto.Common +++ b/Svelto.Common @@ -1 +1 @@ -Subproject commit 460c00846a3b547c4567aec8bdfff82a9861869c +Subproject commit 3c1360fcb86cdb70dcb00149a26d2064ec6fbe63 diff --git a/Svelto.ECS.csproj b/Svelto.ECS.csproj index a07171a..9a62eda 100644 --- a/Svelto.ECS.csproj +++ b/Svelto.ECS.csproj @@ -1,7 +1,8 @@  - netstandard2.0 Svelto.ECS + 6 + netstandard2.0 diff --git a/Svelto.ECS/DataStructures/TypeSafeDictionary.cs b/Svelto.ECS/DataStructures/TypeSafeDictionary.cs index 0260bfa..aea0029 100644 --- a/Svelto.ECS/DataStructures/TypeSafeDictionary.cs +++ b/Svelto.ECS/DataStructures/TypeSafeDictionary.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Svelto.DataStructures; @@ -13,20 +13,31 @@ namespace Svelto.ECS.Internal /// public interface ITypeSafeDictionary { - void FillWithIndexedEntityViews(ITypeSafeList entityViews); - bool Remove(EGID entityId); - IEntityData GetIndexedEntityView(EGID entityID); + void RemoveEntityFromDicAndEngines(EGID entityGid, + Dictionary> + entityViewEnginesDB); + void RemoveEntityViewsFromEngines( + Dictionary> entityViewEngines); + void AddCapacity(int size); + bool Remove(long idGid); + ITypeSafeDictionary Create(); + int Count { get; } + void FillWithIndexedEntityViews(ITypeSafeDictionary entityViews); + void AddEntityViewsToEngines(FasterList enginesForEntityView); } - class TypeSafeDictionaryForClass : Dictionary, ITypeSafeDictionary where TValue : IEntityData + class TypeSafeDictionary : FasterDictionary, ITypeSafeDictionary where TValue : IEntityData { - internal static readonly ReadOnlyDictionary Default = - new ReadOnlyDictionary(new Dictionary()); + public TypeSafeDictionary(int size):base(size) + {} - public void FillWithIndexedEntityViews(ITypeSafeList entityViews) + public TypeSafeDictionary() + {} + + public void FillWithIndexedEntityViews(ITypeSafeDictionary entityViews) { int count; - var buffer = FasterList.NoVirt.ToArrayFast((FasterList) entityViews, out count); + var buffer = (entityViews as TypeSafeDictionary).GetFasterValuesBuffer(out count); try { @@ -43,16 +54,53 @@ namespace Svelto.ECS.Internal } } - public bool Remove(EGID entityId) + public void AddEntityViewsToEngines(FasterList enginesForEntityView) + { + throw new NotImplementedException(); + } + + public void RemoveEntityFromDicAndEngines(EGID entityGid, + Dictionary> + entityViewEnginesDB) + { + + + TValue entity = this[entityGid.GID]; + + RemoveEntityViewsFromEngines(entityViewEnginesDB, ref entity); + + Remove(entityGid.GID); + } + + public void RemoveEntityViewsFromEngines(Dictionary> entityViewEnginesDB, ref TValue entity) { - base.Remove(entityId.GID); + FasterList entityViewsEngines; + if (entityViewEnginesDB.TryGetValue(typeof(TValue), out entityViewsEngines)) + for (int i = 0; i < entityViewEnginesDB.Count; i++) + (entityViewsEngines[i] as IHandleEntityStructEngine).Remove(ref entity); + } + + public void RemoveEntityViewsFromEngines(Dictionary> entityViewEnginesDB) + { + int count; + TValue[] values = this.GetFasterValuesBuffer(out count); + + for (int i = 0; i < count; i++) + { + TValue entity = values[i]; - return Count > 0; + RemoveEntityViewsFromEngines(entityViewEnginesDB, ref entity); + } + } + + public void AddCapacity(int size) + { + throw new NotImplementedException(); } - public IEntityData GetIndexedEntityView(EGID entityID) + public ITypeSafeDictionary Create() { - return this[entityID.GID]; + return new TypeSafeDictionary(); } } } \ No newline at end of file diff --git a/Svelto.ECS/DataStructures/TypeSafeFasterListForECS.cs b/Svelto.ECS/DataStructures/TypeSafeFasterListForECS.cs deleted file mode 100644 index e478ebd..0000000 --- a/Svelto.ECS/DataStructures/TypeSafeFasterListForECS.cs +++ /dev/null @@ -1,225 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using DBC; -using Svelto.DataStructures; - -namespace Svelto.ECS.Internal -{ - public interface ITypeSafeList : IEnumerable - { - bool isQueryiableEntityView { get; } - void AddRange(ITypeSafeList entityViewListValue); - - ITypeSafeList Create(); - bool MappedRemove(EGID entityID); - ITypeSafeDictionary CreateIndexedDictionary(); - EGIDEnumerator EntityIDS(); - void AddCapacity(int capacity); - - void Fill(FasterList enginesForEntityView); - } - - public struct EGIDEnumerator:IEnumerable, IEnumerator - { - Dictionary.Enumerator _keysEnumerator; - - public EGIDEnumerator(Dictionary mappedIndices) - { - _keysEnumerator = mappedIndices.GetEnumerator(); - } - - public bool MoveNext() - { - return _keysEnumerator.MoveNext(); - } - - public void Reset() - { - throw new NotImplementedException(); - } - - public object Current { get { return new EGID(_keysEnumerator.Current.Key);} } - public IEnumerator GetEnumerator() - { - return this; - } - } - - class TypeSafeFasterListForECS : FasterList where T : IEntityData - { - protected TypeSafeFasterListForECS() - { - _mappedIndices = new Dictionary(); - } - - protected TypeSafeFasterListForECS(int size) : base(size) - { - _mappedIndices = new Dictionary(); - } - - public bool MappedRemove(EGID entityID) - { - var index = _mappedIndices[entityID.GID]; - - Check.Assert(entityID.GID == this[index].ID.GID, - "Something went wrong with the Svelto.ECS code, please contact the author"); - - _mappedIndices.Remove(entityID.GID); - - if (UnorderedRemoveAt(index)) - { - _mappedIndices[this[index].ID.GID] = index; - } - - return Count > 0; - } - - public void AddRange(ITypeSafeList entityViewListValue) - { - var index = Count; - - base.AddRange(entityViewListValue as FasterList); - - for (var i = index; i < Count; ++i) - { - try - { - _mappedIndices.Add(this[i].ID.GID, i); - } - catch (Exception e) - { - throw new TypeSafeFasterListForECSException(e); - } - } - } - - public new void Add(T entityView) - { - var index = Count; - - base.Add(entityView); - - try - { - _mappedIndices.Add(entityView.ID.GID, index); - } - catch (Exception e) - { - throw new TypeSafeFasterListForECSException(e); - } - } - - public void AddCapacity(int capacity) - { - if (ToArrayFast().Length < Count + capacity) - Resize(Count + capacity); - } - - public int GetIndexFromID(EGID entityID) - { - return _mappedIndices[entityID.GID]; - } - - public EGIDEnumerator EntityIDS() - { - return new EGIDEnumerator(_mappedIndices); - } - - readonly Dictionary _mappedIndices; - } - - class TypeSafeFasterListForECSForStructs : TypeSafeFasterListForECS, ITypeSafeList where T:struct, IEntityData - { - public TypeSafeFasterListForECSForStructs(int size) : base(size) - {} - - public TypeSafeFasterListForECSForStructs() - {} - - public ITypeSafeList Create() - { - return new TypeSafeFasterListForECSForStructs(); - } - - public bool isQueryiableEntityView - { - get { return false; } - } - - public ITypeSafeDictionary CreateIndexedDictionary() - { - throw new NotImplementedException(); - } - - public void Fill(FasterList enginesForEntityView) - { - var thisfastList = NoVirt.ToArrayFast(this); - for (int i = 0; i < Count; i++) - { - int count; - var fastList = FasterList.NoVirt.ToArrayFast(enginesForEntityView, out count); - for (int j = 0; j < count; j++) - { -#if ENGINE_PROFILER_ENABLED - EngineProfiler.MonitorAddDuration(fastList[j], entityView); -#else - (fastList[j] as IHandleEntityStructEngine).Add(ref thisfastList[j]); -#endif - } - } - } - - public ITypeSafeList Create(int size) - { - return new TypeSafeFasterListForECSForStructs(size); - } - } - - class TypeSafeFasterListForECSForClasses : TypeSafeFasterListForECS, ITypeSafeList where T:IEntityData, new() - { - public TypeSafeFasterListForECSForClasses(int size) : base(size) - {} - - public TypeSafeFasterListForECSForClasses() - {} - - public ITypeSafeList Create() - { - return new TypeSafeFasterListForECSForClasses(); - } - - public bool isQueryiableEntityView - { - get { return true; } - } - - public ITypeSafeDictionary CreateIndexedDictionary() - { - return new TypeSafeDictionaryForClass(); - } - - public void Fill(FasterList enginesForEntityView) - { - var thisfastList = NoVirt.ToArrayFast(this); - for (int i = 0; i < Count; i++) - { - int count; - var fastList = FasterList.NoVirt.ToArrayFast(enginesForEntityView, out count); - for (int j = 0; j < count; j++) - { -#if ENGINE_PROFILER_ENABLED - EngineProfiler.MonitorAddDuration(fastList[j], entityView); -#else - (fastList[j] as IHandleEntityStructEngine).Add(ref thisfastList[j]); -#endif - } - } - } - - public ITypeSafeList Create(int size) - { - return new TypeSafeFasterListForECSForClasses(size); - } - } -} \ No newline at end of file diff --git a/Svelto.ECS/DataStructures/TypeSafeFasterListForECSException.cs b/Svelto.ECS/DataStructures/TypeSafeFasterListForECSException.cs deleted file mode 100644 index 038eaa2..0000000 --- a/Svelto.ECS/DataStructures/TypeSafeFasterListForECSException.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace Svelto.ECS -{ - public class TypeSafeFasterListForECSException : Exception - { - public TypeSafeFasterListForECSException(Exception exception):base("Trying to add an Entity View with the same ID more than once", exception) - {} - } -} \ No newline at end of file diff --git a/Svelto.ECS/EGID.cs b/Svelto.ECS/EGID.cs index 0b42a77..8d328d2 100644 --- a/Svelto.ECS/EGID.cs +++ b/Svelto.ECS/EGID.cs @@ -11,18 +11,19 @@ namespace Svelto.ECS get { return _GID; } } - public int ID + public int entityID { get { return (int) (_GID & 0xFFFFFFFF); } } - public int group + public int groupID { get { return (int) (_GID >> 32); } } public EGID(int entityID, int groupID) : this() { + DBC.Check.Require(groupID != ExclusiveGroups.StandardEntity, "can't use an exclusive group ID"); _GID = MAKE_GLOBAL_ID(entityID, groupID); } @@ -31,19 +32,9 @@ namespace Svelto.ECS _GID = MAKE_GLOBAL_ID(entityID, ExclusiveGroups.StandardEntity); } - internal EGID(long otherID) - { - _GID = otherID; - } - static long MAKE_GLOBAL_ID(int entityId, int groupId) { return (long)groupId << 32 | (uint)entityId; } - - public bool IsEqualTo(EGID otherGID) - { - return otherGID._GID == _GID; - } } } \ No newline at end of file diff --git a/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs b/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs index 2f53b7b..df55316 100644 --- a/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs +++ b/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs @@ -19,24 +19,24 @@ namespace Svelto.ECS public void BuildEntity(int entityID, object[] implementors) where T : IEntityDescriptor, new() { - _weakEngine.Target.BuildEntity(entityID, implementors); + _weakEngine.Target.BuildEntity(new EGID(entityID), implementors); } public void BuildEntity(int entityID, EntityDescriptorInfo entityDescriptor, object[] implementors = null) { - _weakEngine.Target.BuildEntity(entityID, entityDescriptor, implementors); + _weakEngine.Target.BuildEntity(new EGID(entityID), entityDescriptor, implementors); } public void BuildEntity(int entityID, int groupID, object[] implementors) where T : IEntityDescriptor, new() { - _weakEngine.Target.BuildEntity(entityID, groupID, implementors); + _weakEngine.Target.BuildEntity(new EGID(entityID, groupID), implementors); } public void BuildEntity(int entityID, int groupID, EntityDescriptorInfo entityDescriptor, object[] implementors) { - _weakEngine.Target.BuildEntity(entityID, groupID, entityDescriptor, implementors); + _weakEngine.Target.BuildEntity(new EGID(entityID, groupID), entityDescriptor, implementors); } public void PreallocateEntitySpace(int size) where T : IEntityDescriptor, new() diff --git a/Svelto.ECS/EnginesRoot.GenericEntityFunctions.cs b/Svelto.ECS/EnginesRoot.GenericEntityFunctions.cs index 1d3b1cf..a8cf615 100644 --- a/Svelto.ECS/EnginesRoot.GenericEntityFunctions.cs +++ b/Svelto.ECS/EnginesRoot.GenericEntityFunctions.cs @@ -19,12 +19,12 @@ namespace Svelto.ECS public void RemoveEntity(int entityID) { - _weakReference.Target.RemoveEntity(entityID, ExclusiveGroups.StandardEntity); + _weakReference.Target.RemoveEntity(new EGID(entityID)); } public void RemoveEntity(int entityID, int groupID) { - _weakReference.Target.RemoveEntity(entityID, groupID); + _weakReference.Target.RemoveEntity(new EGID(entityID, groupID)); } public void RemoveEntity(EGID entityEGID) diff --git a/Svelto.ECS/EnginesRootEngines.cs b/Svelto.ECS/EnginesRootEngines.cs index 7d554a7..cef158c 100644 --- a/Svelto.ECS/EnginesRootEngines.cs +++ b/Svelto.ECS/EnginesRootEngines.cs @@ -37,15 +37,12 @@ namespace Svelto.ECS _entityViewEngines = new Dictionary>(); _otherEngines = new FasterList(); - _groupEntityViewsDB = new Dictionary>(); - _groupEntityViewsDB[ExclusiveGroups.StandardEntity] = new Dictionary(); - _globalEntityViewsDBDic = new Dictionary(); + _groupEntityViewsDB = new Dictionary>(); + _groupEntityViewsDB[ExclusiveGroups.StandardEntity] = new Dictionary(); - _entityInfos = new Dictionary(); - - _groupedEntityViewsToAdd = new DoubleBufferedEntityViews>>(); + _groupedEntityViewsToAdd = new DoubleBufferedEntityViews>>(); - _DB = new EntityViewsDB(_globalEntityViewsDBDic, _groupEntityViewsDB); + _DB = new EntityViewsDB(_groupEntityViewsDB); _scheduler = entityViewScheduler; _scheduler.Schedule(new WeakAction(SubmitEntityViews)); @@ -119,7 +116,7 @@ namespace Svelto.ECS } readonly Dictionary> _entityViewEngines; - readonly FasterList _otherEngines; + readonly FasterList _otherEngines; static readonly Type _entityViewType= typeof(IEntityData); static readonly Type _objectType = typeof(object); diff --git a/Svelto.ECS/EnginesRootEntities.cs b/Svelto.ECS/EnginesRootEntities.cs index 9c3500b..de3348e 100644 --- a/Svelto.ECS/EnginesRootEntities.cs +++ b/Svelto.ECS/EnginesRootEntities.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using DBC; -using Svelto.DataStructures; using Svelto.ECS.Internal; #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR @@ -15,10 +14,8 @@ namespace Svelto.ECS public void Dispose() { foreach (var groups in _groupEntityViewsDB) - foreach (var entity in groups.Value) - if (entity.Value.isQueryiableEntityView == true) - foreach (var entityView in entity.Value) - RemoveEntityViewFromEngines(_entityViewEngines, entityView as IEntityData, entity.Key); + foreach (var entityList in groups.Value) + entityList.Value.RemoveEntityViewsFromEngines(_entityViewEngines); } ///-------------------------------------------- @@ -35,18 +32,6 @@ namespace Svelto.ECS ///-------------------------------------------- - void BuildEntity(int entityID, object[] implementors = null) where T : IEntityDescriptor, new() - { - BuildEntity - (entityID, ExclusiveGroups.StandardEntity, implementors); - } - - void BuildEntity(int entityID, EntityDescriptorInfo entityDescriptor, object[] implementors) - { - BuildEntity - (entityID, ExclusiveGroups.StandardEntity, entityDescriptor, implementors); - } - /// /// Build the entity using the entityID, inside the group with Id groupID, using the /// implementors (if necessary). The entityViews generated will be stored to be @@ -54,25 +39,22 @@ namespace Svelto.ECS /// /// /// - /// /// - void BuildEntity(int entityID, int groupID, object[] implementors = null) + void BuildEntity(EGID entityID, object[] implementors = null) where T : IEntityDescriptor, new() { - EntityFactory.BuildGroupedEntityViews(entityID, groupID, + EntityFactory.BuildGroupedEntityViews(entityID, _groupedEntityViewsToAdd.current, EntityDescriptorTemplate.Default, - _entityInfos, implementors); } - void BuildEntity(int entityID, int groupID, EntityDescriptorInfo entityDescriptor, + void BuildEntity(EGID entityID, EntityDescriptorInfo entityDescriptor, object[] implementors = null) { - EntityFactory.BuildGroupedEntityViews(entityID, groupID, + EntityFactory.BuildGroupedEntityViews(entityID, _groupedEntityViewsToAdd.current, entityDescriptor, - _entityInfos, implementors); } @@ -95,12 +77,12 @@ namespace Svelto.ECS var entityViewType = entityViewBuilder.GetEntityViewType(); //reserve space for the global pool - ITypeSafeList dbList; + ITypeSafeDictionary dbList; //reserve space for the single group - Dictionary @group; + Dictionary @group; if (_groupEntityViewsDB.TryGetValue(groupID, out group) == false) - group = _groupEntityViewsDB[groupID] = new Dictionary(); + group = _groupEntityViewsDB[groupID] = new Dictionary(); if (group.TryGetValue(entityViewType, out dbList) == false) group[entityViewType] = entityViewBuilder.Preallocate(ref dbList, size); @@ -108,7 +90,7 @@ namespace Svelto.ECS dbList.AddCapacity(size); if (_groupedEntityViewsToAdd.current.TryGetValue(groupID, out group) == false) - group = _groupEntityViewsDB[groupID] = new Dictionary(); + group = _groupEntityViewsDB[groupID] = new Dictionary(); //reserve space to the temporary buffer if (group.TryGetValue(entityViewType, out dbList) == false) @@ -120,102 +102,40 @@ namespace Svelto.ECS ///-------------------------------------------- /// - void RemoveEntity(int entityID, int groupID) - { - RemoveEntity(new EGID(entityID, groupID)); - } - void RemoveEntity(EGID entityGID) { - var entityViewBuilders = _entityInfos[entityGID.GID]; + var typeSafeDictionary = _groupEntityViewsDB[entityGID.groupID][typeof(EntityInfoView)] as TypeSafeDictionary; + var entityInfoView = typeSafeDictionary[entityGID.GID]; + var entityViewBuilders = entityInfoView.entityViewsToBuild; var entityViewBuildersCount = entityViewBuilders.Length; //for each entity view generated by the entity descriptor for (var i = 0; i < entityViewBuildersCount; i++) { var entityViewType = entityViewBuilders[i].GetEntityViewType(); - - if (entityViewBuilders[i].isQueryiableEntityView) - { - var group = _groupEntityViewsDB[entityGID.group]; - InternalRemoveEntityViewFromDBDicAndEngines(entityViewType, entityGID); - RemoveEntityViewFromDB(@group, entityViewType, entityGID); - } + var group = _groupEntityViewsDB[entityGID.groupID]; + + _groupEntityViewsDB[entityGID.groupID][entityViewType].RemoveEntityFromDicAndEngines(entityGID, _entityViewEngines); + RemoveEntityViewFromGroup(group, entityViewType, entityGID); } - - _entityInfos.Remove(entityGID.GID); } - static void RemoveEntityViewFromDB(Dictionary @group, Type entityViewType, EGID id) + static void RemoveEntityViewFromGroup(Dictionary @group, Type entityViewType, EGID id) { //remove it from entity views group DB var typeSafeList = @group[entityViewType]; - if (typeSafeList.MappedRemove(id) == false) //clean up + if (typeSafeList.Remove(id.GID) == false) //clean up @group.Remove(entityViewType); } void RemoveGroupAndEntitiesFromDB(int groupID) { - foreach (var group in _groupEntityViewsDB[groupID]) - { - var entityViewType = group.Key; - - var entities = group.Value.EntityIDS(); - - foreach (EGID entityID in entities) - { - if (group.Value.isQueryiableEntityView) - InternalRemoveEntityViewFromDBDicAndEngines(entityViewType, entityID); - } - } + foreach (var entiTypeSafeList in _groupEntityViewsDB[groupID]) + entiTypeSafeList.Value.RemoveEntityViewsFromEngines(_entityViewEngines); _groupEntityViewsDB.Remove(groupID); } - void InternalRemoveEntityViewFromDBDicAndEngines(Type entityViewType, EGID id) - { - var typeSafeDictionary = _globalEntityViewsDBDic[entityViewType]; - { - var entityView = typeSafeDictionary.GetIndexedEntityView(id); - - //the reason why this for exists is because in the past hierarchical entity views - //where supported :( - //Only EntityView can be removed from engines (won't work for IEntityData or IEntityData) - for (var current = entityViewType; current != _entityViewType; current = current.BaseType) - { -#if DEBUG && !PROFILER - if (current != entityViewType) - Utility.Console.LogWarning("Hierarchical Entity Views are design mistakes, ECS is not OOD!!"); -#endif - - RemoveEntityViewFromEngines(_entityViewEngines, entityView, current); - } - } - typeSafeDictionary.Remove(id); - } - - static void RemoveEntityViewFromEngines(Dictionary> entityViewEngines, - IEntityData entityView, Type entityViewType) - { - FasterList enginesForEntityView; - - if (entityViewEngines.TryGetValue(entityViewType, out enginesForEntityView)) - { - int count; - var fastList = FasterList.NoVirt.ToArrayFast(enginesForEntityView, out count); - - for (var j = 0; j < count; j++) - { -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR - EngineProfiler.MonitorRemoveDuration(fastList[j], entityView); -#else - var handleMixedEntityViewEngine = (fastList[j] as IHandleEntityViewEngine); - handleMixedEntityViewEngine.Remove(entityView); -#endif - } - } - } - ///-------------------------------------------- void SwapEntityGroup(int entityID, int fromGroupID, int toGroupID) @@ -224,15 +144,17 @@ namespace Svelto.ECS "can't move an entity to the same group where it already belongs to"); var entityegid = new EGID(entityID, fromGroupID); - var entityViewBuilders = _entityInfos[entityegid.GID]; + var entityViewBuilders = + ((TypeSafeDictionary) _groupEntityViewsDB[fromGroupID][typeof(EntityInfoView)]) + [entityegid.GID].entityViewsToBuild; var entityViewBuildersCount = entityViewBuilders.Length; var groupedEntities = _groupEntityViewsDB[fromGroupID]; - Dictionary groupedEntityViewsTyped; + Dictionary groupedEntityViewsTyped; if (_groupEntityViewsDB.TryGetValue(toGroupID, out groupedEntityViewsTyped) == false) { - groupedEntityViewsTyped = new Dictionary(); + groupedEntityViewsTyped = new Dictionary(); _groupEntityViewsDB.Add(toGroupID, groupedEntityViewsTyped); } @@ -243,30 +165,19 @@ namespace Svelto.ECS var entityViewType = entityViewBuilder.GetEntityViewType(); var fromSafeList = groupedEntities[entityViewType]; - ITypeSafeList toSafeList; + ITypeSafeDictionary toSafeList; if (groupedEntityViewsTyped.TryGetValue(entityViewType, out toSafeList) == false) groupedEntityViewsTyped[entityViewType] = toSafeList = fromSafeList.Create(); entityViewBuilder.MoveEntityView(entityegid, fromSafeList, toSafeList); - fromSafeList.MappedRemove(entityegid); + fromSafeList.Remove(entityegid.GID); } - - _entityInfos.Remove(entityegid.GID); - _entityInfos.Add(new EGID(entityID, toGroupID).GID, entityViewBuilders); } readonly EntityViewsDB _DB; //grouped set of entity views, this is the standard way to handle entity views - readonly Dictionary> _groupEntityViewsDB; - - - //TODO: Use faster dictionary and merge these two? - - //indexable entity views when the entity ID is known. Usually useful to handle - //event based logic. - readonly Dictionary _globalEntityViewsDBDic; - readonly Dictionary _entityInfos; + readonly Dictionary> _groupEntityViewsDB; } } \ No newline at end of file diff --git a/Svelto.ECS/EnginesRootSubmission.cs b/Svelto.ECS/EnginesRootSubmission.cs index 3e7de1b..04d1987 100644 --- a/Svelto.ECS/EnginesRootSubmission.cs +++ b/Svelto.ECS/EnginesRootSubmission.cs @@ -40,85 +40,56 @@ namespace Svelto.ECS } } //todo: can I make the entity creation less complicated? - void AddEntityViewsToTheDBAndSuitableEngines(Dictionary> groupsToSubmit) + void AddEntityViewsToTheDBAndSuitableEngines(Dictionary> groupsToSubmit) { //for each groups there is a dictionary of built lists of EntityView grouped by type foreach (var groupToSubmit in groupsToSubmit) { - Dictionary groupDB; + Dictionary groupDB; int groupID = groupToSubmit.Key; //if the group doesn't exist in the current DB let's create it frst if (_groupEntityViewsDB.TryGetValue(groupID, out groupDB) == false) - groupDB = _groupEntityViewsDB[groupID] = new Dictionary(); + groupDB = _groupEntityViewsDB[groupID] = new Dictionary(); - foreach (var entityViewsPerType in groupToSubmit.Value) + foreach (var entityViewList in groupToSubmit.Value) { //add the entity View in the group - if (entityViewsPerType.Value.isQueryiableEntityView == true) - AddEntityViewToDB(groupDB, entityViewsPerType); - //and it's not a struct, add in the indexable DB too - AddEntityViewToEntityViewsDictionary(_globalEntityViewsDBDic, entityViewsPerType.Value, entityViewsPerType.Key); + ITypeSafeDictionary dbList; + if (groupDB.TryGetValue(entityViewList.Key, out dbList) == false) + dbList = groupDB[entityViewList.Key] = entityViewList.Value.Create(); + + dbList.FillWithIndexedEntityViews(entityViewList.Value); } } //then submit everything in the engines, so that the DB is up to date //with all the entity views and struct created by the entity built foreach (var groupToSubmit in groupsToSubmit) - { + { foreach (var entityViewsPerType in groupToSubmit.Value) { var type = entityViewsPerType.Key; for (var current = type; current != _entityViewType && current != _objectType && current != _valueType; current = current.BaseType) - AddEntityViewToTheSuitableEngines(_entityViewEngines, entityViewsPerType.Value, + AddEntityViewsToTheSuitableEngines(_entityViewEngines, entityViewsPerType.Value, current); } } } - static void AddEntityViewToDB( Dictionary entityViewsDB, - KeyValuePair entityViewList) - { - - { - ITypeSafeList dbList; - - if (entityViewsDB.TryGetValue(entityViewList.Key, out dbList) == false) - dbList = entityViewsDB[entityViewList.Key] = entityViewList.Value.Create(); - - dbList.AddRange(entityViewList.Value); - } - } - - static void AddEntityViewToEntityViewsDictionary(Dictionary entityViewsDBdic, - ITypeSafeList entityViews, Type entityViewType) - { - if (entityViews.isQueryiableEntityView == true) - { - ITypeSafeDictionary entityViewsDic; - - if (entityViewsDBdic.TryGetValue(entityViewType, out entityViewsDic) == false) - entityViewsDic = entityViewsDBdic[entityViewType] = entityViews.CreateIndexedDictionary(); - - entityViewsDic.FillWithIndexedEntityViews(entityViews); - } - } - - static void AddEntityViewToTheSuitableEngines(Dictionary> entityViewEngines, - ITypeSafeList entityViewsList, - Type entityViewType) + static void AddEntityViewsToTheSuitableEngines( Dictionary> entityViewEngines, + ITypeSafeDictionary entityViewsList, + Type entityViewType) { FasterList enginesForEntityView; if (entityViewEngines.TryGetValue(entityViewType, out enginesForEntityView)) - { - entityViewsList.Fill(enginesForEntityView); - } + entityViewsList.AddEntityViewsToEngines(enginesForEntityView); } - readonly DoubleBufferedEntityViews>> _groupedEntityViewsToAdd; + readonly DoubleBufferedEntityViews>> _groupedEntityViewsToAdd; readonly EntitySubmissionScheduler _scheduler; } } \ No newline at end of file diff --git a/Svelto.ECS/EntityFactory.cs b/Svelto.ECS/EntityFactory.cs index 83ad1b4..2750b09 100644 --- a/Svelto.ECS/EntityFactory.cs +++ b/Svelto.ECS/EntityFactory.cs @@ -5,26 +5,23 @@ namespace Svelto.ECS.Internal { static class EntityFactory { - internal static void BuildGroupedEntityViews(int entityID, int groupID, - Dictionary> groupEntityViewsByType, + internal static void BuildGroupedEntityViews(EGID egid, + Dictionary> groupEntityViewsByType, EntityDescriptorInfo entityViewsToBuildDescriptor, - Dictionary entityInfos, object[] implementors) { - var @group = FetchGroup(groupID, groupEntityViewsByType); + var @group = FetchGroup(egid.groupID, groupEntityViewsByType); - BuildEntityViewsAndAddToGroup(new EGID(entityID, groupID), group, entityViewsToBuildDescriptor, implementors); - - entityInfos.Add(new EGID(entityID, groupID).GID, entityViewsToBuildDescriptor.entityViewsToBuild); + BuildEntityViewsAndAddToGroup(egid, group, entityViewsToBuildDescriptor, implementors); } - static Dictionary FetchGroup(int groupID, Dictionary> groupEntityViewsByType) + static Dictionary FetchGroup(int groupID, Dictionary> groupEntityViewsByType) { - Dictionary group; + Dictionary group; if (groupEntityViewsByType.TryGetValue(groupID, out @group) == false) { - @group = new Dictionary(); + @group = new Dictionary(); groupEntityViewsByType.Add(groupID, @group); } @@ -32,37 +29,43 @@ namespace Svelto.ECS.Internal } static void BuildEntityViewsAndAddToGroup(EGID entityID, - Dictionary entityViewsByType, + Dictionary entityViewsByType, EntityDescriptorInfo entityViewsToBuildDescriptor, object[] implementors) { var entityViewsToBuild = entityViewsToBuildDescriptor.entityViewsToBuild; var count = entityViewsToBuild.Length; - for (var index = 0; index < count; index++) + for (var index = 0; index < count; ++index) { var entityViewBuilder = entityViewsToBuild[index]; var entityViewType = entityViewBuilder.GetEntityViewType(); BuildEntityView(entityID, entityViewsByType, entityViewType, entityViewBuilder, implementors); } + + _viewBuilder._initializer = new EntityInfoView() {entityViewsToBuild = entityViewsToBuild}; + BuildEntityView(entityID, entityViewsByType, _viewType, _viewBuilder, null); } - static void BuildEntityView(EGID entityID, Dictionary entityViewsByType, - Type entityViewType, IEntityViewBuilder entityViewBuilder, object[] implementors) + static void BuildEntityView(EGID entityID, Dictionary entityViewsByType, + Type entityViewType, IEntityViewBuilder entityViewBuilder, object[] implementors) { - ITypeSafeList entityViewsList; + ITypeSafeDictionary safeDictionary; var entityViewsPoolWillBeCreated = - entityViewsByType.TryGetValue(entityViewType, out entityViewsList) == false; + entityViewsByType.TryGetValue(entityViewType, out safeDictionary) == false; //passing the undefined entityViewsByType inside the entityViewBuilder will allow //it to be created with the correct type and casted back to the undefined list. //that's how the list will be eventually of the target type. - entityViewBuilder.BuildEntityViewAndAddToList(ref entityViewsList, entityID, implementors); + entityViewBuilder.BuildEntityViewAndAddToList(ref safeDictionary, entityID, implementors); if (entityViewsPoolWillBeCreated) - entityViewsByType.Add(entityViewType, entityViewsList); + entityViewsByType.Add(entityViewType, safeDictionary); } + + static readonly EntityViewBuilder _viewBuilder = new EntityViewBuilder(); + static readonly Type _viewType = typeof(EntityInfoView); } } \ No newline at end of file diff --git a/Svelto.ECS/EntityViewBuilder.cs b/Svelto.ECS/EntityViewBuilder.cs index 0e980a8..2050b56 100644 --- a/Svelto.ECS/EntityViewBuilder.cs +++ b/Svelto.ECS/EntityViewBuilder.cs @@ -8,29 +8,48 @@ namespace Svelto.ECS { public class EntityViewBuilder : IEntityViewBuilder where EntityViewType : IEntityData, new() { - public void BuildEntityViewAndAddToList(ref ITypeSafeList list, EGID entityID, object[] implementors) + public EntityViewBuilder(ref EntityViewType initializer) + { + _initializer = initializer; + } + + public EntityViewBuilder() + {} + + public void BuildEntityViewAndAddToList(ref ITypeSafeDictionary list, EGID entityID, object[] implementors) { if (list == null) - list = new TypeSafeFasterListForECSForClasses(); - - var castedList = list as TypeSafeFasterListForECSForClasses; + list = new TypeSafeDictionary(); - var lentityView = EntityView.BuildEntityView(entityID); + var castedList = list as TypeSafeDictionary; - castedList.Add(lentityView); + if (implementors != null) + { + EntityViewType lentityView; + + EntityView.BuildEntityView(entityID, out lentityView); - var entityView = lentityView; - - this.FillEntityView(ref entityView - , entityViewBlazingFastReflection - , implementors - , DESCRIPTOR_NAME); + this.FillEntityView(ref lentityView + , entityViewBlazingFastReflection + , implementors + , DESCRIPTOR_NAME); + + castedList.Add(entityID.GID, ref lentityView); + } + else + { + DBC.Check.Require(_initializer != null, "Implementors not found on a EntityView instance"); + + _initializer.ID = entityID; + + castedList.Add(entityID.GID, ref _initializer); + } } - public ITypeSafeList Preallocate(ref ITypeSafeList list, int size) + public ITypeSafeDictionary Preallocate(ref ITypeSafeDictionary list, int size) { if (list == null) - list = new TypeSafeFasterListForECSForClasses(size); + list = new TypeSafeDictionary(size); else list.AddCapacity(size); @@ -42,24 +61,22 @@ namespace Svelto.ECS return ENTITY_VIEW_TYPE; } - public void MoveEntityView(EGID entityID, ITypeSafeList fromSafeList, ITypeSafeList toSafeList) + public void MoveEntityView(EGID entityID, ITypeSafeDictionary fromSafeList, ITypeSafeDictionary toSafeList) { - var fromCastedList = fromSafeList as TypeSafeFasterListForECSForClasses; - var toCastedList = toSafeList as TypeSafeFasterListForECSForClasses; + var fromCastedList = fromSafeList as TypeSafeDictionary; + var toCastedList = toSafeList as TypeSafeDictionary; - toCastedList.Add(fromCastedList[fromCastedList.GetIndexFromID(entityID)]); - } - - public bool isQueryiableEntityView - { - get { return true; } + toCastedList.Add(entityID.GID, fromCastedList[entityID.GID]); + fromCastedList.Remove(entityID.GID); } FasterList>> entityViewBlazingFastReflection { - get { return EntityView.FieldCache.list; } + get { return EntityView.FieldCache.list; } } - + + internal EntityViewType _initializer; + static readonly Type ENTITY_VIEW_TYPE = typeof(EntityViewType); static string DESCRIPTOR_NAME = ENTITY_VIEW_TYPE.ToString(); } diff --git a/Svelto.ECS/EntityViewStructBuilder.cs b/Svelto.ECS/EntityViewStructBuilder.cs deleted file mode 100644 index a13206e..0000000 --- a/Svelto.ECS/EntityViewStructBuilder.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using Svelto.ECS.Internal; - -namespace Svelto.ECS -{ - public class EntityViewStructBuilder : IEntityViewBuilder where EntityViewType : struct, IEntityData - { - public EntityViewStructBuilder(ref EntityViewType initializer) - { - _initializer = initializer; - } - - public void BuildEntityViewAndAddToList(ref ITypeSafeList list, EGID entityID, object[] implementors = null) - { - _initializer.ID = entityID; - - if (list == null) - list = new TypeSafeFasterListForECSForStructs(); - - var castedList = list as TypeSafeFasterListForECSForStructs; - - castedList.Add(_initializer); - } - - public ITypeSafeList Preallocate(ref ITypeSafeList list, int size) - { - if (list == null) - list = new TypeSafeFasterListForECSForStructs(size); - else - list.AddCapacity(size); - - return list; - } - - public Type GetEntityViewType() - { - return ENTITY_VIEW_TYPE; - } - - public void MoveEntityView(EGID entityID, ITypeSafeList fromSafeList, ITypeSafeList toSafeList) - { - var fromCastedList = fromSafeList as TypeSafeFasterListForECSForStructs; - var toCastedList = toSafeList as TypeSafeFasterListForECSForStructs; - - toCastedList.Add(fromCastedList[fromCastedList.GetIndexFromID(entityID)]); - } - - public bool isQueryiableEntityView - { - get { return false; } - } - - static readonly Type ENTITY_VIEW_TYPE = typeof(EntityViewType); - EntityViewType _initializer; - } -} \ No newline at end of file diff --git a/Svelto.ECS/FillEntityView.cs b/Svelto.ECS/EntityViewUtility.cs similarity index 82% rename from Svelto.ECS/FillEntityView.cs rename to Svelto.ECS/EntityViewUtility.cs index 6a8a4b0..2b804cb 100644 --- a/Svelto.ECS/FillEntityView.cs +++ b/Svelto.ECS/EntityViewUtility.cs @@ -5,13 +5,13 @@ using Svelto.ECS; using Svelto.Utilities; using Console = Utility.Console; -static class FillEntityViewASD +static class EntityViewUtility { - public static void FillEntityView(this IEntityViewBuilder entityViewBuilder, - ref T entityView, - FasterList>> entityViewBlazingFastReflection , - object[] implementors - , string entityDescriptorName) + public static void FillEntityView(this IEntityViewBuilder entityViewBuilder + , ref T entityView + , FasterList>> entityViewBlazingFastReflection + , object[] implementors + , string entityDescriptorName) { int count; @@ -19,9 +19,10 @@ static class FillEntityViewASD var setters = FasterList>> .NoVirt.ToArrayFast(entityViewBlazingFastReflection, out count); - - if (count == 0) return; - +#if DEBUG && !PROFILER + if (count == 0) + throw new Exception(NO_COMPONENTS_EXCEPTION.FastConcat("Type ", entityDescriptorName, " entityView ", entityViewBuilder.GetEntityViewType().ToString())); +#endif for (var index = 0; index < implementors.Length; index++) { var implementor = implementors[index]; @@ -45,7 +46,7 @@ static class FillEntityViewASD else implementorsByType[componentType] = new Tuple(implementor, 1); #else - implementorsByType[componentType] = implementor; + implementorsByType[componentType] = implementor; #endif } } @@ -65,7 +66,7 @@ static class FillEntityViewASD #if DEBUG && !PROFILER Tuple component; #else - object component; + object component; #endif if (implementorsByType.TryGetValue(fieldType, out component) == false) @@ -88,7 +89,7 @@ static class FillEntityViewASD #if DEBUG && !PROFILER fieldSetter.Value.Call(ref entityView, component.implementorType); #else - fieldSetter.Value.Call(entityView, component); + fieldSetter.Value.Call(ref entityView, component); #endif } @@ -118,7 +119,9 @@ static class FillEntityViewASD } #endif static readonly Dictionary _cachedTypes = new Dictionary(); - + const string NO_COMPONENTS_EXCEPTION = + "Svelto.ECS An entity view without component interfaces has been found, if you are using an entity view struct or an entity struct, do not pass implementors"; + const string DUPLICATE_IMPLEMENTOR_ERROR = "Svelto.ECS the same component is implemented with more than one implementor. This is considered an error and MUST be fixed. "; diff --git a/Svelto.ECS/EntityViewsDB.cs b/Svelto.ECS/EntityViewsDB.cs index 733f9a4..0e8d74d 100644 --- a/Svelto.ECS/EntityViewsDB.cs +++ b/Svelto.ECS/EntityViewsDB.cs @@ -6,70 +6,54 @@ namespace Svelto.ECS.Internal { class EntityViewsDB : IEntityViewsDB { - internal EntityViewsDB( Dictionary entityViewsDBdic, - Dictionary> groupEntityViewsDB) + internal EntityViewsDB(Dictionary> groupEntityViewsDB) { - _groupedEntityViewsDBDic = entityViewsDBdic; _groupEntityViewsDB = groupEntityViewsDB; } - public FasterReadOnlyList QueryEntityViews() where T:IEntityData + public ReadOnlyCollectionStruct QueryEntityViews() where T:IEntityData { - var type = typeof(T); - - ITypeSafeList entityViews; - - if (_groupEntityViewsDB[ExclusiveGroups.StandardEntity].TryGetValue(type, out entityViews) == false) - return RetrieveEmptyEntityViewList(); - - return new FasterReadOnlyList((FasterList)entityViews); + return QueryEntityViews(ExclusiveGroups.StandardEntity); } - public FasterReadOnlyList QueryGroupedEntityViews(int @group) where T:IEntityData + public ReadOnlyCollectionStruct QueryEntityViews(int @group) where T:IEntityData { - Dictionary entitiesInGroupPerType; + Dictionary entitiesInGroupPerType; if (_groupEntityViewsDB.TryGetValue(group, out entitiesInGroupPerType) == false) return RetrieveEmptyEntityViewList(); - ITypeSafeList outList; + ITypeSafeDictionary outList; if (entitiesInGroupPerType.TryGetValue(typeof(T), out outList) == false) return RetrieveEmptyEntityViewList(); - - return new FasterReadOnlyList((FasterList) outList); + + return (outList as TypeSafeDictionary).FasterValues; } - public T[] QueryEntityViewsAsArray(out int count) where T : IEntityData + public T[] QueryEntityViewsCacheFriendly(out int count) where T : IEntityData { - var type = typeof(T); - count = 0; - - ITypeSafeList entityViews; - - if (_groupEntityViewsDB[ExclusiveGroups.StandardEntity].TryGetValue(type, out entityViews) == false) - return RetrieveEmptyEntityViewArray(); - - return FasterList.NoVirt.ToArrayFast((FasterList)entityViews, out count); + return QueryEntityViewsCacheFriendly(ExclusiveGroups.StandardEntity, out count); } - public T[] QueryGroupedEntityViewsAsArray(int @group, out int count) where T : IEntityData + public T[] QueryEntityViewsCacheFriendly(int @group, out int count) where T : IEntityData { var type = typeof(T); count = 0; - Dictionary entitiesInGroupPerType; + Dictionary entitiesInGroupPerType; if (_groupEntityViewsDB.TryGetValue(group, out entitiesInGroupPerType) == false) return RetrieveEmptyEntityViewArray(); - ITypeSafeList outList; + ITypeSafeDictionary outList; if (entitiesInGroupPerType.TryGetValue(typeof(T), out outList) == false) return RetrieveEmptyEntityViewArray(); - - return FasterList.NoVirt.ToArrayFast((FasterList)entitiesInGroupPerType[type], out count); + + var typeSafeDictionary = entitiesInGroupPerType[type]; + return ((TypeSafeDictionary) typeSafeDictionary).GetFasterValuesBuffer(out count); } - public T QueryEntityView(EGID entityGID) where T : IEntityData + public T QueryEntityView(EGID entityGID) where T : class, IEntityData { T entityView; @@ -88,11 +72,17 @@ namespace Svelto.ECS.Internal var type = typeof(T); T internalEntityView; - ITypeSafeDictionary entityViews; + + Dictionary entitiesInGroupPerType; + if (_groupEntityViewsDB.TryGetValue(entityGID.groupID, out entitiesInGroupPerType) == false) + { + entityView = default(T); + return false; + } - _groupedEntityViewsDBDic.TryGetValue(type, out entityViews); - var casted = entityViews as TypeSafeDictionaryForClass; + entitiesInGroupPerType.TryGetValue(type, out entityViews); + var casted = entityViews as TypeSafeDictionary; if (casted != null && casted.TryGetValue(entityGID.GID, out internalEntityView)) @@ -107,21 +97,17 @@ namespace Svelto.ECS.Internal return false; } - static FasterReadOnlyList RetrieveEmptyEntityViewList() + static ReadOnlyCollectionStruct RetrieveEmptyEntityViewList() { - return FasterReadOnlyList.DefaultList; + return ReadOnlyCollectionStruct.DefaultList; } static T[] RetrieveEmptyEntityViewArray() { return FasterList.DefaultList.ToArrayFast(); } - //grouped set of entity views, this is the standard way to handle entity views - readonly Dictionary> _groupEntityViewsDB; - //indexable entity views when the entity ID is known. Usually useful to handle - //event based logic. - readonly Dictionary _groupedEntityViewsDBDic; + readonly Dictionary> _groupEntityViewsDB; } } diff --git a/Svelto.ECS/ExclusiveGroups.cs b/Svelto.ECS/ExclusiveGroups.cs index 5e8eb2f..5556989 100644 --- a/Svelto.ECS/ExclusiveGroups.cs +++ b/Svelto.ECS/ExclusiveGroups.cs @@ -2,6 +2,6 @@ { static class ExclusiveGroups { - internal const int StandardEntity = 0xFF; + internal const int StandardEntity = int.MaxValue; } } \ No newline at end of file diff --git a/Svelto.ECS/IEngine.cs b/Svelto.ECS/IEngine.cs index a06bd82..0657775 100644 --- a/Svelto.ECS/IEngine.cs +++ b/Svelto.ECS/IEngine.cs @@ -4,11 +4,6 @@ namespace Svelto.ECS.Internal { public interface IHandleEntityViewEngineAbstracted : IEngine {} - - public interface IHandleEntityViewEngine : IHandleEntityViewEngineAbstracted - { - void Remove(IEntityData entityView); - } } namespace Svelto.ECS @@ -19,5 +14,6 @@ namespace Svelto.ECS public interface IHandleEntityStructEngine : IHandleEntityViewEngineAbstracted { void Add(ref T entityView); + void Remove(ref T entityView); } } \ No newline at end of file diff --git a/Svelto.ECS/IEntityView.cs b/Svelto.ECS/IEntityView.cs index 7109aff..81e632b 100644 --- a/Svelto.ECS/IEntityView.cs +++ b/Svelto.ECS/IEntityView.cs @@ -22,36 +22,43 @@ namespace Svelto.ECS EGID _ID; } - - static class EntityView where T: IEntityData, new() + + public struct EntityInfoView : IEntityData { - internal static T BuildEntityView(EGID ID) + public EGID ID { get; set; } + + public IEntityViewBuilder[] entityViewsToBuild; + } + + public static class EntityView where T: IEntityData, new() + { + internal static void BuildEntityView(EGID ID, out T entityView) { - if (FieldCache.list.Count == 0) + if (FieldCache.list == null) { + FieldCache.list = new FasterList>>(); + var type = typeof(T); var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); - + for (int i = fields.Length - 1; i >= 0; --i) { var field = fields[i]; CastedAction setter = FastInvoke.MakeSetter(field); - FieldCache.list.Add(new KeyValuePair>(field.FieldType, setter)); + FieldCache.list.Add(new KeyValuePair>(field.FieldType, setter)); } } - return new T { ID = ID }; + entityView = new T { ID = ID }; } - //check if I can remove W - internal static class FieldCache + public static class FieldCache { - internal static readonly FasterList>> list - = new FasterList>>(); + public static FasterList>> list; } } } diff --git a/Svelto.ECS/IEntityViewBuilder.cs b/Svelto.ECS/IEntityViewBuilder.cs index ca7f47d..fcd6412 100644 --- a/Svelto.ECS/IEntityViewBuilder.cs +++ b/Svelto.ECS/IEntityViewBuilder.cs @@ -5,12 +5,10 @@ namespace Svelto.ECS { public interface IEntityViewBuilder { - void BuildEntityViewAndAddToList(ref ITypeSafeList list, EGID entityID, object[] implementors); - ITypeSafeList Preallocate(ref ITypeSafeList list, int size); + void BuildEntityViewAndAddToList(ref ITypeSafeDictionary list, EGID entityID, object[] implementors); + ITypeSafeDictionary Preallocate(ref ITypeSafeDictionary list, int size); Type GetEntityViewType(); - void MoveEntityView(EGID entityID, ITypeSafeList fromSafeList, ITypeSafeList toSafeList); - - bool isQueryiableEntityView { get; } + void MoveEntityView(EGID entityID, ITypeSafeDictionary fromSafeList, ITypeSafeDictionary toSafeList); } } \ No newline at end of file diff --git a/Svelto.ECS/IEntityViewsDB.cs b/Svelto.ECS/IEntityViewsDB.cs index 8b0be87..3611bfc 100644 --- a/Svelto.ECS/IEntityViewsDB.cs +++ b/Svelto.ECS/IEntityViewsDB.cs @@ -4,13 +4,13 @@ namespace Svelto.ECS { public interface IEntityViewsDB { - FasterReadOnlyList QueryEntityViews() where T : IEntityData; - FasterReadOnlyList QueryGroupedEntityViews(int group) where T : IEntityData; + ReadOnlyCollectionStruct QueryEntityViews() where T : IEntityData; + ReadOnlyCollectionStruct QueryEntityViews(int group) where T : IEntityData; - T[] QueryEntityViewsAsArray(out int count) where T : IEntityData; - T[] QueryGroupedEntityViewsAsArray(int group, out int count) where T : IEntityData; + T[] QueryEntityViewsCacheFriendly(out int count) where T : IEntityData; + T[] QueryEntityViewsCacheFriendly(int group, out int count) where T : IEntityData; bool TryQueryEntityView(EGID ID, out T entityView) where T : IEntityData; - T QueryEntityView(EGID entityGID) where T : IEntityData; + T QueryEntityView(EGID entityGID) where T : class, IEntityData; } } \ No newline at end of file diff --git a/Svelto.ECS/MixedEntityDescriptor.cs b/Svelto.ECS/MixedEntityDescriptor.cs deleted file mode 100644 index 3a27826..0000000 --- a/Svelto.ECS/MixedEntityDescriptor.cs +++ /dev/null @@ -1,107 +0,0 @@ -namespace Svelto.ECS -{ - public abstract class MixedEntityDescriptor:IEntityDescriptor where T : class, IEntityViewBuilder, new() - { - static MixedEntityDescriptor() - { - _entityViewsToBuild = new IEntityViewBuilder[] {new T()}; - } - - public IEntityViewBuilder[] entityViewsToBuild - { - get { return _entityViewsToBuild; } - } - - static readonly IEntityViewBuilder[] _entityViewsToBuild; - } - - public abstract class MixedEntityDescriptor : IEntityDescriptor where T : class, IEntityViewBuilder, new() - where U : class, IEntityViewBuilder, new() - { - static MixedEntityDescriptor() - { - _entityViewsToBuild = new IEntityViewBuilder[] {new T(), new U()}; - } - - public IEntityViewBuilder[] entityViewsToBuild - { - get { return _entityViewsToBuild; } - } - - static readonly IEntityViewBuilder[] _entityViewsToBuild; - } - - public abstract class MixedEntityDescriptor : IEntityDescriptor where T : class, IEntityViewBuilder, new() - where U : class, IEntityViewBuilder, new() - where V : class, IEntityViewBuilder, new() - { - static MixedEntityDescriptor() - { - _entityViewsToBuild = new IEntityViewBuilder[] {new T(), new U(), new V()}; - } - - public IEntityViewBuilder[] entityViewsToBuild - { - get { return _entityViewsToBuild; } - } - - static readonly IEntityViewBuilder[] _entityViewsToBuild; - } - - public abstract class MixedEntityDescriptor : IEntityDescriptor where T : class, IEntityViewBuilder, new() - where U : class, IEntityViewBuilder, new() - where V : class, IEntityViewBuilder, new() - where W : class, IEntityViewBuilder, new() - { - static MixedEntityDescriptor() - { - _entityViewsToBuild = new IEntityViewBuilder[] {new T(), new U(), new V(), new W()}; - } - - public IEntityViewBuilder[] entityViewsToBuild - { - get { return _entityViewsToBuild; } - } - - static readonly IEntityViewBuilder[] _entityViewsToBuild; - } - - public abstract class MixedEntityDescriptor : IEntityDescriptor where T : class, IEntityViewBuilder, new() - where U : class, IEntityViewBuilder, new() - where V : class, IEntityViewBuilder, new() - where W : class, IEntityViewBuilder, new() - where X : class, IEntityViewBuilder, new() - { - static MixedEntityDescriptor() - { - _entityViewsToBuild = new IEntityViewBuilder[] {new T(), new U(), new V(), new W(), new X()}; - } - - public IEntityViewBuilder[] entityViewsToBuild - { - get { return _entityViewsToBuild; } - } - - static readonly IEntityViewBuilder[] _entityViewsToBuild; - } - - public abstract class MixedEntityDescriptor : IEntityDescriptor where T : class, IEntityViewBuilder, new() - where U : class, IEntityViewBuilder, new() - where V : class, IEntityViewBuilder, new() - where W : class, IEntityViewBuilder, new() - where X : class, IEntityViewBuilder, new() - where Y : class, IEntityViewBuilder, new() - { - static MixedEntityDescriptor() - { - _entityViewsToBuild = new IEntityViewBuilder[] {new T(), new U(), new V(), new W(), new X(), new Y()}; - } - - public IEntityViewBuilder[] entityViewsToBuild - { - get { return _entityViewsToBuild; } - } - - static readonly IEntityViewBuilder[] _entityViewsToBuild; - } -} diff --git a/Svelto.ECS/MultiEntityViewsEngine.cs b/Svelto.ECS/MultiEntityViewsEngine.cs index 05f18d3..93bf157 100644 --- a/Svelto.ECS/MultiEntityViewsEngine.cs +++ b/Svelto.ECS/MultiEntityViewsEngine.cs @@ -1,65 +1,17 @@ -using Svelto.ECS.Internal; - -namespace Svelto.ECS.Internal -{ - public abstract class MultiEntityViewsEngine:IHandleEntityStructEngine, - IHandleEntityViewEngine where T:IEntityData - { - public void Add(ref T entityView) - { - Add(entityView); - } - - public virtual void Remove(IEntityData entityView) - { - Remove((T) entityView); - } - - protected abstract void Add(T entityView); - protected abstract void Remove(T entityView); - } -} - namespace Svelto.ECS { - public abstract class MultiEntityViewsEngine : MultiEntityViewsEngine, IHandleEntityStructEngine + public abstract class MultiEntityViewsEngine : SingleEntityViewEngine, IHandleEntityStructEngine where U : IEntityData where T : IEntityData { - protected abstract void Add(U entityView); - protected abstract void Remove(U entityView); - - public override void Remove(IEntityData entityView) - { - if (entityView is U) - Remove((U) entityView); - else - base.Remove(entityView); - } - - public void Add(ref U entityView) - { - Add(entityView); - } + public abstract void Add(ref U entityView); + public abstract void Remove(ref U entityView); } public abstract class MultiEntityViewsEngine : MultiEntityViewsEngine, IHandleEntityStructEngine where V : IEntityData where U : IEntityData where T : IEntityData { - protected abstract void Add(V entityView); - protected abstract void Remove(V entityView); - - public override void Remove(IEntityData entityView) - { - if (entityView is V) - Remove((V) entityView); - else - base.Remove(entityView); - } - - public void Add(ref V entityView) - { - Add(entityView); - } + public abstract void Add(ref V entityView); + public abstract void Remove(ref V entityView); } /// @@ -70,20 +22,7 @@ namespace Svelto.ECS public abstract class MultiEntityViewsEngine : MultiEntityViewsEngine, IHandleEntityStructEngine where W : IEntityData where V : IEntityData where U : IEntityData where T : IEntityData { - protected abstract void Add(W entityView); - protected abstract void Remove(W entityView); - - public override void Remove(IEntityData entityView) - { - if (entityView is W) - Remove((W) entityView); - else - base.Remove(entityView); - } - - public void Add(ref W entityView) - { - Add(entityView); - } + public abstract void Add(ref W entityView); + public abstract void Remove(ref W entityView); } } \ No newline at end of file diff --git a/Svelto.ECS/Profiler/EngineProfiler.cs b/Svelto.ECS/Profiler/EngineProfiler.cs index 78f027d..2aeb967 100644 --- a/Svelto.ECS/Profiler/EngineProfiler.cs +++ b/Svelto.ECS/Profiler/EngineProfiler.cs @@ -12,7 +12,7 @@ namespace Svelto.ECS.Profiler { static readonly Stopwatch _stopwatch = new Stopwatch(); - public static void MonitorAddDuration(IHandleEntityViewEngineAbstracted engine, T entityView) + public static void MonitorAddDuration(IHandleEntityViewEngineAbstracted engine, ref T entityView) { EngineInfo info; if (engineInfos.TryGetValue(engine.GetType(), out info)) @@ -25,13 +25,13 @@ namespace Svelto.ECS.Profiler } } - public static void MonitorRemoveDuration(IHandleEntityViewEngineAbstracted engine, IEntityData entityView) + public static void MonitorRemoveDuration(IHandleEntityViewEngineAbstracted engine, ref T entityView) { EngineInfo info; if (engineInfos.TryGetValue(engine.GetType(), out info)) { _stopwatch.Start(); - (engine as IHandleEntityViewEngine).Remove(entityView); + (engine as IHandleEntityStructEngine).Remove(ref entityView); _stopwatch.Stop(); info.AddRemoveDuration(_stopwatch.Elapsed.TotalMilliseconds); diff --git a/Svelto.ECS/SingleEntityViewEngine.cs b/Svelto.ECS/SingleEntityViewEngine.cs index ee7acd0..d8bf11a 100644 --- a/Svelto.ECS/SingleEntityViewEngine.cs +++ b/Svelto.ECS/SingleEntityViewEngine.cs @@ -1,20 +1,8 @@ -using Svelto.ECS.Internal; - namespace Svelto.ECS { - public abstract class SingleEntityViewEngine : IHandleEntityViewEngine where T : class, IEntityData + public abstract class SingleEntityViewEngine : IHandleEntityStructEngine where T : IEntityData { - public void Add(IEntityData entityView) - { - Add((T) entityView); - } - - public void Remove(IEntityData entityView) - { - Remove((T) entityView); - } - - protected abstract void Add(T entityView); - protected abstract void Remove(T entityView); + public abstract void Add(ref T entityView); + public abstract void Remove(ref T entityView); } } \ No newline at end of file