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 8.5KB

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