Browse Source

add entity operations optimized

tags/2.9.1
Sebastiano Mandala 4 years ago
parent
commit
ce452d786d
5 changed files with 58 additions and 32 deletions
  1. +1
    -1
      Svelto.Common
  2. +1
    -0
      Svelto.ECS/DataStructures/TypeSafeDictionary.cs
  3. +26
    -8
      Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs
  4. +29
    -22
      Svelto.ECS/EnginesRoot.Submission.cs
  5. +1
    -1
      Svelto.ECS/Serialization/ISerializer.cs

+ 1
- 1
Svelto.Common

@@ -1 +1 @@
Subproject commit 0d71df6e66f2d0c72d23fa44b740bad4a0ff5e8c
Subproject commit c9f91c96bb7b765525607adbc66f3abe4eae4fd5

+ 1
- 0
Svelto.ECS/DataStructures/TypeSafeDictionary.cs View File

@@ -27,6 +27,7 @@ namespace Svelto.ECS.Internal
void SetCapacity(uint size);
void Trim();
void Clear();
void FastClear();
bool Has(uint entityIdEntityId);
}



+ 26
- 8
Svelto.ECS/EnginesRoot.DoubleBufferedEntityViews.cs View File

@@ -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<uint, uint> currentEntitiesCreatedPerGroup;
@@ -54,7 +72,7 @@ namespace Svelto.ECS

readonly FasterDictionary<uint, uint> _entitiesCreatedPerGroupA = new FasterDictionary<uint, uint>();
readonly FasterDictionary<uint, uint> _entitiesCreatedPerGroupB = new FasterDictionary<uint, uint>();
public DoubleBufferedEntitiesToAdd()
{
currentEntitiesCreatedPerGroup = _entitiesCreatedPerGroupA;


+ 29
- 22
Svelto.ECS/EnginesRoot.Submission.cs View File

@@ -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<RefWrapper<Type>, 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<RefWrapper<Type>, 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>(type);
if (groupDB.TryGetValue(wrapper, out var dbDic) == false)
dbDic = groupDB[wrapper] = typeSafeDictionary.Create();
var wrapper = new RefWrapper<Type>(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<uint, ITypeSafeDictionary>();
if (_groupsPerEntity.TryGetValue(wrapper, out var groupedGroup) == false)
groupedGroup = _groupsPerEntity[wrapper] =
new FasterDictionary<uint, ITypeSafeDictionary>();

groupedGroup[groupID] = dbDic;
groupedGroup[groupID] = dbDic;
}
}
}



+ 1
- 1
Svelto.ECS/Serialization/ISerializer.cs View File

@@ -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; }
}



Loading…
Cancel
Save