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.

186 lines
8.0KB

  1. #if UNITY_NATIVE
  2. using System;
  3. using Svelto.Common;
  4. using Svelto.DataStructures;
  5. using Svelto.ECS.DataStructures;
  6. namespace Svelto.ECS
  7. {
  8. public partial class EnginesRoot
  9. {
  10. //todo: I very likely don't need to create one for each native entity factory, the same can be reused
  11. readonly AtomicNativeBags _addOperationQueue =
  12. new AtomicNativeBags(Common.Allocator.Persistent);
  13. readonly AtomicNativeBags _removeOperationQueue =
  14. new AtomicNativeBags(Common.Allocator.Persistent);
  15. readonly AtomicNativeBags _swapOperationQueue =
  16. new AtomicNativeBags(Common.Allocator.Persistent);
  17. NativeEntityRemove ProvideNativeEntityRemoveQueue<T>(string memberName) where T : IEntityDescriptor, new()
  18. {
  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(
  22. new NativeOperationRemove(EntityDescriptorTemplate<T>.descriptor.componentsToBuild, TypeCache<T>.type, memberName));
  23. return new NativeEntityRemove(_removeOperationQueue, _nativeRemoveOperations.count - 1);
  24. }
  25. NativeEntitySwap ProvideNativeEntitySwapQueue<T>(string memberName) where T : IEntityDescriptor, new()
  26. {
  27. //todo: remove operation array and store entity descriptor hash in the return value
  28. _nativeSwapOperations.Add(
  29. new NativeOperationSwap(EntityDescriptorTemplate<T>.descriptor.componentsToBuild, TypeCache<T>.type, memberName));
  30. return new NativeEntitySwap(_swapOperationQueue, _nativeSwapOperations.count - 1);
  31. }
  32. NativeEntityFactory ProvideNativeEntityFactoryQueue<T>(string memberName) where T : IEntityDescriptor, new()
  33. {
  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));
  37. return new NativeEntityFactory(_addOperationQueue, _nativeAddOperations.count - 1);
  38. }
  39. void NativeOperationSubmission(in PlatformProfiler profiler)
  40. {
  41. using (profiler.Sample("Native Remove/Swap Operations"))
  42. {
  43. for (int i = 0; i < _removeOperationQueue.count; i++)
  44. {
  45. ref var buffer = ref _removeOperationQueue.GetBuffer(i);
  46. while (buffer.IsEmpty() == false)
  47. {
  48. var componentsIndex = buffer.Dequeue<uint>();
  49. var entityEGID = buffer.Dequeue<EGID>();
  50. var nativeRemoveOperation = _nativeRemoveOperations[componentsIndex];
  51. CheckRemoveEntityID(entityEGID, nativeRemoveOperation.entityDescriptorType);
  52. QueueEntitySubmitOperation(new EntitySubmitOperation(
  53. EntitySubmitOperationType.Remove, entityEGID, entityEGID
  54. , nativeRemoveOperation.components));
  55. }
  56. }
  57. for (int i = 0; i < _swapOperationQueue.count; i++)
  58. {
  59. ref var buffer = ref _swapOperationQueue.GetBuffer(i);
  60. while (buffer.IsEmpty() == false)
  61. {
  62. var componentsIndex = buffer.Dequeue<uint>();
  63. var entityEGID = buffer.Dequeue<DoubleEGID>();
  64. var componentBuilders = _nativeSwapOperations[componentsIndex].components;
  65. CheckRemoveEntityID(entityEGID.@from, _nativeSwapOperations[componentsIndex].entityDescriptorType, _nativeSwapOperations[componentsIndex].caller );
  66. CheckAddEntityID(entityEGID.to, _nativeSwapOperations[componentsIndex].entityDescriptorType, _nativeSwapOperations[componentsIndex].caller);
  67. QueueEntitySubmitOperation(new EntitySubmitOperation(
  68. EntitySubmitOperationType.Swap, entityEGID.@from, entityEGID.to
  69. , componentBuilders));
  70. }
  71. }
  72. }
  73. using (profiler.Sample("Native Add Operations"))
  74. {
  75. for (int i = 0; i < _addOperationQueue.count; i++)
  76. {
  77. ref var buffer = ref _addOperationQueue.GetBuffer(i);
  78. while (buffer.IsEmpty() == false)
  79. {
  80. var componentsIndex = buffer.Dequeue<uint>();
  81. var egid = buffer.Dequeue<EGID>();
  82. var componentCounts = buffer.Dequeue<uint>();
  83. EntityComponentInitializer init =
  84. BuildEntity(egid, _nativeAddOperations[componentsIndex].components, _nativeAddOperations[componentsIndex].entityDescriptorType);
  85. //only called if Init is called on the initialized (there is something to init)
  86. while (componentCounts > 0)
  87. {
  88. componentCounts--;
  89. var typeID = buffer.Dequeue<uint>();
  90. IFiller entityBuilder = EntityComponentIDMap.GetTypeFromID(typeID);
  91. //after the typeID, I expect the serialized component
  92. entityBuilder.FillFromByteArray(init, buffer);
  93. }
  94. }
  95. }
  96. }
  97. }
  98. void AllocateNativeOperations()
  99. {
  100. _nativeRemoveOperations = new FasterList<NativeOperationRemove>();
  101. _nativeSwapOperations = new FasterList<NativeOperationSwap>();
  102. _nativeAddOperations = new FasterList<NativeOperationBuild>();
  103. }
  104. FasterList<NativeOperationRemove> _nativeRemoveOperations;
  105. FasterList<NativeOperationSwap> _nativeSwapOperations;
  106. FasterList<NativeOperationBuild> _nativeAddOperations;
  107. }
  108. readonly struct DoubleEGID
  109. {
  110. internal readonly EGID from;
  111. internal readonly EGID to;
  112. public DoubleEGID(EGID from1, EGID to1)
  113. {
  114. from = from1;
  115. to = to1;
  116. }
  117. }
  118. readonly struct NativeOperationBuild
  119. {
  120. internal readonly IComponentBuilder[] components;
  121. internal readonly Type entityDescriptorType;
  122. public NativeOperationBuild(IComponentBuilder[] descriptorComponentsToBuild, Type entityDescriptorType)
  123. {
  124. this.entityDescriptorType = entityDescriptorType;
  125. components = descriptorComponentsToBuild;
  126. }
  127. }
  128. readonly struct NativeOperationRemove
  129. {
  130. internal readonly IComponentBuilder[] components;
  131. internal readonly Type entityDescriptorType;
  132. internal readonly string caller;
  133. public NativeOperationRemove(IComponentBuilder[] descriptorComponentsToRemove, Type entityDescriptorType, string caller)
  134. {
  135. this.caller = caller;
  136. components = descriptorComponentsToRemove;
  137. this.entityDescriptorType = entityDescriptorType;
  138. }
  139. }
  140. readonly struct NativeOperationSwap
  141. {
  142. internal readonly IComponentBuilder[] components;
  143. internal readonly Type entityDescriptorType;
  144. internal readonly string caller;
  145. public NativeOperationSwap(IComponentBuilder[] descriptorComponentsToSwap, Type entityDescriptorType, string caller)
  146. {
  147. this.caller = caller;
  148. components = descriptorComponentsToSwap;
  149. this.entityDescriptorType = entityDescriptorType;
  150. }
  151. }
  152. }
  153. #endif