From 70344dbe139b07a64682db470430f0e524e574ac Mon Sep 17 00:00:00 2001 From: sebas77 Date: Thu, 17 May 2018 09:11:20 +0100 Subject: [PATCH] working on use just one data structure, still WIP and a lot of work to do --- .../DataStructures/TypeSafeDictionary.cs | 34 ++++-- .../EnginesRoot.GenericEntityFactory.cs | 26 +++-- Svelto.ECS/EnginesRootEntities.cs | 26 ++--- Svelto.ECS/EnginesRootSubmission.cs | 31 ++--- Svelto.ECS/EntityDescriptor.cs | 6 +- Svelto.ECS/EntityFactory.cs | 8 +- Svelto.ECS/EntityViewBuilder.cs | 22 +--- Svelto.ECS/EntityViewStructBuilder.cs | 57 ++++++++++ Svelto.ECS/EntityViewUtility.cs | 8 +- Svelto.ECS/EntityViewsDB.cs | 4 +- .../Unity/GenericEntityDescriptorHolder.cs | 2 +- Svelto.ECS/IEngine.cs | 4 +- Svelto.ECS/IEntityFactory.cs | 30 +++-- Svelto.ECS/IEntityView.cs | 8 +- Svelto.ECS/IEntityViewsDB.cs | 4 +- Svelto.ECS/MixedEntityDescriptor.cs | 107 ++++++++++++++++++ Svelto.ECS/MultiEntityStructsEngine.cs | 43 +++++++ Svelto.ECS/MultiEntityViewsEngine.cs | 27 ++++- Svelto.ECS/Profiler/EngineProfiler.cs | 4 +- Svelto.ECS/SingleEntityViewEngine.cs | 22 +++- 20 files changed, 357 insertions(+), 116 deletions(-) create mode 100644 Svelto.ECS/EntityViewStructBuilder.cs create mode 100644 Svelto.ECS/MixedEntityDescriptor.cs create mode 100644 Svelto.ECS/MultiEntityStructsEngine.cs diff --git a/Svelto.ECS/DataStructures/TypeSafeDictionary.cs b/Svelto.ECS/DataStructures/TypeSafeDictionary.cs index aea0029..7f18c92 100644 --- a/Svelto.ECS/DataStructures/TypeSafeDictionary.cs +++ b/Svelto.ECS/DataStructures/TypeSafeDictionary.cs @@ -23,7 +23,7 @@ namespace Svelto.ECS.Internal ITypeSafeDictionary Create(); int Count { get; } void FillWithIndexedEntityViews(ITypeSafeDictionary entityViews); - void AddEntityViewsToEngines(FasterList enginesForEntityView); + void AddEntityViewsToEngines(Dictionary> entityViewEnginesDB); } class TypeSafeDictionary : FasterDictionary, ITypeSafeDictionary where TValue : IEntityData @@ -54,9 +54,25 @@ namespace Svelto.ECS.Internal } } - public void AddEntityViewsToEngines(FasterList enginesForEntityView) + public void AddEntityViewsToEngines(Dictionary> entityViewEnginesDB) { - throw new NotImplementedException(); + int count; + TValue[] values = GetFasterValuesBuffer(out count); + + for (int i = 0; i < count; i++) + { + TValue entity = values[i]; + + AddEntityViewFromEngines(entityViewEnginesDB, ref entity); + } + } + + void AddEntityViewFromEngines(Dictionary> entityViewEnginesDB, ref TValue entity) + { + FasterList entityViewsEngines; + if (entityViewEnginesDB.TryGetValue(typeof(TValue), out entityViewsEngines)) + for (int i = 0; i < entityViewsEngines.Count; i++) + (entityViewsEngines[i] as IHandleEntityStructEngine).AddInternal(ref entity); } public void RemoveEntityFromDicAndEngines(EGID entityGid, @@ -67,29 +83,29 @@ namespace Svelto.ECS.Internal TValue entity = this[entityGid.GID]; - RemoveEntityViewsFromEngines(entityViewEnginesDB, ref entity); + RemoveEntityViewFromEngines(entityViewEnginesDB, ref entity); Remove(entityGid.GID); } - public void RemoveEntityViewsFromEngines(Dictionary> entityViewEnginesDB, ref TValue entity) + static void RemoveEntityViewFromEngines(Dictionary> entityViewEnginesDB, ref TValue entity) { FasterList entityViewsEngines; if (entityViewEnginesDB.TryGetValue(typeof(TValue), out entityViewsEngines)) - for (int i = 0; i < entityViewEnginesDB.Count; i++) - (entityViewsEngines[i] as IHandleEntityStructEngine).Remove(ref entity); + for (int i = 0; i < entityViewsEngines.Count; i++) + (entityViewsEngines[i] as IHandleEntityStructEngine).RemoveInternal(ref entity); } public void RemoveEntityViewsFromEngines(Dictionary> entityViewEnginesDB) { int count; - TValue[] values = this.GetFasterValuesBuffer(out count); + TValue[] values = GetFasterValuesBuffer(out count); for (int i = 0; i < count; i++) { TValue entity = values[i]; - RemoveEntityViewsFromEngines(entityViewEnginesDB, ref entity); + RemoveEntityViewFromEngines(entityViewEnginesDB, ref entity); } } diff --git a/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs b/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs index df55316..653cb8f 100644 --- a/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs +++ b/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs @@ -22,23 +22,33 @@ namespace Svelto.ECS _weakEngine.Target.BuildEntity(new EGID(entityID), implementors); } - public void BuildEntity(int entityID, EntityDescriptorInfo entityDescriptor, object[] implementors = null) + public void BuildEntity(int entityID, int groupID, object[] implementors) where T : IEntityDescriptor, new() { - _weakEngine.Target.BuildEntity(new EGID(entityID), entityDescriptor, implementors); + _weakEngine.Target.BuildEntity(new EGID(entityID, groupID), implementors); } - public void BuildEntity(int entityID, int groupID, object[] implementors) - where T : IEntityDescriptor, new() + public void BuildEntity(EGID egid, object[] implementors) where T : IEntityDescriptor, new() { - _weakEngine.Target.BuildEntity(new EGID(entityID, groupID), implementors); + _weakEngine.Target.BuildEntity(egid, implementors); + } + + + public void BuildEntity(int entityID, EntityDescriptorInfo entityDescriptorInfo, object[] implementors) + { + _weakEngine.Target.BuildEntity(new EGID(entityID), entityDescriptorInfo, implementors); } - public void BuildEntity(int entityID, int groupID, EntityDescriptorInfo entityDescriptor, - object[] implementors) + public void BuildEntity(EGID egid, EntityDescriptorInfo entityDescriptorInfo, object[] implementors) { - _weakEngine.Target.BuildEntity(new EGID(entityID, groupID), entityDescriptor, implementors); + _weakEngine.Target.BuildEntity(egid, entityDescriptorInfo, implementors); } + public void BuildEntity(int entityID, int groupID, EntityDescriptorInfo entityDescriptorInfo, object[] implementors) + { + _weakEngine.Target.BuildEntity(new EGID(entityID, groupID), entityDescriptorInfo, implementors); + } + + public void PreallocateEntitySpace(int size) where T : IEntityDescriptor, new() { _weakEngine.Target.Preallocate(ExclusiveGroups.StandardEntity, size); diff --git a/Svelto.ECS/EnginesRootEntities.cs b/Svelto.ECS/EnginesRootEntities.cs index de3348e..0c90b61 100644 --- a/Svelto.ECS/EnginesRootEntities.cs +++ b/Svelto.ECS/EnginesRootEntities.cs @@ -11,6 +11,11 @@ namespace Svelto.ECS { public partial class EnginesRoot : IDisposable { + /// + /// Dispose an EngineRoot once not used anymore, so that all the + /// engines are notified with the entities removed. + /// It's a clean up process. + /// public void Dispose() { foreach (var groups in _groupEntityViewsDB) @@ -32,29 +37,22 @@ namespace Svelto.ECS ///-------------------------------------------- - /// - /// 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 - /// added later in the engines. - /// - /// - /// - /// - void BuildEntity(EGID entityID, object[] implementors = null) + + void BuildEntity(EGID entityID, object[] implementors) where T : IEntityDescriptor, new() { EntityFactory.BuildGroupedEntityViews(entityID, _groupedEntityViewsToAdd.current, - EntityDescriptorTemplate.Default, + EntityDescriptorTemplate.Info, implementors); } - void BuildEntity(EGID entityID, EntityDescriptorInfo entityDescriptor, - object[] implementors = null) + void BuildEntity(EGID entityID, EntityDescriptorInfo entityDescriptorInfo, + object[] implementors) { EntityFactory.BuildGroupedEntityViews(entityID, _groupedEntityViewsToAdd.current, - entityDescriptor, + entityDescriptorInfo, implementors); } @@ -68,7 +66,7 @@ namespace Svelto.ECS /// void Preallocate(int groupID, int size) where T : IEntityDescriptor, new() { - var entityViewsToBuild = EntityDescriptorTemplate.Default.entityViewsToBuild; + var entityViewsToBuild = EntityDescriptorTemplate.Info.entityViewsToBuild; var count = entityViewsToBuild.Length; for (var index = 0; index < count; index++) diff --git a/Svelto.ECS/EnginesRootSubmission.cs b/Svelto.ECS/EnginesRootSubmission.cs index 04d1987..f98dd21 100644 --- a/Svelto.ECS/EnginesRootSubmission.cs +++ b/Svelto.ECS/EnginesRootSubmission.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Svelto.DataStructures; using Svelto.ECS.Internal; using Svelto.ECS.Schedulers; @@ -39,22 +38,23 @@ namespace Svelto.ECS numberOfReenteringLoops++; } } - //todo: can I make the entity creation less complicated? - void AddEntityViewsToTheDBAndSuitableEngines(Dictionary> groupsToSubmit) + + //todo: groupsToSubmit can be semplified as data structure? + void AddEntityViewsToTheDBAndSuitableEngines(ITypeSafeDictionary> groupsOfEntitiesToSubmit) { //for each groups there is a dictionary of built lists of EntityView grouped by type - foreach (var groupToSubmit in groupsToSubmit) + foreach (var groupOfEntitiesToSubmit in groupsOfEntitiesToSubmit) { Dictionary groupDB; - int groupID = groupToSubmit.Key; + int groupID = groupOfEntitiesToSubmit.Key; - //if the group doesn't exist in the current DB let's create it frst + //if the group doesn't exist in the current DB let's create it first if (_groupEntityViewsDB.TryGetValue(groupID, out groupDB) == false) groupDB = _groupEntityViewsDB[groupID] = new Dictionary(); - foreach (var entityViewList in groupToSubmit.Value) + //add the entity View in the group + foreach (var entityViewList in groupOfEntitiesToSubmit.Value) { - //add the entity View in the group ITypeSafeDictionary dbList; if (groupDB.TryGetValue(entityViewList.Key, out dbList) == false) dbList = groupDB[entityViewList.Key] = entityViewList.Value.Create(); @@ -65,7 +65,7 @@ namespace Svelto.ECS //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 groupToSubmit in groupsOfEntitiesToSubmit) { foreach (var entityViewsPerType in groupToSubmit.Value) { @@ -73,21 +73,10 @@ namespace Svelto.ECS for (var current = type; current != _entityViewType && current != _objectType && current != _valueType; current = current.BaseType) - AddEntityViewsToTheSuitableEngines(_entityViewEngines, entityViewsPerType.Value, - current); + entityViewsPerType.Value.AddEntityViewsToEngines(_entityViewEngines); } } } - - static void AddEntityViewsToTheSuitableEngines( Dictionary> entityViewEngines, - ITypeSafeDictionary entityViewsList, - Type entityViewType) - { - FasterList enginesForEntityView; - - if (entityViewEngines.TryGetValue(entityViewType, out enginesForEntityView)) - entityViewsList.AddEntityViewsToEngines(enginesForEntityView); - } readonly DoubleBufferedEntityViews>> _groupedEntityViewsToAdd; readonly EntitySubmissionScheduler _scheduler; diff --git a/Svelto.ECS/EntityDescriptor.cs b/Svelto.ECS/EntityDescriptor.cs index e75b01b..7ccd7b1 100644 --- a/Svelto.ECS/EntityDescriptor.cs +++ b/Svelto.ECS/EntityDescriptor.cs @@ -21,7 +21,7 @@ namespace Svelto.ECS public static class EntityDescriptorTemplate where TType : IEntityDescriptor, new() { - public static readonly EntityDescriptorInfo Default = new EntityDescriptorInfo(new TType()); + public static readonly EntityDescriptorInfo Info = new EntityDescriptorInfo(new TType()); } public class DynamicEntityDescriptorInfo : EntityDescriptorInfo where TType : IEntityDescriptor, new() @@ -31,7 +31,7 @@ namespace Svelto.ECS Check.Require(extraEntityViews.Count > 0, "don't use a DynamicEntityDescriptorInfo if you don't need to use extra EntityViews"); - var defaultEntityViewsToBuild = EntityDescriptorTemplate.Default.entityViewsToBuild; + var defaultEntityViewsToBuild = EntityDescriptorTemplate.Info.entityViewsToBuild; var length = defaultEntityViewsToBuild.Length; entityViewsToBuild = new IEntityViewBuilder[length + extraEntityViews.Count]; @@ -39,7 +39,7 @@ namespace Svelto.ECS Array.Copy(defaultEntityViewsToBuild, 0, entityViewsToBuild, 0, length); Array.Copy(extraEntityViews.ToArrayFast(), 0, entityViewsToBuild, length, extraEntityViews.Count); - name = EntityDescriptorTemplate.Default.name; + name = EntityDescriptorTemplate.Info.name; } } diff --git a/Svelto.ECS/EntityFactory.cs b/Svelto.ECS/EntityFactory.cs index 2750b09..df5cc70 100644 --- a/Svelto.ECS/EntityFactory.cs +++ b/Svelto.ECS/EntityFactory.cs @@ -10,12 +10,12 @@ namespace Svelto.ECS.Internal EntityDescriptorInfo entityViewsToBuildDescriptor, object[] implementors) { - var @group = FetchGroup(egid.groupID, groupEntityViewsByType); + var @group = FetchEntityViewGroup(egid.groupID, groupEntityViewsByType); BuildEntityViewsAndAddToGroup(egid, group, entityViewsToBuildDescriptor, implementors); } - static Dictionary FetchGroup(int groupID, Dictionary> groupEntityViewsByType) + static Dictionary FetchEntityViewGroup(int groupID, Dictionary> groupEntityViewsByType) { Dictionary group; @@ -44,7 +44,7 @@ namespace Svelto.ECS.Internal BuildEntityView(entityID, entityViewsByType, entityViewType, entityViewBuilder, implementors); } - _viewBuilder._initializer = new EntityInfoView() {entityViewsToBuild = entityViewsToBuild}; + _viewBuilder._initializer = new EntityInfoView {entityViewsToBuild = entityViewsToBuild}; BuildEntityView(entityID, entityViewsByType, _viewType, _viewBuilder, null); } @@ -65,7 +65,7 @@ namespace Svelto.ECS.Internal entityViewsByType.Add(entityViewType, safeDictionary); } - static readonly EntityViewBuilder _viewBuilder = new EntityViewBuilder(); + static readonly EntityViewStructBuilder _viewBuilder = new EntityViewStructBuilder(); 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 2050b56..6c67709 100644 --- a/Svelto.ECS/EntityViewBuilder.cs +++ b/Svelto.ECS/EntityViewBuilder.cs @@ -8,14 +8,6 @@ namespace Svelto.ECS { public class EntityViewBuilder : IEntityViewBuilder where EntityViewType : IEntityData, new() { - public EntityViewBuilder(ref EntityViewType initializer) - { - _initializer = initializer; - } - - public EntityViewBuilder() - {} - public void BuildEntityViewAndAddToList(ref ITypeSafeDictionary list, EGID entityID, object[] implementors) { if (list == null) @@ -23,7 +15,7 @@ namespace Svelto.ECS var castedList = list as TypeSafeDictionary; - if (implementors != null) + DBC.Check.Require(implementors != null, "Implementors not found while building an EntityView"); { EntityViewType lentityView; @@ -36,14 +28,6 @@ namespace Svelto.ECS 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 ITypeSafeDictionary Preallocate(ref ITypeSafeDictionary list, int size) @@ -70,13 +54,11 @@ namespace Svelto.ECS fromCastedList.Remove(entityID.GID); } - FasterList>> entityViewBlazingFastReflection + FasterList>> entityViewBlazingFastReflection { 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 new file mode 100644 index 0000000..e3f0c38 --- /dev/null +++ b/Svelto.ECS/EntityViewStructBuilder.cs @@ -0,0 +1,57 @@ +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 EntityViewStructBuilder() + { + _initializer = default(EntityViewType); + } + + public void BuildEntityViewAndAddToList(ref ITypeSafeDictionary list, EGID entityID, object[] implementors = null) + { + _initializer.ID = entityID; + + if (list == null) + list = new TypeSafeDictionary(); + + var castedList = list as TypeSafeDictionary; + + castedList.Add(entityID.GID, _initializer); + } + + public ITypeSafeDictionary Preallocate(ref ITypeSafeDictionary list, int size) + { + if (list == null) + list = new TypeSafeDictionary(size); + else + list.AddCapacity(size); + + return list; + } + + public Type GetEntityViewType() + { + return ENTITY_VIEW_TYPE; + } + + public void MoveEntityView(EGID entityID, ITypeSafeDictionary fromSafeList, ITypeSafeDictionary toSafeList) + { + var fromCastedList = fromSafeList as TypeSafeDictionary; + var toCastedList = toSafeList as TypeSafeDictionary; + + toCastedList.Add(entityID.GID, fromCastedList[entityID.GID]); + fromCastedList.Remove(entityID.GID); + } + + static readonly Type ENTITY_VIEW_TYPE = typeof(EntityViewType); + internal EntityViewType _initializer; + } +} \ No newline at end of file diff --git a/Svelto.ECS/EntityViewUtility.cs b/Svelto.ECS/EntityViewUtility.cs index 2b804cb..a2d789c 100644 --- a/Svelto.ECS/EntityViewUtility.cs +++ b/Svelto.ECS/EntityViewUtility.cs @@ -9,7 +9,7 @@ static class EntityViewUtility { public static void FillEntityView(this IEntityViewBuilder entityViewBuilder , ref T entityView - , FasterList>> entityViewBlazingFastReflection + , FasterList>> entityViewBlazingFastReflection , object[] implementors , string entityDescriptorName) { @@ -17,7 +17,7 @@ static class EntityViewUtility //Very efficent way to collect the fields of every EntityViewType var setters = - FasterList>> + FasterList>> .NoVirt.ToArrayFast(entityViewBlazingFastReflection, out count); #if DEBUG && !PROFILER if (count == 0) @@ -87,9 +87,9 @@ static class EntityViewUtility entityViewBuilder.GetEntityViewType().Name + " - EntityDescriptor " + entityDescriptorName); #endif #if DEBUG && !PROFILER - fieldSetter.Value.Call(ref entityView, component.implementorType); + fieldSetter.Value(ref entityView, component.implementorType); #else - fieldSetter.Value.Call(ref entityView, component); + fieldSetter.Value(ref entityView, component); #endif } diff --git a/Svelto.ECS/EntityViewsDB.cs b/Svelto.ECS/EntityViewsDB.cs index 0e8d74d..02d5b8f 100644 --- a/Svelto.ECS/EntityViewsDB.cs +++ b/Svelto.ECS/EntityViewsDB.cs @@ -30,12 +30,12 @@ namespace Svelto.ECS.Internal return (outList as TypeSafeDictionary).FasterValues; } - public T[] QueryEntityViewsCacheFriendly(out int count) where T : IEntityData + public T[] QueryEntityViewsCacheFriendly(out int count) where T : struct, IEntityData { return QueryEntityViewsCacheFriendly(ExclusiveGroups.StandardEntity, out count); } - public T[] QueryEntityViewsCacheFriendly(int @group, out int count) where T : IEntityData + public T[] QueryEntityViewsCacheFriendly(int @group, out int count) where T : struct, IEntityData { var type = typeof(T); count = 0; diff --git a/Svelto.ECS/Extensions/Unity/GenericEntityDescriptorHolder.cs b/Svelto.ECS/Extensions/Unity/GenericEntityDescriptorHolder.cs index ebb4fcc..db7e9f7 100644 --- a/Svelto.ECS/Extensions/Unity/GenericEntityDescriptorHolder.cs +++ b/Svelto.ECS/Extensions/Unity/GenericEntityDescriptorHolder.cs @@ -7,7 +7,7 @@ namespace Svelto.ECS { public EntityDescriptorInfo RetrieveDescriptor() { - return EntityDescriptorTemplate.Default; + return EntityDescriptorTemplate.Info; } } } diff --git a/Svelto.ECS/IEngine.cs b/Svelto.ECS/IEngine.cs index 0657775..2a3cb00 100644 --- a/Svelto.ECS/IEngine.cs +++ b/Svelto.ECS/IEngine.cs @@ -13,7 +13,7 @@ namespace Svelto.ECS public interface IHandleEntityStructEngine : IHandleEntityViewEngineAbstracted { - void Add(ref T entityView); - void Remove(ref T entityView); + void AddInternal(ref T entityView); + void RemoveInternal(ref T entityView); } } \ No newline at end of file diff --git a/Svelto.ECS/IEntityFactory.cs b/Svelto.ECS/IEntityFactory.cs index 34a076c..dbdcc7d 100644 --- a/Svelto.ECS/IEntityFactory.cs +++ b/Svelto.ECS/IEntityFactory.cs @@ -18,6 +18,18 @@ namespace Svelto.ECS /// void PreallocateEntitySpace(int size) where T : IEntityDescriptor, new(); void PreallocateEntitySpace(int groupID, int size) where T : IEntityDescriptor, new(); + + /// + /// The EntityDescriptor doesn't need to be ever instantiated. It just describes the Entity + /// itself in terms of EntityViews to build. The Implementors are passed to fill the + /// references of the EntityViews components. Please read the articles on my blog + /// to understand better the terminologies + /// + /// + /// + /// + void BuildEntity(int entityID, object[] implementors) where T:IEntityDescriptor, new(); + /// /// Using this function is like building a normal entity, but the entityViews @@ -30,18 +42,9 @@ namespace Svelto.ECS /// /// void BuildEntity(int entityID, int groupID, object[] implementors) where T:IEntityDescriptor, new(); - void BuildEntity(int entityID, int groupID, EntityDescriptorInfo entityDescriptor, object[] implementors); - - /// - /// The EntityDescriptor doesn't need to be ever instantiated. It just describes the Entity - /// itself in terms of EntityViews to build. The Implementors are passed to fill the - /// references of the EntityViews components. Please read the articles on my blog - /// to understand better the terminologies - /// - /// - /// - /// - void BuildEntity(int entityID, object[] implementors) where T:IEntityDescriptor, new(); + + void BuildEntity(EGID egid, object[] implementors) where T:IEntityDescriptor, new(); + /// /// When the type of the entity is not known (this is a special case!) an EntityDescriptorInfo @@ -50,6 +53,9 @@ namespace Svelto.ECS /// /// /// + /// + void BuildEntity(int entityID, int groupID, EntityDescriptorInfo entityDescriptor, object[] implementors); void BuildEntity(int entityID, EntityDescriptorInfo entityDescriptorInfo, object[] implementors); + void BuildEntity(EGID egid, EntityDescriptorInfo entityDescriptorInfo, object[] implementors); } } diff --git a/Svelto.ECS/IEntityView.cs b/Svelto.ECS/IEntityView.cs index 81e632b..f40c20b 100644 --- a/Svelto.ECS/IEntityView.cs +++ b/Svelto.ECS/IEntityView.cs @@ -36,7 +36,7 @@ namespace Svelto.ECS { if (FieldCache.list == null) { - FieldCache.list = new FasterList>>(); + FieldCache.list = new FasterList>>(); var type = typeof(T); @@ -47,9 +47,9 @@ namespace Svelto.ECS { var field = fields[i]; - CastedAction setter = FastInvoke.MakeSetter(field); + ActionRef setter = FastInvoke.MakeSetter(field); - FieldCache.list.Add(new KeyValuePair>(field.FieldType, setter)); + FieldCache.list.Add(new KeyValuePair>(field.FieldType, setter)); } } @@ -58,7 +58,7 @@ namespace Svelto.ECS public static class FieldCache { - public static FasterList>> list; + public static FasterList>> list; } } } diff --git a/Svelto.ECS/IEntityViewsDB.cs b/Svelto.ECS/IEntityViewsDB.cs index 3611bfc..208756f 100644 --- a/Svelto.ECS/IEntityViewsDB.cs +++ b/Svelto.ECS/IEntityViewsDB.cs @@ -7,8 +7,8 @@ namespace Svelto.ECS ReadOnlyCollectionStruct QueryEntityViews() where T : IEntityData; ReadOnlyCollectionStruct QueryEntityViews(int group) where T : IEntityData; - T[] QueryEntityViewsCacheFriendly(out int count) where T : IEntityData; - T[] QueryEntityViewsCacheFriendly(int group, out int count) where T : IEntityData; + T[] QueryEntityViewsCacheFriendly(out int count) where T : struct, IEntityData; + T[] QueryEntityViewsCacheFriendly(int group, out int count) where T : struct, IEntityData; bool TryQueryEntityView(EGID ID, out T entityView) where T : IEntityData; T QueryEntityView(EGID entityGID) where T : class, IEntityData; diff --git a/Svelto.ECS/MixedEntityDescriptor.cs b/Svelto.ECS/MixedEntityDescriptor.cs new file mode 100644 index 0000000..3a27826 --- /dev/null +++ b/Svelto.ECS/MixedEntityDescriptor.cs @@ -0,0 +1,107 @@ +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/MultiEntityStructsEngine.cs b/Svelto.ECS/MultiEntityStructsEngine.cs new file mode 100644 index 0000000..2e501d4 --- /dev/null +++ b/Svelto.ECS/MultiEntityStructsEngine.cs @@ -0,0 +1,43 @@ +namespace Svelto.ECS +{ + public abstract class MultiEntityStructsEngine : SingleEntityViewEngine, IHandleEntityStructEngine + where U : IEntityData where T : IEntityData + { + public void AddInternal(ref U entityView) + { Add(ref entityView); } + public void RemoveInternal(ref U entityView) + { Remove(ref entityView); } + + protected abstract void Add(ref U entityView); + protected abstract void Remove(ref U entityView); + } + + public abstract class MultiEntityStructsEngine : MultiEntityViewsEngine, IHandleEntityStructEngine + where V : IEntityData where U : IEntityData where T : IEntityData + { + public void AddInternal(ref V entityView) + { Add(ref entityView); } + public void RemoveInternal(ref V entityView) + { Remove(ref entityView); } + + protected abstract void Add(ref V entityView); + protected abstract void Remove(ref V entityView); + } + + /// + /// Please do not add more MultiEntityViewsEngine + /// if you use more than 4 nodes, your engine has + /// already too many responsabilities. + /// + public abstract class MultiEntityStructsEngine : MultiEntityViewsEngine, IHandleEntityStructEngine + where W : IEntityData where V : IEntityData where U : IEntityData where T : IEntityData + { + public void AddInternal(ref W entityView) + { Add(ref entityView); } + public void RemoveInternal(ref W entityView) + { Remove(ref entityView); } + + protected abstract void Add(ref W entityView); + protected abstract void Remove(ref W entityView); + } +} \ No newline at end of file diff --git a/Svelto.ECS/MultiEntityViewsEngine.cs b/Svelto.ECS/MultiEntityViewsEngine.cs index 93bf157..beaf78f 100644 --- a/Svelto.ECS/MultiEntityViewsEngine.cs +++ b/Svelto.ECS/MultiEntityViewsEngine.cs @@ -3,15 +3,25 @@ namespace Svelto.ECS public abstract class MultiEntityViewsEngine : SingleEntityViewEngine, IHandleEntityStructEngine where U : IEntityData where T : IEntityData { - public abstract void Add(ref U entityView); - public abstract void Remove(ref U entityView); + public void AddInternal(ref U entityView) + { Add(entityView); } + public void RemoveInternal(ref U entityView) + { Remove(entityView); } + + protected abstract void Add(U entityView); + protected abstract void Remove(U entityView); } public abstract class MultiEntityViewsEngine : MultiEntityViewsEngine, IHandleEntityStructEngine where V : IEntityData where U : IEntityData where T : IEntityData { - public abstract void Add(ref V entityView); - public abstract void Remove(ref V entityView); + public void AddInternal(ref V entityView) + { Add(entityView); } + public void RemoveInternal(ref V entityView) + { Remove(entityView); } + + protected abstract void Add(V entityView); + protected abstract void Remove(V entityView); } /// @@ -22,7 +32,12 @@ namespace Svelto.ECS public abstract class MultiEntityViewsEngine : MultiEntityViewsEngine, IHandleEntityStructEngine where W : IEntityData where V : IEntityData where U : IEntityData where T : IEntityData { - public abstract void Add(ref W entityView); - public abstract void Remove(ref W entityView); + public void AddInternal(ref W entityView) + { Add(entityView); } + public void RemoveInternal(ref W entityView) + { Remove(entityView); } + + protected abstract void Add(W entityView); + protected abstract void Remove(W entityView); } } \ No newline at end of file diff --git a/Svelto.ECS/Profiler/EngineProfiler.cs b/Svelto.ECS/Profiler/EngineProfiler.cs index 2aeb967..6e7f18b 100644 --- a/Svelto.ECS/Profiler/EngineProfiler.cs +++ b/Svelto.ECS/Profiler/EngineProfiler.cs @@ -18,7 +18,7 @@ namespace Svelto.ECS.Profiler if (engineInfos.TryGetValue(engine.GetType(), out info)) { _stopwatch.Start(); - (engine as IHandleEntityStructEngine).Add(ref entityView); + (engine as IHandleEntityStructEngine).AddInternal(ref entityView); _stopwatch.Stop(); info.AddAddDuration(_stopwatch.Elapsed.TotalMilliseconds); _stopwatch.Reset(); @@ -31,7 +31,7 @@ namespace Svelto.ECS.Profiler if (engineInfos.TryGetValue(engine.GetType(), out info)) { _stopwatch.Start(); - (engine as IHandleEntityStructEngine).Remove(ref entityView); + (engine as IHandleEntityStructEngine).RemoveInternal(ref entityView); _stopwatch.Stop(); info.AddRemoveDuration(_stopwatch.Elapsed.TotalMilliseconds); diff --git a/Svelto.ECS/SingleEntityViewEngine.cs b/Svelto.ECS/SingleEntityViewEngine.cs index d8bf11a..f59eb26 100644 --- a/Svelto.ECS/SingleEntityViewEngine.cs +++ b/Svelto.ECS/SingleEntityViewEngine.cs @@ -2,7 +2,25 @@ namespace Svelto.ECS { public abstract class SingleEntityViewEngine : IHandleEntityStructEngine where T : IEntityData { - public abstract void Add(ref T entityView); - public abstract void Remove(ref T entityView); + public void AddInternal(ref T entityView) + { Add(entityView); } + + public void RemoveInternal(ref T entityView) + { Remove(entityView); } + + protected abstract void Add(T entityView); + protected abstract void Remove(T entityView); + } + + public abstract class SingleEntityStructEngine : IHandleEntityStructEngine where T : IEntityData + { + public void AddInternal(ref T entityView) + { Add(ref entityView); } + + public void RemoveInternal(ref T entityView) + { Remove(ref entityView); } + + protected abstract void Add(ref T entityView); + protected abstract void Remove(ref T entityView); } } \ No newline at end of file