|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- using Svelto.DataStructures;
- using Svelto.ECS.Internal;
-
- namespace Svelto.ECS
- {
- public partial class EnginesRoot
- {
- internal class DoubleBufferedEntitiesToAdd
- {
- const int MAX_NUMBER_OF_ITEMS_PER_FRAME_BEFORE_TO_CLEAR = 100;
-
- public DoubleBufferedEntitiesToAdd()
- {
- _currentEntitiesCreatedPerGroup = _entitiesCreatedPerGroupA;
- _otherEntitiesCreatedPerGroup = _entitiesCreatedPerGroupB;
-
- current = _entityComponentsToAddBufferA;
- other = _entityComponentsToAddBufferB;
- }
-
- public void ClearOther()
- {
- //do not clear the groups created so far, they will be reused, unless they are too many!
- var otherCount = other.count;
- if (otherCount > MAX_NUMBER_OF_ITEMS_PER_FRAME_BEFORE_TO_CLEAR)
- {
- var otherValuesArray = other.unsafeValues;
- for (var i = 0; i < otherCount; ++i)
- {
- var safeDictionariesCount = otherValuesArray[i].count;
- var safeDictionaries = otherValuesArray[i].unsafeValues;
- {
- for (var j = 0; j < safeDictionariesCount; ++j)
- //clear the dictionary of entities create do far (it won't allocate though)
- safeDictionaries[j].Dispose();
- }
- }
-
- //reset the number of entities created so far
- _otherEntitiesCreatedPerGroup.FastClear();
- other.FastClear();
- return;
- }
-
- {
- var otherValuesArray = other.unsafeValues;
- for (var i = 0; i < otherCount; ++i)
- {
- var safeDictionariesCount = otherValuesArray[i].count;
- var safeDictionaries = otherValuesArray[i].unsafeValues;
- //do not remove the dictionaries of entities per type created so far, they will be reused
- if (safeDictionariesCount <= MAX_NUMBER_OF_ITEMS_PER_FRAME_BEFORE_TO_CLEAR)
- {
- for (var j = 0; j < safeDictionariesCount; ++j)
- //clear the dictionary of entities create do far (it won't allocate though)
- safeDictionaries[j].FastClear();
- }
- else
- {
- for (var j = 0; j < safeDictionariesCount; ++j)
- //clear the dictionary of entities create do far (it won't allocate though)
- safeDictionaries[j].Dispose();
-
- otherValuesArray[i].FastClear();
- }
- }
-
- //reset the number of entities created so far
- _otherEntitiesCreatedPerGroup.FastClear();
- }
- }
-
- public void Dispose()
- {
- {
- var otherValuesArray = other.unsafeValues;
- for (var i = 0; i < other.count; ++i)
- {
- var safeDictionariesCount = otherValuesArray[i].count;
- var safeDictionaries = otherValuesArray[i].unsafeValues;
- //do not remove the dictionaries of entities per type created so far, they will be reused
- for (var j = 0; j < safeDictionariesCount; ++j)
- //clear the dictionary of entities create do far (it won't allocate though)
- safeDictionaries[j].Dispose();
- }
- }
- {
- var currentValuesArray = current.unsafeValues;
- for (var i = 0; i < current.count; ++i)
- {
- var safeDictionariesCount = currentValuesArray[i].count;
- var safeDictionaries = currentValuesArray[i].unsafeValues;
- //do not remove the dictionaries of entities per type created so far, they will be reused
- for (var j = 0; j < safeDictionariesCount; ++j)
- //clear the dictionary of entities create do far (it won't allocate though)
- safeDictionaries[j].Dispose();
- }
- }
- }
-
- internal bool AnyEntityCreated()
- {
- return _currentEntitiesCreatedPerGroup.count > 0;
- }
-
- internal bool AnyOtherEntityCreated()
- {
- return _otherEntitiesCreatedPerGroup.count > 0;
- }
-
- internal void IncrementEntityCount(ExclusiveGroupStruct groupID)
- {
- _currentEntitiesCreatedPerGroup.GetOrCreate(groupID)++;
- }
-
- internal void Preallocate
- (ExclusiveGroupStruct groupID, uint numberOfEntities, IComponentBuilder[] entityComponentsToBuild)
- {
- void PreallocateDictionaries
- (FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>> dic)
- {
- var group = dic.GetOrCreate(groupID, () => new FasterDictionary<RefWrapperType,
- ITypeSafeDictionary>());
-
- foreach (var componentBuilder in entityComponentsToBuild)
- {
- var entityComponentType = componentBuilder.GetEntityComponentType();
- var safeDictionary = group.GetOrCreate(new RefWrapperType(entityComponentType)
- , () => componentBuilder
- .CreateDictionary(numberOfEntities));
- componentBuilder.Preallocate(safeDictionary, numberOfEntities);
- }
- }
-
- PreallocateDictionaries(current);
- PreallocateDictionaries(other);
-
- _currentEntitiesCreatedPerGroup.GetOrCreate(groupID);
- _otherEntitiesCreatedPerGroup.GetOrCreate(groupID);
- }
-
- internal void Swap()
- {
- Swap(ref current, ref other);
- Swap(ref _currentEntitiesCreatedPerGroup, ref _otherEntitiesCreatedPerGroup);
- }
-
- void Swap<T>(ref T item1, ref T item2)
- {
- var toSwap = item2;
- item2 = item1;
- item1 = toSwap;
- }
-
- //Before I tried for the third time to use a SparseSet instead of FasterDictionary, remember that
- //while group indices are sequential, they may not be used in a sequential order. Sparseset needs
- //entities to be created sequentially (the index cannot be managed externally)
- internal FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>> current;
- internal FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>> other;
-
- readonly FasterDictionary<ExclusiveGroupStruct, uint> _entitiesCreatedPerGroupA =
- new FasterDictionary<ExclusiveGroupStruct, uint>();
-
- readonly FasterDictionary<ExclusiveGroupStruct, uint> _entitiesCreatedPerGroupB =
- new FasterDictionary<ExclusiveGroupStruct, uint>();
-
- readonly FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>> _entityComponentsToAddBufferA =
- new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>();
-
- readonly FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>> _entityComponentsToAddBufferB =
- new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>();
-
- /// <summary>
- /// To avoid extra allocation, I don't clear the groups, so I need an extra data structure
- /// to keep count of the number of entities built this frame. At the moment the actual number
- /// of entities built is not used
- /// </summary>
- FasterDictionary<ExclusiveGroupStruct, uint> _currentEntitiesCreatedPerGroup;
- FasterDictionary<ExclusiveGroupStruct, uint> _otherEntitiesCreatedPerGroup;
- }
- }
- }
|