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.

148 lines
7.0KB

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