diff --git a/Svelto.Common b/Svelto.Common index 0d71df6..c9f91c9 160000 --- a/Svelto.Common +++ b/Svelto.Common @@ -1 +1 @@ -Subproject commit 0d71df6e66f2d0c72d23fa44b740bad4a0ff5e8c +Subproject commit c9f91c96bb7b765525607adbc66f3abe4eae4fd5 diff --git a/Svelto.ECS/DataStructures/TypeSafeDictionary.cs b/Svelto.ECS/DataStructures/TypeSafeDictionary.cs index 53a54be..d902d72 100644 --- a/Svelto.ECS/DataStructures/TypeSafeDictionary.cs +++ b/Svelto.ECS/DataStructures/TypeSafeDictionary.cs @@ -27,6 +27,7 @@ namespace Svelto.ECS.Internal void SetCapacity(uint size); void Trim(); void Clear(); + void FastClear(); bool Has(uint entityIdEntityId); } diff --git a/Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs b/Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs index 8625abe..f6077f3 100644 --- a/Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs +++ b/Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using Svelto.DataStructures; using Svelto.ECS.Internal; @@ -9,6 +8,8 @@ namespace Svelto.ECS { internal class DoubleBufferedEntitiesToAdd { + const int MaximumNumberOfItemsPerFrameBeforeToClear = 100; + internal void Swap() { Swap(ref current, ref other); @@ -24,18 +25,35 @@ namespace Svelto.ECS public void ClearOther() { - //do not clear the groups created so far, they will be reused - foreach (var groups in other) + //do not clear the groups created so far, they will be reused, unless they are too many! + var otherCount = other.Count; + if (otherCount > MaximumNumberOfItemsPerFrameBeforeToClear) + { + otherEntitiesCreatedPerGroup.FastClear(); + other.FastClear(); + return; + } + var otherValuesArray = other.valuesArray; + for (int i = 0; i < otherCount; ++i) { + var safeDictionariesCount = otherValuesArray[i].Count; + var safeDictionaries = otherValuesArray[i].valuesArray; //do not remove the dictionaries of entities per type created so far, they will be reused - foreach (var entitiesPerType in groups.Value) + if (safeDictionariesCount <= MaximumNumberOfItemsPerFrameBeforeToClear) { - //clear the dictionary of entities create do far (it won't allocate though) - entitiesPerType.Value.Clear(); + for (int j = 0; j < safeDictionariesCount; ++j) + { + //clear the dictionary of entities create do far (it won't allocate though) + safeDictionaries[j].FastClear(); + } + } + else + { + otherValuesArray[i].FastClear(); } } - otherEntitiesCreatedPerGroup.Clear(); + otherEntitiesCreatedPerGroup.FastClear(); } internal FasterDictionary currentEntitiesCreatedPerGroup; @@ -54,7 +72,7 @@ namespace Svelto.ECS readonly FasterDictionary _entitiesCreatedPerGroupA = new FasterDictionary(); readonly FasterDictionary _entitiesCreatedPerGroupB = new FasterDictionary(); - + public DoubleBufferedEntitiesToAdd() { currentEntitiesCreatedPerGroup = _entitiesCreatedPerGroupA; diff --git a/Svelto.ECS/EnginesRoot.Submission.cs b/Svelto.ECS/EnginesRoot.Submission.cs index 8ecaa15..f0e8963 100644 --- a/Svelto.ECS/EnginesRoot.Submission.cs +++ b/Svelto.ECS/EnginesRoot.Submission.cs @@ -88,8 +88,11 @@ namespace Svelto.ECS } finally { - //other can be cleared now, but let's avoid deleting the dictionary every time - _groupedEntityToAdd.ClearOther(); + using (profiler.Sample("clear operates double buffering")) + { + //other can be cleared now, but let's avoid deleting the dictionary every time + _groupedEntityToAdd.ClearOther(); + } } } } @@ -97,33 +100,37 @@ namespace Svelto.ECS void AddEntityViewsToTheDBAndSuitableEngines(in PlatformProfiler profiler) { - //each group is indexed by entity view type. for each type there is a dictionary indexed by entityID - foreach (var groupOfEntitiesToSubmit in _groupedEntityToAdd.otherEntitiesCreatedPerGroup) + using (profiler.Sample("Add entities to database")) { - var groupID = groupOfEntitiesToSubmit.Key; + //each group is indexed by entity view type. for each type there is a dictionary indexed by entityID + foreach (var groupOfEntitiesToSubmit in _groupedEntityToAdd.otherEntitiesCreatedPerGroup) + { + var groupID = groupOfEntitiesToSubmit.Key; - //if the group doesn't exist in the current DB let's create it first - if (_groupEntityViewsDB.TryGetValue(groupID, out var groupDB) == false) - groupDB = _groupEntityViewsDB[groupID] = - new FasterDictionary, ITypeSafeDictionary>(); + //if the group doesn't exist in the current DB let's create it first + if (_groupEntityViewsDB.TryGetValue(groupID, out var groupDB) == false) + groupDB = _groupEntityViewsDB[groupID] = + new FasterDictionary, ITypeSafeDictionary>(); - //add the entityViews in the group - foreach (var entityViewsToSubmit in _groupedEntityToAdd.other[groupID]) - { - var type = entityViewsToSubmit.Key; - var typeSafeDictionary = entityViewsToSubmit.Value; + //add the entityViews in the group + foreach (var entityViewsToSubmit in _groupedEntityToAdd.other[groupID]) + { + var type = entityViewsToSubmit.Key; + var typeSafeDictionary = entityViewsToSubmit.Value; - var wrapper = new RefWrapper(type); - if (groupDB.TryGetValue(wrapper, out var dbDic) == false) - dbDic = groupDB[wrapper] = typeSafeDictionary.Create(); + var wrapper = new RefWrapper(type); + if (groupDB.TryGetValue(wrapper, out var dbDic) == false) + dbDic = groupDB[wrapper] = typeSafeDictionary.Create(); - //Fill the DB with the entity views generate this frame. - dbDic.AddEntitiesFromDictionary(typeSafeDictionary, groupID); + //Fill the DB with the entity views generate this frame. + dbDic.AddEntitiesFromDictionary(typeSafeDictionary, groupID); - if (_groupsPerEntity.TryGetValue(wrapper, out var groupedGroup) == false) - groupedGroup = _groupsPerEntity[wrapper] = new FasterDictionary(); + if (_groupsPerEntity.TryGetValue(wrapper, out var groupedGroup) == false) + groupedGroup = _groupsPerEntity[wrapper] = + new FasterDictionary(); - groupedGroup[groupID] = dbDic; + groupedGroup[groupID] = dbDic; + } } } diff --git a/Svelto.ECS/Serialization/ISerializer.cs b/Svelto.ECS/Serialization/ISerializer.cs index 4dd9296..39fa588 100644 --- a/Svelto.ECS/Serialization/ISerializer.cs +++ b/Svelto.ECS/Serialization/ISerializer.cs @@ -9,7 +9,7 @@ namespace Svelto.ECS.Serialization { bool Serialize(in T value, ISerializationData serializationData); bool Deserialize(ref T value, ISerializationData serializationData); - + uint size { get; } }