Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

EnginesRoot.DoubleBufferedEntitiesToAdd.cs 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. using Svelto.DataStructures;
  2. using Svelto.ECS.Internal;
  3. namespace Svelto.ECS
  4. {
  5. public partial class EnginesRoot
  6. {
  7. internal class DoubleBufferedEntitiesToAdd
  8. {
  9. const int MaximumNumberOfItemsPerFrameBeforeToClear = 100;
  10. internal void Swap()
  11. {
  12. Swap(ref current, ref other);
  13. Swap(ref currentEntitiesCreatedPerGroup, ref otherEntitiesCreatedPerGroup);
  14. }
  15. void Swap<T>(ref T item1, ref T item2)
  16. {
  17. var toSwap = item2;
  18. item2 = item1;
  19. item1 = toSwap;
  20. }
  21. public void ClearOther()
  22. {
  23. //do not clear the groups created so far, they will be reused, unless they are too many!
  24. var otherCount = other.count;
  25. if (otherCount > MaximumNumberOfItemsPerFrameBeforeToClear)
  26. {
  27. FasterDictionary<RefWrapperType, ITypeSafeDictionary>[] otherValuesArray = other.unsafeValues;
  28. for (int i = 0; i < otherCount; ++i)
  29. {
  30. var safeDictionariesCount = otherValuesArray[i].count;
  31. ITypeSafeDictionary[] safeDictionaries = otherValuesArray[i].unsafeValues;
  32. {
  33. for (int j = 0; j < safeDictionariesCount; ++j)
  34. {
  35. //clear the dictionary of entities create do far (it won't allocate though)
  36. safeDictionaries[j].Dispose();
  37. }
  38. }
  39. }
  40. otherEntitiesCreatedPerGroup.FastClear();
  41. other.FastClear();
  42. return;
  43. }
  44. {
  45. FasterDictionary<RefWrapperType, ITypeSafeDictionary>[] otherValuesArray = other.unsafeValues;
  46. for (int i = 0; i < otherCount; ++i)
  47. {
  48. var safeDictionariesCount = otherValuesArray[i].count;
  49. ITypeSafeDictionary[] safeDictionaries = otherValuesArray[i].unsafeValues;
  50. //do not remove the dictionaries of entities per type created so far, they will be reused
  51. if (safeDictionariesCount <= MaximumNumberOfItemsPerFrameBeforeToClear)
  52. {
  53. for (int j = 0; j < safeDictionariesCount; ++j)
  54. {
  55. //clear the dictionary of entities create do far (it won't allocate though)
  56. safeDictionaries[j].FastClear();
  57. }
  58. }
  59. else
  60. {
  61. for (int j = 0; j < safeDictionariesCount; ++j)
  62. {
  63. //clear the dictionary of entities create do far (it won't allocate though)
  64. safeDictionaries[j].Dispose();
  65. }
  66. otherValuesArray[i].FastClear();
  67. }
  68. }
  69. otherEntitiesCreatedPerGroup.FastClear();
  70. }
  71. }
  72. /// <summary>
  73. /// To avoid extra allocation, I don't clear the dictionaries, so I need an extra data structure
  74. /// to keep count of the number of entities submitted this frame
  75. /// </summary>
  76. internal FasterDictionary<ExclusiveGroupStruct, uint> currentEntitiesCreatedPerGroup;
  77. internal FasterDictionary<ExclusiveGroupStruct, uint> otherEntitiesCreatedPerGroup;
  78. //Before I tried for the third time to use a SparseSet instead of FasterDictionary, remember that
  79. //while group indices are sequential, they may not be used in a sequential order. Sparaset needs
  80. //entities to be created sequentially (the index cannot be managed externally)
  81. internal FasterDictionary<uint, FasterDictionary<RefWrapperType, ITypeSafeDictionary>> current;
  82. internal FasterDictionary<uint, FasterDictionary<RefWrapperType, ITypeSafeDictionary>> other;
  83. readonly FasterDictionary<uint, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>
  84. _entityComponentsToAddBufferA =
  85. new FasterDictionary<uint, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>();
  86. readonly FasterDictionary<uint, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>
  87. _entityComponentsToAddBufferB =
  88. new FasterDictionary<uint, FasterDictionary<RefWrapperType, ITypeSafeDictionary>>();
  89. readonly FasterDictionary<ExclusiveGroupStruct, uint> _entitiesCreatedPerGroupA = new FasterDictionary<ExclusiveGroupStruct, uint>();
  90. readonly FasterDictionary<ExclusiveGroupStruct, uint> _entitiesCreatedPerGroupB = new FasterDictionary<ExclusiveGroupStruct, uint>();
  91. public DoubleBufferedEntitiesToAdd()
  92. {
  93. currentEntitiesCreatedPerGroup = _entitiesCreatedPerGroupA;
  94. otherEntitiesCreatedPerGroup = _entitiesCreatedPerGroupB;
  95. current = _entityComponentsToAddBufferA;
  96. other = _entityComponentsToAddBufferB;
  97. }
  98. public void Dispose()
  99. {
  100. {
  101. var otherValuesArray = other.unsafeValues;
  102. for (int i = 0; i < other.count; ++i)
  103. {
  104. var safeDictionariesCount = otherValuesArray[i].count;
  105. var safeDictionaries = otherValuesArray[i].unsafeValues;
  106. //do not remove the dictionaries of entities per type created so far, they will be reused
  107. for (int j = 0; j < safeDictionariesCount; ++j)
  108. {
  109. //clear the dictionary of entities create do far (it won't allocate though)
  110. safeDictionaries[j].Dispose();
  111. }
  112. }
  113. }
  114. {
  115. var currentValuesArray = current.unsafeValues;
  116. for (int i = 0; i < current.count; ++i)
  117. {
  118. var safeDictionariesCount = currentValuesArray[i].count;
  119. var safeDictionaries = currentValuesArray[i].unsafeValues;
  120. //do not remove the dictionaries of entities per type created so far, they will be reused
  121. for (int j = 0; j < safeDictionariesCount; ++j)
  122. {
  123. //clear the dictionary of entities create do far (it won't allocate though)
  124. safeDictionaries[j].Dispose();
  125. }
  126. }
  127. }
  128. }
  129. }
  130. }
  131. }