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.

216 lines
10KB

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