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.

254 lines
12KB

  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using Svelto.DataStructures;
  4. using Svelto.Utilities;
  5. namespace Svelto.ECS
  6. {
  7. class EntitiesOperations
  8. {
  9. /// <summary>
  10. /// Todo: need to go back here and add a ton of comments
  11. /// </summary>
  12. public EntitiesOperations()
  13. {
  14. _thisSubmissionInfo.Init();
  15. _lastSubmittedInfo.Init();
  16. _newGroupDictionary = NewGroupDictionary;
  17. _newGroupsDictionary = NewGroupsDictionary;
  18. _recycleDictionary = RecycleDictionary;
  19. _newList = NewList;
  20. _clearList = ClearList;
  21. _newGroupsDictionaryWithCaller = NewGroupsDictionaryWithCaller;
  22. _recycleGroupDictionaryWithCaller = RecycleGroupDictionaryWithCaller;
  23. _recycleDicitionaryWithCaller = RecycleDicitionaryWithCaller;
  24. _newListWithCaller = NewListWithCaller;
  25. _clearListWithCaller = ClearListWithCaller;
  26. }
  27. public void QueueRemoveGroupOperation(ExclusiveBuildGroup groupID, string caller)
  28. {
  29. _thisSubmissionInfo._groupsToRemove.Add((groupID, caller));
  30. }
  31. public void QueueRemoveOperation(EGID entityEgid, IComponentBuilder[] componentBuilders, string caller)
  32. {
  33. _thisSubmissionInfo._entitiesRemoved.Add(entityEgid);
  34. //todo: limit the number of dictionaries that can be cached
  35. //recycle or create dictionaries of components per group
  36. var removedComponentsPerType = _thisSubmissionInfo._currentRemoveEntitiesOperations.RecycleOrAdd(
  37. entityEgid.groupID, _newGroupsDictionary, _recycleDictionary);
  38. foreach (var operation in componentBuilders)
  39. {
  40. removedComponentsPerType //recycle or create dictionaries per component type
  41. .RecycleOrAdd(operation.getComponentID, _newList, _clearList)
  42. //add entity to remove
  43. .Add((entityEgid.entityID, caller));
  44. }
  45. }
  46. public void QueueSwapGroupOperation(ExclusiveBuildGroup fromGroupID, ExclusiveBuildGroup toGroupID, string caller)
  47. {
  48. _thisSubmissionInfo._groupsToSwap.Add((fromGroupID, toGroupID, caller));
  49. }
  50. public void QueueSwapOperation(EGID fromID, EGID toID, IComponentBuilder[] componentBuilders, string caller)
  51. {
  52. _thisSubmissionInfo._entitiesSwapped.Add((fromID, toID));
  53. //todo: limit the number of dictionaries that can be cached
  54. //recycle or create dictionaries of components per group
  55. //Get the dictionary that holds the entities that are swapping from fromID
  56. var swappedComponentsPerType = _thisSubmissionInfo._currentSwapEntitiesOperations.RecycleOrAdd(
  57. fromID.groupID, _newGroupsDictionaryWithCaller, _recycleGroupDictionaryWithCaller);
  58. var componentBuildersLength = componentBuilders.Length - 1;
  59. for (var index = componentBuildersLength; index >= 0; index--)
  60. {
  61. var operation = componentBuilders[index];
  62. //Get the dictionary for each component that holds the list of entities to swap
  63. swappedComponentsPerType //recycle or create dictionaries per component type
  64. .RecycleOrAdd(operation.getComponentID, _newGroupDictionary, _recycleDicitionaryWithCaller)
  65. //recycle or create list of entities to swap
  66. .RecycleOrAdd(toID.groupID, _newListWithCaller, _clearListWithCaller)
  67. //add entity to swap
  68. .Add((fromID.entityID, toID.entityID, caller));
  69. }
  70. }
  71. [MethodImpl(MethodImplOptions.Synchronized)]
  72. public bool AnyOperationQueued()
  73. {
  74. return _thisSubmissionInfo.AnyOperationQueued();
  75. }
  76. public void ExecuteRemoveAndSwappingOperations(Action<FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID,
  77. FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>>, FasterList<(EGID, EGID)>,
  78. EnginesRoot> swapEntities, Action<FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID, FasterList<(uint, string)>>>,
  79. FasterList<EGID>, EnginesRoot> removeEntities, Action<ExclusiveGroupStruct, EnginesRoot> removeGroup,
  80. Action<ExclusiveGroupStruct, ExclusiveGroupStruct, EnginesRoot> swapGroup, EnginesRoot enginesRoot)
  81. {
  82. (_thisSubmissionInfo, _lastSubmittedInfo) = (_lastSubmittedInfo, _thisSubmissionInfo);
  83. /// todo: entity references should be updated before calling all the methods to avoid callbacks handling
  84. /// references that should be marked as invalid.
  85. foreach (var (group, caller) in _lastSubmittedInfo._groupsToRemove)
  86. try
  87. {
  88. removeGroup(group, enginesRoot);
  89. }
  90. catch
  91. {
  92. var str = "Crash while removing a whole group on ".FastConcat(group.ToString())
  93. .FastConcat(" from : ", caller);
  94. Console.LogError(str);
  95. throw;
  96. }
  97. foreach (var (fromGroup, toGroup, caller) in _lastSubmittedInfo._groupsToSwap)
  98. try
  99. {
  100. swapGroup(fromGroup, toGroup, enginesRoot);
  101. }
  102. catch
  103. {
  104. var str = "Crash while swapping a whole group on "
  105. .FastConcat(fromGroup.ToString(), " ", toGroup.ToString()).FastConcat(" from : ", caller);
  106. Console.LogError(str);
  107. throw;
  108. }
  109. if (_lastSubmittedInfo._entitiesSwapped.count > 0)
  110. swapEntities(_lastSubmittedInfo._currentSwapEntitiesOperations, _lastSubmittedInfo._entitiesSwapped
  111. , enginesRoot);
  112. if (_lastSubmittedInfo._entitiesRemoved.count > 0)
  113. removeEntities(_lastSubmittedInfo._currentRemoveEntitiesOperations, _lastSubmittedInfo._entitiesRemoved
  114. , enginesRoot);
  115. _lastSubmittedInfo.Clear();
  116. }
  117. FasterDictionary<ComponentID, FasterList<(uint, string)>> NewGroupsDictionary()
  118. {
  119. return new FasterDictionary<ComponentID, FasterList<(uint, string)>>();
  120. }
  121. void RecycleDictionary(ref FasterDictionary<ComponentID, FasterList<(uint, string)>> recycled)
  122. {
  123. recycled.Recycle();
  124. }
  125. FasterList<(uint, string)> NewList()
  126. {
  127. return new FasterList<(uint, string)>();
  128. }
  129. void ClearList(ref FasterList<(uint, string)> target)
  130. {
  131. target.Clear();
  132. }
  133. void RecycleDicitionaryWithCaller(ref FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>> target)
  134. {
  135. target.Recycle();
  136. }
  137. void ClearListWithCaller(ref FasterList<(uint, uint, string)> target)
  138. {
  139. target.Clear();
  140. }
  141. FasterList<(uint, uint, string)> NewListWithCaller()
  142. {
  143. return new FasterList<(uint, uint, string)>();
  144. }
  145. FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>> NewGroupsDictionaryWithCaller()
  146. {
  147. return new FasterDictionary<ComponentID, //add case
  148. FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>();
  149. }
  150. void RecycleGroupDictionaryWithCaller(ref FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>> recycled)
  151. {
  152. recycled.Recycle();
  153. }
  154. FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>> NewGroupDictionary()
  155. {
  156. return new FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>();
  157. }
  158. struct Info
  159. {
  160. //from group //actual component type
  161. internal FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID,
  162. // to group ID //entityIDs , debugInfo
  163. FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>>
  164. _currentSwapEntitiesOperations;
  165. internal FasterDictionary<ExclusiveGroupStruct,
  166. FasterDictionary<ComponentID, FasterList<(uint, string)>>> _currentRemoveEntitiesOperations;
  167. internal FasterList<(EGID, EGID)> _entitiesSwapped;
  168. internal FasterList<EGID> _entitiesRemoved;
  169. public FasterList<(ExclusiveBuildGroup, ExclusiveBuildGroup, string)> _groupsToSwap;
  170. public FasterList<(ExclusiveBuildGroup, string)> _groupsToRemove;
  171. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  172. internal bool AnyOperationQueued()
  173. {
  174. return _entitiesSwapped.count > 0 || _entitiesRemoved.count > 0 || _groupsToSwap.count > 0
  175. || _groupsToRemove.count > 0;
  176. }
  177. internal void Clear()
  178. {
  179. _currentSwapEntitiesOperations.Recycle();
  180. _currentRemoveEntitiesOperations.Recycle();
  181. _entitiesSwapped.Clear();
  182. _entitiesRemoved.Clear();
  183. _groupsToRemove.Clear();
  184. _groupsToSwap.Clear();
  185. }
  186. internal void Init()
  187. {
  188. _entitiesSwapped = new FasterList<(EGID, EGID)>();
  189. _entitiesRemoved = new FasterList<EGID>();
  190. _groupsToRemove = new FasterList<(ExclusiveBuildGroup, string)>();
  191. _groupsToSwap = new FasterList<(ExclusiveBuildGroup, ExclusiveBuildGroup, string)>();
  192. _currentSwapEntitiesOperations =
  193. new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<ComponentID,
  194. FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>>();
  195. _currentRemoveEntitiesOperations =
  196. new FasterDictionary<ExclusiveGroupStruct,
  197. FasterDictionary<ComponentID, FasterList<(uint, string)>>>();
  198. }
  199. }
  200. Info _lastSubmittedInfo;
  201. Info _thisSubmissionInfo;
  202. readonly Func<FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>> _newGroupDictionary;
  203. readonly Func<FasterDictionary<ComponentID, FasterList<(uint, string)>>> _newGroupsDictionary;
  204. readonly ActionRef<FasterDictionary<ComponentID, FasterList<(uint, string)>>> _recycleDictionary;
  205. readonly Func<FasterList<(uint, string)>> _newList;
  206. readonly ActionRef<FasterList<(uint, string)>> _clearList;
  207. readonly Func<FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>> _newGroupsDictionaryWithCaller;
  208. readonly ActionRef<FasterDictionary<ComponentID, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>> _recycleGroupDictionaryWithCaller;
  209. readonly ActionRef<FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>> _recycleDicitionaryWithCaller;
  210. readonly Func<FasterList<(uint, uint, string)>> _newListWithCaller;
  211. readonly ActionRef<FasterList<(uint, uint, string)>> _clearListWithCaller;
  212. }
  213. }