From a65a36fcab07ab61ac1af055540dbebe3ba29e39 Mon Sep 17 00:00:00 2001 From: sebas77 Date: Thu, 29 Mar 2018 15:57:47 +0100 Subject: [PATCH] Entity Struct Add callback rework --- .../TypeSafeFasterListForECS.cs | 53 +++++++++++++--- Svelto.ECS/EnginesRootEngines.cs | 14 +++-- Svelto.ECS/EnginesRootEntities.cs | 22 ++++--- Svelto.ECS/EnginesRootSubmission.cs | 30 ++-------- .../Unity/GenericEntityDescriptorHolder.cs | 2 +- .../UnitySumbmissionEntityViewScheduler .cs | 4 +- Svelto.ECS/IEngine.cs | 12 +++- Svelto.ECS/IEntityDescriptorHolder.cs | 2 +- Svelto.ECS/MultiEntityViewsEngine.cs | 60 ++++++++----------- Svelto.ECS/Profiler/EngineProfiler.cs | 21 ++++--- Svelto.ECS/SingleEntityViewEngine.cs | 4 +- 11 files changed, 129 insertions(+), 95 deletions(-) diff --git a/Svelto.ECS/DataStructures/TypeSafeFasterListForECS.cs b/Svelto.ECS/DataStructures/TypeSafeFasterListForECS.cs index 0fc8437..c61e352 100644 --- a/Svelto.ECS/DataStructures/TypeSafeFasterListForECS.cs +++ b/Svelto.ECS/DataStructures/TypeSafeFasterListForECS.cs @@ -16,12 +16,12 @@ namespace Svelto.ECS.Internal ITypeSafeDictionary CreateIndexedDictionary(); IEntityView[] ToArrayFast(out int count); void ReserveCapacity(int capacity); + + void Fill(FasterList enginesForEntityView); } class TypeSafeFasterListForECS : FasterList where T : IEntityView { - readonly Dictionary _mappedIndices; - protected TypeSafeFasterListForECS() { _mappedIndices = new Dictionary(); @@ -76,10 +76,11 @@ namespace Svelto.ECS.Internal { return _mappedIndices[entityID]; } + + readonly Dictionary _mappedIndices; } - class TypeSafeFasterListForECSForStructs : TypeSafeFasterListForECS, ITypeSafeList - where T : struct, IEntityStruct + class TypeSafeFasterListForECSForStructs : TypeSafeFasterListForECS, ITypeSafeList where T:struct, IEntityView { public TypeSafeFasterListForECSForStructs(int size) : base(size) { @@ -101,12 +102,30 @@ namespace Svelto.ECS.Internal public ITypeSafeDictionary CreateIndexedDictionary() { - throw new Exception("Not Allowed"); + throw new NotImplementedException(); } public IEntityView[] ToArrayFast(out int count) { - throw new Exception("Not Allowed"); + 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) @@ -114,8 +133,8 @@ namespace Svelto.ECS.Internal return new TypeSafeFasterListForECSForStructs(size); } } - - class TypeSafeFasterListForECSForClasses : TypeSafeFasterListForECS, ITypeSafeList where T : EntityView, new() + + class TypeSafeFasterListForECSForClasses : TypeSafeFasterListForECS, ITypeSafeList where T:class, IEntityView, new() { public TypeSafeFasterListForECSForClasses(int size) : base(size) { @@ -147,6 +166,24 @@ namespace Svelto.ECS.Internal return ToArrayFast(); } + 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); diff --git a/Svelto.ECS/EnginesRootEngines.cs b/Svelto.ECS/EnginesRootEngines.cs index 249e82f..8f855d7 100644 --- a/Svelto.ECS/EnginesRootEngines.cs +++ b/Svelto.ECS/EnginesRootEngines.cs @@ -35,7 +35,7 @@ namespace Svelto.ECS /// public EnginesRoot(EntitySubmissionScheduler entityViewScheduler) { - _entityViewEngines = new Dictionary>(); + _entityViewEngines = new Dictionary>(); _otherEngines = new FasterList(); _entityViewsDB = new Dictionary(); @@ -59,7 +59,7 @@ namespace Svelto.ECS #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR Profiler.EngineProfiler.AddEngine(engine); #endif - var viewEngine = engine as IHandleEntityViewEngine; + var viewEngine = engine as IHandleEntityViewEngineAbstracted; if (viewEngine != null) CheckEntityViewsEngine(viewEngine); @@ -78,12 +78,13 @@ namespace Svelto.ECS { var baseType = engine.GetType().GetBaseType(); - while (baseType != _object) + while (baseType != _objectType) { if (baseType.IsGenericTypeEx()) { var genericArguments = baseType.GetGenericArgumentsEx(); - AddEngine(engine as IHandleEntityViewEngine, genericArguments, _entityViewEngines); + + AddEngine(engine as IHandleEntityViewEngineAbstracted, genericArguments, _entityViewEngines); return; } @@ -120,11 +121,12 @@ namespace Svelto.ECS list.Add(engine); } - readonly Dictionary> _entityViewEngines; + readonly Dictionary> _entityViewEngines; readonly FasterList _otherEngines; static readonly Type _entityViewType= typeof(EntityView); - static readonly Type _object = typeof(object); + static readonly Type _objectType = typeof(object); + static readonly Type _valueType = typeof(ValueType); class DoubleBufferedEntityViews where T : class, IDictionary, new() { diff --git a/Svelto.ECS/EnginesRootEntities.cs b/Svelto.ECS/EnginesRootEntities.cs index 0b11704..c982835 100644 --- a/Svelto.ECS/EnginesRootEntities.cs +++ b/Svelto.ECS/EnginesRootEntities.cs @@ -15,7 +15,7 @@ namespace Svelto.ECS public void Dispose() { foreach (var entity in _entityViewsDB) - if (entity.Value.isQueryiableEntityView) + if (entity.Value.isQueryiableEntityView == true) foreach (var entityView in entity.Value) RemoveEntityViewFromEngines(_entityViewEngines, entityView as EntityView, entity.Key); @@ -204,6 +204,11 @@ namespace Svelto.ECS Type entityViewType, int entityID) { +#if DEBUG && !PROFILE + if (entityViewsDB.ContainsKey(entityViewType) == false) + throw new Exception(NO_ENTITY_FOUND_EXCEPTION + " - EntityViewType: " + + entityViewType.Name + " - ID " + entityID); +#endif var entityViews = entityViewsDB[entityViewType]; if (entityViews.MappedRemove(entityID) == false) entityViewsDB.Remove(entityViewType); @@ -300,23 +305,23 @@ namespace Svelto.ECS } } - static void RemoveEntityViewFromEngines(Dictionary> entityViewEngines, - IEntityView entityView, - Type entityViewType) + static void RemoveEntityViewFromEngines(Dictionary> entityViewEngines, + IEntityView entityView, Type entityViewType) { - FasterList enginesForEntityView; + FasterList enginesForEntityView; if (entityViewEngines.TryGetValue(entityViewType, out enginesForEntityView)) { int count; - var fastList = FasterList.NoVirt.ToArrayFast(enginesForEntityView, out 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 - fastList[j].Remove(entityView); + var handleMixedEntityViewEngine = (fastList[j] as IHandleEntityViewEngine); + handleMixedEntityViewEngine.Remove(entityView); #endif } } @@ -401,6 +406,9 @@ namespace Svelto.ECS readonly Dictionary _entityViewsDBDic; readonly Dictionary> _groupEntityViewsDB; readonly Dictionary _metaEntityViewsDB; + const string NO_ENTITY_FOUND_EXCEPTION = + "Svelto.ECS Trying to remove an Entity never added, please be sure the " + + "Entity is submitted before trying to remove it"; readonly Dictionary _metaEntityViewsDBDic; } diff --git a/Svelto.ECS/EnginesRootSubmission.cs b/Svelto.ECS/EnginesRootSubmission.cs index 37d9299..7eeb83c 100644 --- a/Svelto.ECS/EnginesRootSubmission.cs +++ b/Svelto.ECS/EnginesRootSubmission.cs @@ -71,13 +71,10 @@ namespace Svelto.ECS foreach (var entityViewList in entityViewsToAdd) { - if (entityViewList.Value.isQueryiableEntityView) - { var type = entityViewList.Key; - for (var current = type; current != _entityViewType; current = current.BaseType) + for (var current = type; current != _entityViewType && current != _objectType && current != _valueType; current = current.BaseType) AddEntityViewToTheSuitableEngines(_entityViewEngines, entityViewList.Value, current); - } } } @@ -129,30 +126,15 @@ namespace Svelto.ECS entityViewsDic.FillWithIndexedEntityViews(entityViews); } - static void AddEntityViewToTheSuitableEngines(Dictionary> entityViewEngines, ITypeSafeList entityViewsList, Type entityViewType) + static void AddEntityViewToTheSuitableEngines(Dictionary> entityViewEngines, + ITypeSafeList entityViewsList, + Type entityViewType) { - FasterList enginesForEntityView; + FasterList enginesForEntityView; if (entityViewEngines.TryGetValue(entityViewType, out enginesForEntityView)) { - int viewsCount; - - var entityViews = entityViewsList.ToArrayFast(out viewsCount); - - for (int i = 0; i < viewsCount; i++) - { - int count; - var fastList = FasterList.NoVirt.ToArrayFast(enginesForEntityView, out count); - IEntityView entityView = entityViews[i]; - for (int j = 0; j < count; j++) - { -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR - EngineProfiler.MonitorAddDuration(fastList[j], entityView); -#else - fastList[j].Add(entityView); -#endif - } - } + entityViewsList.Fill(enginesForEntityView); } } diff --git a/Svelto.ECS/Extensions/Unity/GenericEntityDescriptorHolder.cs b/Svelto.ECS/Extensions/Unity/GenericEntityDescriptorHolder.cs index fb672cb..af3fd9c 100644 --- a/Svelto.ECS/Extensions/Unity/GenericEntityDescriptorHolder.cs +++ b/Svelto.ECS/Extensions/Unity/GenericEntityDescriptorHolder.cs @@ -5,7 +5,7 @@ namespace Svelto.ECS UnityEngine.MonoBehaviour , IEntityDescriptorHolder where T: class, IEntityDescriptor, new() { - public IEntityDescriptorInfo RetrieveDescriptor() + public IEntityDescriptorInfo RetrieveDescriptorInfo() { return EntityDescriptorTemplate.Default; } diff --git a/Svelto.ECS/Extensions/Unity/UnitySumbmissionEntityViewScheduler .cs b/Svelto.ECS/Extensions/Unity/UnitySumbmissionEntityViewScheduler .cs index 4eab8cd..9d66549 100644 --- a/Svelto.ECS/Extensions/Unity/UnitySumbmissionEntityViewScheduler .cs +++ b/Svelto.ECS/Extensions/Unity/UnitySumbmissionEntityViewScheduler .cs @@ -44,10 +44,10 @@ namespace Svelto.ECS.Schedulers.Unity internal WeakAction OnTick; - WaitForEndOfFrame _wait = new WaitForEndOfFrame(); + readonly WaitForEndOfFrame _wait = new WaitForEndOfFrame(); } - Scheduler _scheduler; + readonly Scheduler _scheduler; } } #endif \ No newline at end of file diff --git a/Svelto.ECS/IEngine.cs b/Svelto.ECS/IEngine.cs index e482ed5..ec8c5dc 100644 --- a/Svelto.ECS/IEngine.cs +++ b/Svelto.ECS/IEngine.cs @@ -1,8 +1,12 @@ +using Svelto.ECS.Internal; + namespace Svelto.ECS.Internal { - public interface IHandleEntityViewEngine : IEngine + public interface IHandleEntityViewEngineAbstracted : IEngine + {} + + public interface IHandleEntityViewEngine : IHandleEntityViewEngineAbstracted { - void Add(IEntityView entityView); void Remove(IEntityView entityView); } } @@ -10,6 +14,10 @@ namespace Svelto.ECS.Internal namespace Svelto.ECS { public interface IEngine + {} + + public interface IHandleEntityStructEngine : IHandleEntityViewEngineAbstracted { + void Add(ref T entityView); } } \ No newline at end of file diff --git a/Svelto.ECS/IEntityDescriptorHolder.cs b/Svelto.ECS/IEntityDescriptorHolder.cs index 1971d25..df33b0e 100644 --- a/Svelto.ECS/IEntityDescriptorHolder.cs +++ b/Svelto.ECS/IEntityDescriptorHolder.cs @@ -2,6 +2,6 @@ namespace Svelto.ECS { public interface IEntityDescriptorHolder { - IEntityDescriptorInfo RetrieveDescriptor(); + IEntityDescriptorInfo RetrieveDescriptorInfo(); } } \ No newline at end of file diff --git a/Svelto.ECS/MultiEntityViewsEngine.cs b/Svelto.ECS/MultiEntityViewsEngine.cs index 3810f10..ccbdc01 100644 --- a/Svelto.ECS/MultiEntityViewsEngine.cs +++ b/Svelto.ECS/MultiEntityViewsEngine.cs @@ -2,11 +2,12 @@ using Svelto.ECS.Internal; namespace Svelto.ECS.Internal { - public abstract class MultiEntityViewsEngine : IHandleEntityViewEngine where T : class, IEntityView + public abstract class MultiEntityViewsEngine:IHandleEntityStructEngine, + IHandleEntityViewEngine where T:IEntityView { - public virtual void Add(IEntityView entityView) + public void Add(ref T entityView) { - Add((T) entityView); + Add(entityView); } public virtual void Remove(IEntityView entityView) @@ -14,27 +15,19 @@ namespace Svelto.ECS.Internal Remove((T) entityView); } - protected abstract void Add(T entityView); + protected abstract void Add(T entityView); protected abstract void Remove(T entityView); } } namespace Svelto.ECS { - public abstract class MultiEntityViewsEngine : MultiEntityViewsEngine - where U : class, IEntityView where T : class, IEntityView + public abstract class MultiEntityViewsEngine : MultiEntityViewsEngine, IHandleEntityStructEngine + where U : IEntityView where T : IEntityView { protected abstract void Add(U entityView); protected abstract void Remove(U entityView); - public override void Add(IEntityView entityView) - { - if (entityView is U) - Add((U) entityView); - else - base.Add(entityView); - } - public override void Remove(IEntityView entityView) { if (entityView is U) @@ -42,22 +35,19 @@ namespace Svelto.ECS else base.Remove(entityView); } + + public void Add(ref U entityView) + { + Add(entityView); + } } - public abstract class MultiEntityViewsEngine : MultiEntityViewsEngine - where V : class, IEntityView where U : class, IEntityView where T : class, IEntityView + public abstract class MultiEntityViewsEngine : MultiEntityViewsEngine, IHandleEntityStructEngine + where V : IEntityView where U : IEntityView where T : IEntityView { protected abstract void Add(V entityView); protected abstract void Remove(V entityView); - public override void Add(IEntityView entityView) - { - if (entityView is V) - Add((V) entityView); - else - base.Add(entityView); - } - public override void Remove(IEntityView entityView) { if (entityView is V) @@ -65,6 +55,11 @@ namespace Svelto.ECS else base.Remove(entityView); } + + public void Add(ref V entityView) + { + Add(entityView); + } } /// @@ -72,20 +67,12 @@ namespace Svelto.ECS /// if you use more than 4 nodes, your engine has /// already too many responsabilities. /// - public abstract class MultiEntityViewsEngine : MultiEntityViewsEngine - where W : class, IEntityView where V : class, IEntityView where U : class, IEntityView where T : class, IEntityView + public abstract class MultiEntityViewsEngine : MultiEntityViewsEngine, IHandleEntityStructEngine + where W : IEntityView where V : IEntityView where U : IEntityView where T : IEntityView { protected abstract void Add(W entityView); protected abstract void Remove(W entityView); - public override void Add(IEntityView entityView) - { - if (entityView is W) - Add((W) entityView); - else - base.Add(entityView); - } - public override void Remove(IEntityView entityView) { if (entityView is W) @@ -93,5 +80,10 @@ namespace Svelto.ECS else base.Remove(entityView); } + + public void Add(ref W entityView) + { + Add(entityView); + } } } \ No newline at end of file diff --git a/Svelto.ECS/Profiler/EngineProfiler.cs b/Svelto.ECS/Profiler/EngineProfiler.cs index 4dc5ae4..56d0e39 100644 --- a/Svelto.ECS/Profiler/EngineProfiler.cs +++ b/Svelto.ECS/Profiler/EngineProfiler.cs @@ -12,28 +12,26 @@ namespace Svelto.ECS.Profiler { static readonly Stopwatch _stopwatch = new Stopwatch(); - public static readonly Dictionary engineInfos = new Dictionary(); - - public static void MonitorAddDuration(IHandleEntityViewEngine engine, IEntityView entityView) + public static void MonitorAddDuration(IHandleEntityViewEngineAbstracted engine, T entityView) { EngineInfo info; if (engineInfos.TryGetValue(engine.GetType(), out info)) { _stopwatch.Start(); - engine.Add(entityView); + (engine as IHandleEntityStructEngine).Add(ref entityView); _stopwatch.Stop(); info.AddAddDuration(_stopwatch.Elapsed.TotalMilliseconds); _stopwatch.Reset(); } } - public static void MonitorRemoveDuration(IHandleEntityViewEngine engine, IEntityView entityView) + public static void MonitorRemoveDuration(IHandleEntityViewEngineAbstracted engine, IEntityView entityView) { EngineInfo info; if (engineInfos.TryGetValue(engine.GetType(), out info)) { _stopwatch.Start(); - engine.Remove(entityView); + (engine as IHandleEntityViewEngine).Remove(entityView); _stopwatch.Stop(); info.AddRemoveDuration(_stopwatch.Elapsed.TotalMilliseconds); @@ -44,12 +42,19 @@ namespace Svelto.ECS.Profiler public static void AddEngine(IEngine engine) { if (engineInfos.ContainsKey(engine.GetType()) == false) + { engineInfos.Add(engine.GetType(), new EngineInfo(engine)); + } } public static void ResetDurations() { - foreach (var engine in engineInfos) engine.Value.ResetDurations(); + foreach (var engine in engineInfos) + { + engine.Value.ResetDurations(); + } } + + public static readonly Dictionary engineInfos = new Dictionary(); } -} \ No newline at end of file +} diff --git a/Svelto.ECS/SingleEntityViewEngine.cs b/Svelto.ECS/SingleEntityViewEngine.cs index 683257d..81489ba 100644 --- a/Svelto.ECS/SingleEntityViewEngine.cs +++ b/Svelto.ECS/SingleEntityViewEngine.cs @@ -2,11 +2,11 @@ using Svelto.ECS.Internal; namespace Svelto.ECS { - public abstract class SingleEntityViewEngine : IHandleEntityViewEngine where T : EntityView, new() + public abstract class SingleEntityViewEngine : IHandleEntityViewEngine where T : class, IEntityView { public void Add(IEntityView entityView) { - Add((T) entityView); //when byref returns will be vailable, this should be passed by reference, not copy! + Add((T) entityView); } public void Remove(IEntityView entityView)