diff --git a/Svelto.ECS/DataStructures/TypeSafeDictionary.cs b/Svelto.ECS/DataStructures/TypeSafeDictionary.cs index e892a2e..c835592 100644 --- a/Svelto.ECS/DataStructures/TypeSafeDictionary.cs +++ b/Svelto.ECS/DataStructures/TypeSafeDictionary.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Svelto.Common; using Svelto.DataStructures; using Svelto.DataStructures.Experimental; @@ -10,14 +11,15 @@ namespace Svelto.ECS.Internal ITypeSafeDictionary Create(); void RemoveEntitiesFromEngines(Dictionary> - entityViewEnginesDB); + entityViewEnginesDB, PlatformProfiler profiler); void MoveEntityFromDictionaryAndEngines(EGID fromEntityGid, EGID toEntityID, ITypeSafeDictionary toGroup, Dictionary> - entityViewEnginesDB); + entityViewEnginesDB, PlatformProfiler profiler); void FillWithIndexedEntities(ITypeSafeDictionary entities); - void AddEntitiesToEngines(Dictionary> entityViewEnginesDB); + void AddEntitiesToEngines(Dictionary> entityViewEnginesDB, + PlatformProfiler profiler); void AddCapacity(int size); @@ -58,7 +60,8 @@ namespace Svelto.ECS.Internal } public void AddEntitiesToEngines( - Dictionary> entityViewEnginesDB) + Dictionary> entityViewEnginesDB, + PlatformProfiler profiler) { int count; TValue[] values = GetValuesArray(out count); @@ -67,7 +70,7 @@ namespace Svelto.ECS.Internal { TValue entity = values[i]; - AddEntityViewToEngines(entityViewEnginesDB, ref entity); + AddEntityViewToEngines(entityViewEnginesDB, ref entity, profiler); } } @@ -82,7 +85,8 @@ namespace Svelto.ECS.Internal } void AddEntityViewToEngines(Dictionary> entityViewEnginesDB, - ref TValue entity) + ref TValue entity, + PlatformProfiler profiler) { FasterList entityViewsEngines; //get all the engines linked to TValue @@ -91,7 +95,10 @@ namespace Svelto.ECS.Internal { try { - (entityViewsEngines[i] as IHandleEntityStructEngine).AddInternal(ref entity); + using (profiler.Sample((entityViewsEngines[i] as EngineInfo).name)) + { + (entityViewsEngines[i] as IHandleEntityStructEngine).AddInternal(ref entity); + } } catch (Exception e) { @@ -103,14 +110,14 @@ namespace Svelto.ECS.Internal public void MoveEntityFromDictionaryAndEngines(EGID fromEntityGid, EGID toEntityID, ITypeSafeDictionary toGroup, Dictionary> - entityViewEnginesDB) + entityViewEnginesDB, PlatformProfiler profiler) { int count; var fasterValuesBuffer = GetValuesArray(out count); var valueIndex = GetValueIndex(fromEntityGid.entityID); - + if (entityViewEnginesDB != null) - RemoveEntityViewFromEngines(entityViewEnginesDB, ref fasterValuesBuffer[valueIndex]); + RemoveEntityViewFromEngines(entityViewEnginesDB, ref fasterValuesBuffer[valueIndex], profiler); if (toGroup != null) { @@ -120,21 +127,25 @@ namespace Svelto.ECS.Internal if (entityViewEnginesDB != null) AddEntityViewToEngines(entityViewEnginesDB, ref toGroupCasted.GetValuesArray(out count) - [toGroupCasted.GetValueIndex(toEntityID.entityID)]); + [toGroupCasted.GetValueIndex(toEntityID.entityID)], profiler); } Remove(fromEntityGid.entityID); } static void RemoveEntityViewFromEngines - (Dictionary> entityViewEnginesDB, ref TValue entity) + (Dictionary> entityViewEnginesDB, ref TValue entity, + PlatformProfiler profiler) { FasterList entityViewsEngines; if (entityViewEnginesDB.TryGetValue(_type, out entityViewsEngines)) for (int i = 0; i < entityViewsEngines.Count; i++) try { - (entityViewsEngines[i] as IHandleEntityStructEngine).RemoveInternal(ref entity); + using (profiler.Sample((entityViewsEngines[i] as EngineInfo).name, _typeName)) + { + (entityViewsEngines[i] as IHandleEntityStructEngine).RemoveInternal(ref entity); + } } catch (Exception e) { @@ -143,13 +154,13 @@ namespace Svelto.ECS.Internal } } - public void RemoveEntitiesFromEngines(Dictionary> entityViewEnginesDB) + public void RemoveEntitiesFromEngines(Dictionary> entityViewEnginesDB, PlatformProfiler profiler) { int count; TValue[] values = GetValuesArray(out count); for (int i = 0; i < count; i++) - RemoveEntityViewFromEngines(entityViewEnginesDB, ref values[i]); + RemoveEntityViewFromEngines(entityViewEnginesDB, ref values[i], profiler); } public ITypeSafeDictionary Create() @@ -198,5 +209,10 @@ namespace Svelto.ECS.Internal } static readonly Type _type = typeof(TValue); + static readonly string _typeName +#if ENABLE_PLATFORM_PROFILER + = _type.Name +#endif + ; } } \ No newline at end of file diff --git a/Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs b/Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs index f5f26c4..6ed2d9a 100644 --- a/Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs +++ b/Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs @@ -1,13 +1,8 @@ using System; -using System.Collections; using System.Collections.Generic; using Svelto.DataStructures.Experimental; using Svelto.ECS.Internal; -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR -using Svelto.ECS.Profiler; -#endif - namespace Svelto.ECS { public partial class EnginesRoot diff --git a/Svelto.ECS/EnginesRoot.Engines.cs b/Svelto.ECS/EnginesRoot.Engines.cs index 8a3991f..67ef500 100644 --- a/Svelto.ECS/EnginesRoot.Engines.cs +++ b/Svelto.ECS/EnginesRoot.Engines.cs @@ -6,27 +6,10 @@ using Svelto.ECS.Internal; using Svelto.ECS.Schedulers; using Svelto.WeakEvents; -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR -using Svelto.ECS.Profiler; -#endif - namespace Svelto.ECS { public partial class EnginesRoot { -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR - static EnginesRoot() - { - -/// -/// I still need to find a good solution for this. Need to move somewhere else -/// - UnityEngine.GameObject debugEngineObject = new UnityEngine.GameObject("Svelto.ECS.Profiler"); - debugEngineObject.gameObject.AddComponent(); - UnityEngine.GameObject.DontDestroyOnLoad(debugEngineObject); - } -#endif - /// /// Engines root contextualize your engines and entities. You don't need to limit yourself to one EngineRoot /// as multiple engines root could promote separation of scopes. The EntitySubmissionScheduler checks @@ -58,9 +41,6 @@ namespace Svelto.ECS public void AddEngine(IEngine engine) { -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR - Profiler.EngineProfiler.AddEngine(engine); -#endif DBC.ECS.Check.Require(_enginesSet.Contains(engine) == false, "The same engine has been added more than once " .FastConcat(engine.ToString())); diff --git a/Svelto.ECS/EnginesRoot.Entities.cs b/Svelto.ECS/EnginesRoot.Entities.cs index 7949772..a0169a3 100644 --- a/Svelto.ECS/EnginesRoot.Entities.cs +++ b/Svelto.ECS/EnginesRoot.Entities.cs @@ -1,12 +1,9 @@ using System; using System.Collections.Generic; -using Svelto.DataStructures.Experimental; + using Svelto.Common; + using Svelto.DataStructures.Experimental; using Svelto.ECS.Internal; -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR -using Svelto.ECS.Profiler; -#endif - namespace Svelto.ECS { public partial class EnginesRoot: IDisposable @@ -18,28 +15,31 @@ namespace Svelto.ECS /// public void Dispose() { - foreach (var groups in _groupEntityDB) - foreach (var entityList in groups.Value) - { + using (var profiler = new PlatformProfiler("Final Dispose")) + { + foreach (var groups in _groupEntityDB) + foreach (var entityList in groups.Value) + { + try + { + entityList.Value.RemoveEntitiesFromEngines(_entityEngines, profiler); + } + catch (Exception e) + { + Svelto.Utilities.Console.LogException(e); + } + } + + foreach (var engine in _disposableEngines) try { - entityList.Value.RemoveEntitiesFromEngines(_entityEngines); + engine.Dispose(); } catch (Exception e) { Svelto.Utilities.Console.LogException(e); } - } - - foreach (var engine in _disposableEngines) - try - { - engine.Dispose(); - } - catch (Exception e) - { - Svelto.Utilities.Console.LogException(e); - } + } GC.SuppressFinalize(this); } @@ -123,53 +123,64 @@ namespace Svelto.ECS void MoveEntity(IEntityBuilder[] entityBuilders, EGID entityGID, Type originalDescriptorType, EGID toEntityGID, Dictionary toGroup = null) { - //for each entity view generated by the entity descriptor - Dictionary fromGroup; + using (var profiler = new PlatformProfiler("Move Entity")) + { + //for each entity view generated by the entity descriptor + Dictionary fromGroup; - if (_groupEntityDB.TryGetValue(entityGID.groupID, out fromGroup) == false) - throw new ECSException("from group not found eid: ".FastConcat(entityGID.entityID).FastConcat(" group: ").FastConcat(entityGID.groupID)); + if (_groupEntityDB.TryGetValue(entityGID.groupID, out fromGroup) == false) + throw new ECSException("from group not found eid: " + .FastConcat(entityGID.entityID).FastConcat(" group: ") + .FastConcat(entityGID.groupID)); - ITypeSafeDictionary entityInfoViewDic; - - EntityInfoView entityInfoView = default(EntityInfoView); - - //Check if there is an EntityInfoView linked to this entity, if so it's a DynamicEntityDescriptor! - bool correctEntityDescriptorFound = true; - if (fromGroup.TryGetValue(_entityInfoView, out entityInfoViewDic) == true - && (entityInfoViewDic as TypeSafeDictionary).TryGetValue - (entityGID.entityID, out entityInfoView) == true && - (correctEntityDescriptorFound = entityInfoView.type == originalDescriptorType) == true) - { - var entitiesToMove = entityInfoView.entitiesToBuild; - - for (int i = 0; i < entitiesToMove.Length; i++) - MoveEntityView(entityGID, toEntityGID, toGroup, fromGroup, entitiesToMove[i].GetEntityType()); - } - //otherwise it's a normal static entity descriptor - else - { + ITypeSafeDictionary entityInfoViewDic; + + EntityInfoView entityInfoView = default(EntityInfoView); + + //Check if there is an EntityInfoView linked to this entity, if so it's a DynamicEntityDescriptor! + bool correctEntityDescriptorFound = true; + if (fromGroup.TryGetValue(_entityInfoView, out entityInfoViewDic) == true + && (entityInfoViewDic as TypeSafeDictionary).TryGetValue + (entityGID.entityID, out entityInfoView) == true && + (correctEntityDescriptorFound = entityInfoView.type == originalDescriptorType) == true) + { + var entitiesToMove = entityInfoView.entitiesToBuild; + + for (int i = 0; i < entitiesToMove.Length; i++) + MoveEntityView(entityGID, toEntityGID, toGroup, fromGroup, entitiesToMove[i].GetEntityType(), profiler); + } + //otherwise it's a normal static entity descriptor + else + { #if DEBUG && !PROFILER - if (correctEntityDescriptorFound == false) -#if RELAXED_ECS - Utilities.Console.LogError(INVALID_DYNAMIC_DESCRIPTOR_ERROR.FastConcat(" ID ").FastConcat(entityGID.entityID) - .FastConcat(" group ID ").FastConcat(entityGID.groupID).FastConcat( - " descriptor found: ", entityInfoView.type.Name, " descriptor Excepted ", - originalDescriptorType.Name)); + if (correctEntityDescriptorFound == false) +#if RELAXED_ECS + Utilities.Console.LogError(INVALID_DYNAMIC_DESCRIPTOR_ERROR + .FastConcat(" ID ").FastConcat(entityGID.entityID) + .FastConcat(" group ID ").FastConcat(entityGID.groupID).FastConcat( + " descriptor found: ", + entityInfoView + .type + .Name, + " descriptor Excepted ", + originalDescriptorType + .Name)); #else throw new ECSException(INVALID_DYNAMIC_DESCRIPTOR_ERROR.FastConcat(" ID ").FastConcat(entityGID.entityID) .FastConcat(" group ID ").FastConcat(entityGID.groupID).FastConcat( " descriptor found: ", entityInfoView.type.Name, " descriptor Excepted ", originalDescriptorType.Name)); #endif -#endif - - for (var i = 0; i < entityBuilders.Length; i++) - MoveEntityView(entityGID, toEntityGID, toGroup, fromGroup, entityBuilders[i].GetEntityType()); +#endif + + for (var i = 0; i < entityBuilders.Length; i++) + MoveEntityView(entityGID, toEntityGID, toGroup, fromGroup, entityBuilders[i].GetEntityType(), profiler); + } } } void MoveEntityView(EGID entityGID, EGID toEntityGID, Dictionary toGroup, - Dictionary fromGroup, Type entityType) + Dictionary fromGroup, Type entityType, PlatformProfiler profiler) { ITypeSafeDictionary fromTypeSafeDictionary; if (fromGroup.TryGetValue(entityType, out fromTypeSafeDictionary) == false) @@ -199,31 +210,34 @@ namespace Svelto.ECS { throw new EntityNotFoundException(entityGID.entityID, entityGID.groupID, entityType); } - fromTypeSafeDictionary.MoveEntityFromDictionaryAndEngines(entityGID, toEntityGID, dictionaryOfEntities, _entityEngines); + fromTypeSafeDictionary.MoveEntityFromDictionaryAndEngines(entityGID, toEntityGID, dictionaryOfEntities, _entityEngines, profiler); if (fromTypeSafeDictionary.Count == 0) //clean up { _groupsPerEntity[entityType].Remove(entityGID.groupID); - //I don't remove the group if empty on purpose, in case it needs to be reused - //however I trim it to save memory + //I don't remove the group if empty on purpose, in case it needs to be reused however I trim it to save + //memory fromTypeSafeDictionary.Trim(); } } void RemoveGroupAndEntitiesFromDB(int groupID) { - var dictionariesOfEntities = _groupEntityDB[groupID]; - foreach (var dictionaryOfEntities in dictionariesOfEntities) + using (var profiler = new PlatformProfiler("Remove Group")) { - dictionaryOfEntities.Value.RemoveEntitiesFromEngines(_entityEngines); - var groupedGroupOfEntities = _groupsPerEntity[dictionaryOfEntities.Key]; - groupedGroupOfEntities.Remove(groupID); - } + var dictionariesOfEntities = _groupEntityDB[groupID]; + foreach (var dictionaryOfEntities in dictionariesOfEntities) + { + dictionaryOfEntities.Value.RemoveEntitiesFromEngines(_entityEngines, profiler); + var groupedGroupOfEntities = _groupsPerEntity[dictionaryOfEntities.Key]; + groupedGroupOfEntities.Remove(groupID); + } - //careful, in this case I assume you really don't want to use this group anymore - //so I remove it from the database - _groupEntityDB.Remove(groupID); + //careful, in this case I assume you really don't want to use this group anymore + //so I remove it from the database + _groupEntityDB.Remove(groupID); + } } ///-------------------------------------------- diff --git a/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs b/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs index 7c0a5b3..73b7a93 100644 --- a/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs +++ b/Svelto.ECS/EnginesRoot.GenericEntityFactory.cs @@ -1,8 +1,4 @@ -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR -using Svelto.ECS.Profiler; -#endif - -namespace Svelto.ECS +namespace Svelto.ECS { public partial class EnginesRoot { diff --git a/Svelto.ECS/EnginesRoot.GenericEntityFunctions.cs b/Svelto.ECS/EnginesRoot.GenericEntityFunctions.cs index 39a7afb..0025a65 100644 --- a/Svelto.ECS/EnginesRoot.GenericEntityFunctions.cs +++ b/Svelto.ECS/EnginesRoot.GenericEntityFunctions.cs @@ -1,9 +1,5 @@ using System; - using Svelto.ECS.Internal; - -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR -using Svelto.ECS.Profiler; -#endif +using Svelto.ECS.Internal; namespace Svelto.ECS { diff --git a/Svelto.ECS/EnginesRoot.Submission.cs b/Svelto.ECS/EnginesRoot.Submission.cs index 4200887..758bb07 100644 --- a/Svelto.ECS/EnginesRoot.Submission.cs +++ b/Svelto.ECS/EnginesRoot.Submission.cs @@ -7,10 +7,6 @@ using Svelto.ECS.Internal; using Svelto.ECS.Schedulers; using Console = Svelto.Utilities.Console; -#if ENGINE_PROFILER_ENABLED && UNITY_EDITOR -using Svelto.ECS.Profiler; -#endif - namespace Svelto.ECS { public partial class EnginesRoot @@ -21,7 +17,7 @@ namespace Svelto.ECS { if (_entitiesOperations.Count > 0) { - using (profiler.Sample("Remove and Swap")) + using (profiler.Sample("Remove and Swap operations")) { #if DEBUG && !PROFILER _entitiesOperationsDebug.Clear(); @@ -94,7 +90,7 @@ namespace Svelto.ECS if (_groupedEntityToAdd.current.Count > 0) { - using (profiler.Sample("Add")) + using (profiler.Sample("Add operations")) { //use other as source from now on current will be use to write new entityViews _groupedEntityToAdd.Swap(); @@ -105,7 +101,7 @@ namespace Svelto.ECS //times on the same frame. if the Add callback builds a new entity, that entity will not //be available in the database until the N callbacks are done solving it could be complicated as //callback and database update must be interleaved. - AddEntityViewsToTheDBAndSuitableEngines(_groupedEntityToAdd.other); + AddEntityViewsToTheDBAndSuitableEngines(_groupedEntityToAdd.other, profiler); } #if !DEBUG catch (Exception e) @@ -124,7 +120,7 @@ namespace Svelto.ECS } void AddEntityViewsToTheDBAndSuitableEngines( - FasterDictionary> groupsOfEntitiesToSubmit) + FasterDictionary> groupsOfEntitiesToSubmit, PlatformProfiler profiler) { //each group is indexed by entity view type. for each type there is a dictionary indexed by entityID foreach (var groupOfEntitiesToSubmit in groupsOfEntitiesToSubmit) @@ -160,7 +156,10 @@ namespace Svelto.ECS { foreach (var entityViewsPerType in groupToSubmit.Value) { - entityViewsPerType.Value.AddEntitiesToEngines(_entityEngines); + using (profiler.Sample("Add entities to engines")) + { + entityViewsPerType.Value.AddEntitiesToEngines(_entityEngines, profiler); + } } } } diff --git a/Svelto.ECS/IEngine.cs b/Svelto.ECS/IEngine.cs index 2a3cb00..a2e8c1e 100644 --- a/Svelto.ECS/IEngine.cs +++ b/Svelto.ECS/IEngine.cs @@ -1,19 +1,28 @@ -using Svelto.ECS.Internal; - namespace Svelto.ECS.Internal { public interface IHandleEntityViewEngineAbstracted : IEngine {} + + public interface IHandleEntityStructEngine : IHandleEntityViewEngineAbstracted + { + void AddInternal(ref T entityView); + void RemoveInternal(ref T entityView); + } + + public class EngineInfo + { +#if ENABLE_PLATFORM_PROFILER + public EngineInfo() + { + name = GetType().FullName; + } +#endif + internal string name; + } } namespace Svelto.ECS { public interface IEngine {} - - public interface IHandleEntityStructEngine : IHandleEntityViewEngineAbstracted - { - void AddInternal(ref T entityView); - void RemoveInternal(ref T entityView); - } } \ No newline at end of file diff --git a/Svelto.ECS/MultiEntitiesEngine.cs b/Svelto.ECS/MultiEntitiesEngine.cs index c0fb410..701b6f1 100644 --- a/Svelto.ECS/MultiEntitiesEngine.cs +++ b/Svelto.ECS/MultiEntitiesEngine.cs @@ -1,3 +1,5 @@ +using Svelto.ECS.Internal; + namespace Svelto.ECS { public abstract class MultiEntitiesEngine : SingleEntityEngine, IHandleEntityStructEngine @@ -25,9 +27,8 @@ namespace Svelto.ECS } /// - /// Please do not add more MultiEntityViewsEngine - /// if you use more than 4 nodes, your engine has - /// already too many responsabilities. + /// Please do not add more MultiEntityViewsEngine if you use more than 4 nodes, your engine has + /// already too many responsibilities. /// public abstract class MultiEntitiesEngine : MultiEntitiesEngine, IHandleEntityStructEngine where W : IEntityStruct where V : IEntityStruct where U : IEntityStruct where T : IEntityStruct diff --git a/Svelto.ECS/MultiEntityViewsEngine.cs b/Svelto.ECS/MultiEntityViewsEngine.cs index 0d82fcc..fabb009 100644 --- a/Svelto.ECS/MultiEntityViewsEngine.cs +++ b/Svelto.ECS/MultiEntityViewsEngine.cs @@ -1,3 +1,5 @@ +using Svelto.ECS.Internal; + namespace Svelto.ECS { public abstract class MultiEntityViewsEngine : SingleEntityViewEngine, IHandleEntityStructEngine diff --git a/Svelto.ECS/SingleEntityEngine.cs b/Svelto.ECS/SingleEntityEngine.cs index 260ea3c..5c3d47d 100644 --- a/Svelto.ECS/SingleEntityEngine.cs +++ b/Svelto.ECS/SingleEntityEngine.cs @@ -1,6 +1,8 @@ +using Svelto.ECS.Internal; + namespace Svelto.ECS { - public abstract class SingleEntityEngine : IHandleEntityStructEngine where T : IEntityStruct + public abstract class SingleEntityEngine : EngineInfo, IHandleEntityStructEngine where T : IEntityStruct { public void AddInternal(ref T entityView) { Add(ref entityView); } diff --git a/Svelto.ECS/SingleEntityViewEngine.cs b/Svelto.ECS/SingleEntityViewEngine.cs index d023748..52539d2 100644 --- a/Svelto.ECS/SingleEntityViewEngine.cs +++ b/Svelto.ECS/SingleEntityViewEngine.cs @@ -1,6 +1,8 @@ +using Svelto.ECS.Internal; + namespace Svelto.ECS { - public abstract class SingleEntityViewEngine : IHandleEntityStructEngine where T : class, IEntityStruct + public abstract class SingleEntityViewEngine : EngineInfo, IHandleEntityStructEngine where T : class, IEntityStruct { public void AddInternal(ref T entityView) { Add(entityView); }