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.NativeOperation.cs 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #if UNITY_NATIVE
  2. using System;
  3. using DBC.ECS;
  4. using Svelto.Common;
  5. using Svelto.DataStructures;
  6. using Svelto.ECS.DataStructures;
  7. using Svelto.ECS.Internal;
  8. namespace Svelto.ECS
  9. {
  10. public partial class EnginesRoot
  11. {
  12. //todo: I very likely don't need to create one for each native entity factory, the same can be reused
  13. readonly AtomicNativeBags _nativeAddOperationQueue = new AtomicNativeBags(Common.Allocator.Persistent);
  14. readonly AtomicNativeBags _nativeRemoveOperationQueue = new AtomicNativeBags(Common.Allocator.Persistent);
  15. readonly AtomicNativeBags _nativeSwapOperationQueue = new AtomicNativeBags(Common.Allocator.Persistent);
  16. NativeEntityRemove ProvideNativeEntityRemoveQueue<T>(string memberName) where T : IEntityDescriptor, new()
  17. {
  18. //DBC.ECS.Check.Require(EntityDescriptorTemplate<T>.descriptor.IsUnmanaged(), "can't remove entities with not native types");
  19. //todo: remove operation array and store entity descriptor hash in the return value
  20. //todo I maybe able to provide a _nativeSwap.SwapEntity<entityDescriptor>
  21. _nativeRemoveOperations.Add(new NativeOperationRemove(
  22. EntityDescriptorTemplate<T>.descriptor.componentsToBuild, TypeCache<T>.type
  23. , memberName));
  24. return new NativeEntityRemove(_nativeRemoveOperationQueue, _nativeRemoveOperations.count - 1);
  25. }
  26. NativeEntitySwap ProvideNativeEntitySwapQueue<T>(string memberName) where T : IEntityDescriptor, new()
  27. {
  28. // DBC.ECS.Check.Require(EntityDescriptorTemplate<T>.descriptor.IsUnmanaged(), "can't swap entities with not native types");
  29. //todo: remove operation array and store entity descriptor hash in the return value
  30. _nativeSwapOperations.Add(new NativeOperationSwap(EntityDescriptorTemplate<T>.descriptor.componentsToBuild
  31. , TypeCache<T>.type, memberName));
  32. return new NativeEntitySwap(_nativeSwapOperationQueue, _nativeSwapOperations.count - 1);
  33. }
  34. NativeEntityFactory ProvideNativeEntityFactoryQueue<T>(string memberName) where T : IEntityDescriptor, new()
  35. {
  36. DBC.ECS.Check.Require(EntityDescriptorTemplate<T>.descriptor.IsUnmanaged(), "can't build entities with not native types");
  37. //todo: remove operation array and store entity descriptor hash in the return value
  38. _nativeAddOperations.Add(
  39. new NativeOperationBuild(EntityDescriptorTemplate<T>.descriptor.componentsToBuild, TypeCache<T>.type, memberName));
  40. return new NativeEntityFactory(_nativeAddOperationQueue, _nativeAddOperations.count - 1);
  41. }
  42. void NativeOperationSubmission(in PlatformProfiler profiler)
  43. {
  44. using (profiler.Sample("Native Remove/Swap Operations"))
  45. {
  46. var removeBuffersCount = _nativeRemoveOperationQueue.count;
  47. for (int i = 0; i < removeBuffersCount; i++)
  48. {
  49. ref var buffer = ref _nativeRemoveOperationQueue.GetBuffer(i);
  50. while (buffer.IsEmpty() == false)
  51. {
  52. var componentsIndex = buffer.Dequeue<uint>();
  53. var entityEGID = buffer.Dequeue<EGID>();
  54. NativeOperationRemove nativeRemoveOperation = _nativeRemoveOperations[componentsIndex];
  55. CheckRemoveEntityID(entityEGID, nativeRemoveOperation.entityDescriptorType
  56. , nativeRemoveOperation.caller);
  57. QueueEntitySubmitOperation(new EntitySubmitOperation(
  58. EntitySubmitOperationType.Remove, entityEGID, entityEGID
  59. , nativeRemoveOperation.components));
  60. }
  61. }
  62. var swapBuffersCount = _nativeSwapOperationQueue.count;
  63. for (int i = 0; i < swapBuffersCount; i++)
  64. {
  65. ref var buffer = ref _nativeSwapOperationQueue.GetBuffer(i);
  66. while (buffer.IsEmpty() == false)
  67. {
  68. var componentsIndex = buffer.Dequeue<uint>();
  69. var entityEGID = buffer.Dequeue<DoubleEGID>();
  70. var componentBuilders = _nativeSwapOperations[componentsIndex].components;
  71. CheckRemoveEntityID(entityEGID.@from
  72. , _nativeSwapOperations[componentsIndex].entityDescriptorType
  73. , _nativeSwapOperations[componentsIndex].caller);
  74. CheckAddEntityID(entityEGID.to, _nativeSwapOperations[componentsIndex].entityDescriptorType
  75. , _nativeSwapOperations[componentsIndex].caller);
  76. QueueEntitySubmitOperation(new EntitySubmitOperation(
  77. EntitySubmitOperationType.Swap, entityEGID.@from, entityEGID.to
  78. , componentBuilders));
  79. }
  80. }
  81. }
  82. using (profiler.Sample("Native Add Operations"))
  83. {
  84. var addBuffersCount = _nativeAddOperationQueue.count;
  85. for (int i = 0; i < addBuffersCount; i++)
  86. {
  87. ref var buffer = ref _nativeAddOperationQueue.GetBuffer(i);
  88. while (buffer.IsEmpty() == false)
  89. {
  90. var componentsIndex = buffer.Dequeue<uint>();
  91. var egid = buffer.Dequeue<EGID>();
  92. var componentCounts = buffer.Dequeue<uint>();
  93. var componentBuilders = _nativeAddOperations[componentsIndex].components;
  94. var entityDescriptorType = _nativeAddOperations[componentsIndex].entityDescriptorType;
  95. CheckAddEntityID(egid, entityDescriptorType, _nativeAddOperations[componentsIndex].caller);
  96. Check.Require(egid.groupID != 0, "invalid group detected, are you using new ExclusiveGroupStruct() instead of new ExclusiveGroup()?");
  97. var dic = EntityFactory.BuildGroupedEntities(egid, _groupedEntityToAdd, componentBuilders
  98. , null, entityDescriptorType);
  99. var init = new EntityInitializer(egid, dic);
  100. //only called if Init is called on the initialized (there is something to init)
  101. while (componentCounts > 0)
  102. {
  103. componentCounts--;
  104. var typeID = buffer.Dequeue<uint>();
  105. IFiller entityBuilder = EntityComponentIDMap.GetTypeFromID(typeID);
  106. //after the typeID, I expect the serialized component
  107. entityBuilder.FillFromByteArray(init, buffer);
  108. }
  109. }
  110. }
  111. }
  112. }
  113. void AllocateNativeOperations()
  114. {
  115. _nativeRemoveOperations = new FasterList<NativeOperationRemove>();
  116. _nativeSwapOperations = new FasterList<NativeOperationSwap>();
  117. _nativeAddOperations = new FasterList<NativeOperationBuild>();
  118. }
  119. FasterList<NativeOperationRemove> _nativeRemoveOperations;
  120. FasterList<NativeOperationSwap> _nativeSwapOperations;
  121. FasterList<NativeOperationBuild> _nativeAddOperations;
  122. }
  123. readonly struct DoubleEGID
  124. {
  125. internal readonly EGID from;
  126. internal readonly EGID to;
  127. public DoubleEGID(EGID from1, EGID to1)
  128. {
  129. from = from1;
  130. to = to1;
  131. }
  132. }
  133. readonly struct NativeOperationBuild
  134. {
  135. internal readonly IComponentBuilder[] components;
  136. internal readonly Type entityDescriptorType;
  137. internal readonly string caller;
  138. public NativeOperationBuild
  139. (IComponentBuilder[] descriptorComponentsToBuild, Type entityDescriptorType, string caller)
  140. {
  141. this.entityDescriptorType = entityDescriptorType;
  142. components = descriptorComponentsToBuild;
  143. this.caller = caller;
  144. }
  145. }
  146. readonly struct NativeOperationRemove
  147. {
  148. internal readonly IComponentBuilder[] components;
  149. internal readonly Type entityDescriptorType;
  150. internal readonly string caller;
  151. public NativeOperationRemove
  152. (IComponentBuilder[] descriptorComponentsToRemove, Type entityDescriptorType, string caller)
  153. {
  154. this.caller = caller;
  155. components = descriptorComponentsToRemove;
  156. this.entityDescriptorType = entityDescriptorType;
  157. }
  158. }
  159. readonly struct NativeOperationSwap
  160. {
  161. internal readonly IComponentBuilder[] components;
  162. internal readonly Type entityDescriptorType;
  163. internal readonly string caller;
  164. public NativeOperationSwap
  165. (IComponentBuilder[] descriptorComponentsToSwap, Type entityDescriptorType, string caller)
  166. {
  167. this.caller = caller;
  168. components = descriptorComponentsToSwap;
  169. this.entityDescriptorType = entityDescriptorType;
  170. }
  171. }
  172. }
  173. #endif