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.

183 lines
8.5KB

  1. using System;
  2. using Svelto.DataStructures;
  3. namespace Svelto.ECS
  4. {
  5. class EntitiesOperations
  6. {
  7. public EntitiesOperations()
  8. {
  9. _thisSubmissionInfo.Init();
  10. _lastSubmittedInfo.Init();
  11. }
  12. public void AddSwapOperation(EGID fromID, EGID toID, IComponentBuilder[] componentBuilders, string caller)
  13. {
  14. _thisSubmissionInfo._entitiesSwapped.Add((fromID, toID));
  15. //todo: limit the number of dictionaries that can be cached
  16. //recycle or create dictionaries of components per group
  17. var swappedComponentsPerType = _thisSubmissionInfo._currentSwapEntitiesOperations.RecycleOrAdd(
  18. fromID.groupID,
  19. () => new FasterDictionary<RefWrapperType,
  20. FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>(),
  21. (ref FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>> recycled) =>
  22. recycled.FastClear());
  23. foreach (IComponentBuilder operation in componentBuilders)
  24. {
  25. swappedComponentsPerType
  26. //recycle or create dictionaries per component type
  27. .RecycleOrAdd(new RefWrapperType(operation.GetEntityComponentType()),
  28. () => new FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>(),
  29. (ref FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>> target) =>
  30. target.FastClear())
  31. //recycle or create list of entities to swap
  32. .RecycleOrAdd(toID.groupID, () => new FasterList<(uint, uint, string)>(),
  33. (ref FasterList<(uint, uint, string)> target) => target.FastClear())
  34. //add entity to swap
  35. .Add((fromID.entityID, toID.entityID, caller));
  36. }
  37. }
  38. public void AddRemoveOperation(EGID entityEgid, IComponentBuilder[] componentBuilders, string caller)
  39. {
  40. _thisSubmissionInfo._entitiesRemoved.Add(entityEgid);
  41. //todo: limit the number of dictionaries that can be cached
  42. //recycle or create dictionaries of components per group
  43. var removedComponentsPerType = _thisSubmissionInfo._currentRemoveEntitiesOperations.RecycleOrAdd(
  44. entityEgid.groupID, () => new FasterDictionary<RefWrapperType, FasterList<(uint, string)>>(),
  45. (ref FasterDictionary<RefWrapperType, FasterList<(uint, string)>> recycled) => recycled.FastClear());
  46. foreach (IComponentBuilder operation in componentBuilders)
  47. {
  48. removedComponentsPerType
  49. //recycle or create dictionaries per component type
  50. .RecycleOrAdd(new RefWrapperType(operation.GetEntityComponentType()),
  51. () => new FasterList<(uint, string)>(),
  52. (ref FasterList<(uint, string)> target) => target.FastClear())
  53. //add entity to swap
  54. .Add((entityEgid.entityID, caller));
  55. }
  56. }
  57. public void AddRemoveGroupOperation(ExclusiveBuildGroup groupID, string caller)
  58. {
  59. _thisSubmissionInfo._groupsToRemove.Add((groupID, caller));
  60. }
  61. public void AddSwapGroupOperation(ExclusiveBuildGroup fromGroupID, ExclusiveBuildGroup toGroupID, string caller)
  62. {
  63. _thisSubmissionInfo._groupsToSwap.Add((fromGroupID, toGroupID, caller));
  64. }
  65. public void ExecuteRemoveAndSwappingOperations(
  66. Action<FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType,
  67. FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>>, FasterList<(EGID, EGID)>
  68. ,
  69. EnginesRoot> swapEntities,
  70. Action<FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType, FasterList<(uint, string)>>>,
  71. FasterList<EGID>, EnginesRoot> removeEntities, Action<ExclusiveGroupStruct, EnginesRoot> removeGroup,
  72. Action<ExclusiveGroupStruct, ExclusiveGroupStruct, EnginesRoot> swapGroup, EnginesRoot enginesRoot)
  73. {
  74. (_thisSubmissionInfo, _lastSubmittedInfo) = (_lastSubmittedInfo, _thisSubmissionInfo);
  75. /// todo: entity references should be updated before calling all the methods to avoid callbacks handling
  76. /// references that should be marked as invalid.
  77. foreach (var (group, caller) in _lastSubmittedInfo._groupsToRemove)
  78. {
  79. try
  80. {
  81. removeGroup(group, enginesRoot);
  82. }
  83. catch
  84. {
  85. var str = "Crash while removing a whole group on ".FastConcat(group.ToString())
  86. .FastConcat(" from : ", caller);
  87. Console.LogError(str);
  88. throw;
  89. }
  90. }
  91. foreach (var (fromGroup, toGroup, caller) in _lastSubmittedInfo._groupsToSwap)
  92. {
  93. try
  94. {
  95. swapGroup(fromGroup, toGroup, enginesRoot);
  96. }
  97. catch
  98. {
  99. var str = "Crash while swapping a whole group on "
  100. .FastConcat(fromGroup.ToString(), " ", toGroup.ToString()).FastConcat(" from : ", caller);
  101. Console.LogError(str);
  102. throw;
  103. }
  104. }
  105. if (_lastSubmittedInfo._entitiesSwapped.count > 0)
  106. swapEntities(_lastSubmittedInfo._currentSwapEntitiesOperations, _lastSubmittedInfo._entitiesSwapped,
  107. enginesRoot);
  108. if (_lastSubmittedInfo._entitiesRemoved.count > 0)
  109. removeEntities(_lastSubmittedInfo._currentRemoveEntitiesOperations, _lastSubmittedInfo._entitiesRemoved,
  110. enginesRoot);
  111. _lastSubmittedInfo.Clear();
  112. }
  113. public bool AnyOperationQueued() => _thisSubmissionInfo.AnyOperationQueued();
  114. struct Info
  115. {
  116. //from group //actual component type
  117. internal FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType,
  118. // to group ID //entityIDs , debugInfo
  119. FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>>
  120. _currentSwapEntitiesOperations;
  121. internal FasterDictionary<ExclusiveGroupStruct,
  122. FasterDictionary<RefWrapperType, FasterList<(uint, string)>>> _currentRemoveEntitiesOperations;
  123. internal FasterList<(EGID, EGID)> _entitiesSwapped;
  124. internal FasterList<EGID> _entitiesRemoved;
  125. public FasterList<(ExclusiveBuildGroup, ExclusiveBuildGroup, string)> _groupsToSwap;
  126. public FasterList<(ExclusiveBuildGroup, string)> _groupsToRemove;
  127. internal bool AnyOperationQueued() =>
  128. _entitiesSwapped.count > 0 || _entitiesRemoved.count > 0 || _groupsToSwap.count > 0 ||
  129. _groupsToRemove.count > 0;
  130. internal void Clear()
  131. {
  132. _currentSwapEntitiesOperations.FastClear();
  133. _currentRemoveEntitiesOperations.FastClear();
  134. _entitiesSwapped.FastClear();
  135. _entitiesRemoved.FastClear();
  136. _groupsToRemove.FastClear();
  137. _groupsToSwap.FastClear();
  138. }
  139. internal void Init()
  140. {
  141. _entitiesSwapped = new FasterList<(EGID, EGID)>();
  142. _entitiesRemoved = new FasterList<EGID>();
  143. _groupsToRemove = new FasterList<(ExclusiveBuildGroup, string)>();
  144. _groupsToSwap = new FasterList<(ExclusiveBuildGroup, ExclusiveBuildGroup, string)>();
  145. _currentSwapEntitiesOperations =
  146. new FasterDictionary<ExclusiveGroupStruct, FasterDictionary<RefWrapperType,
  147. FasterDictionary<ExclusiveGroupStruct, FasterList<(uint, uint, string)>>>>();
  148. _currentRemoveEntitiesOperations =
  149. new FasterDictionary<ExclusiveGroupStruct,
  150. FasterDictionary<RefWrapperType, FasterList<(uint, string)>>>();
  151. }
  152. }
  153. Info _thisSubmissionInfo;
  154. Info _lastSubmittedInfo;
  155. }
  156. }