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.

306 lines
11KB

  1. #if UNITY_ECS
  2. using System.Runtime.CompilerServices;
  3. using Svelto.DataStructures;
  4. using Svelto.ECS.Internal;
  5. using Unity.Burst;
  6. using Unity.Collections;
  7. using Unity.Collections.LowLevel.Unsafe;
  8. using Unity.Entities;
  9. using Unity.Jobs;
  10. namespace Svelto.ECS.SveltoOnDOTS
  11. {
  12. public readonly struct DOTSOperationsForSvelto
  13. {
  14. internal unsafe DOTSOperationsForSvelto(EntityManager manager, JobHandle* jobHandle)
  15. {
  16. _EManager = manager;
  17. _jobHandle = jobHandle;
  18. }
  19. public EntityArchetype CreateArchetype(params ComponentType[] types)
  20. {
  21. return _EManager.CreateArchetype(types);
  22. }
  23. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  24. public void SetComponent<T>(Entity e, in T component)
  25. where T : unmanaged, IComponentData
  26. {
  27. _EManager.SetComponentData(e, component);
  28. }
  29. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  30. public void SetSharedComponent<T>(Entity e, in T component)
  31. where T : unmanaged, ISharedComponentData
  32. {
  33. #if UNITY_ECS_100
  34. _EManager.SetSharedComponent(e, component);
  35. #else
  36. _EManager.SetSharedComponentData(e, component);
  37. #endif
  38. }
  39. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  40. public Entity CreateDOTSEntityOnSvelto(Entity prefabEntity, EGID egid)
  41. {
  42. Entity dotsEntity = _EManager.Instantiate(prefabEntity);
  43. //SharedComponentData can be used to group the DOTS ECS entities exactly like the Svelto ones
  44. #if UNITY_ECS_100
  45. _EManager.AddSharedComponent(dotsEntity, new DOTSSveltoGroupID(egid.groupID));
  46. #else
  47. _EManager.AddSharedComponentData(dotsEntity, new DOTSSveltoGroupID(egid.groupID));
  48. #endif
  49. _EManager.AddComponent<DOTSSveltoEGID>(dotsEntity);
  50. _EManager.SetComponentData(dotsEntity, new DOTSSveltoEGID(egid));
  51. return dotsEntity;
  52. }
  53. /// <summary>
  54. /// This method assumes that the Svelto entity with EGID egid has also dotsEntityComponent
  55. /// among the descriptors
  56. /// </summary>
  57. /// <param name="archetype"></param>
  58. /// <param name="egid"></param>
  59. /// <returns></returns>
  60. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  61. public Entity CreateDOTSEntityOnSvelto(EntityArchetype archetype, EGID egid)
  62. {
  63. Entity dotsEntity = _EManager.CreateEntity(archetype);
  64. //SharedComponentData can be used to group the DOTS ECS entities exactly like the Svelto ones
  65. #if UNITY_ECS_100
  66. _EManager.AddSharedComponent(dotsEntity, new DOTSSveltoGroupID(egid.groupID));
  67. #else
  68. _EManager.AddSharedComponentData(dotsEntity, new DOTSSveltoGroupID(egid.groupID));
  69. #endif
  70. _EManager.AddComponent<DOTSSveltoEGID>(dotsEntity);
  71. _EManager.SetComponentData(dotsEntity, new DOTSSveltoEGID(egid));
  72. return dotsEntity;
  73. }
  74. /// <summary>
  75. /// in this case the user decided to create a DOTS entity that is self managed and not managed
  76. /// by the framework
  77. /// </summary>
  78. /// <param name="archetype"></param>
  79. /// <param name="wireEgid"></param>
  80. /// <returns></returns>
  81. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  82. public Entity CreateDOTSEntity(EntityArchetype archetype)
  83. {
  84. return _EManager.CreateEntity(archetype);
  85. }
  86. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  87. public void DestroyEntity(Entity e)
  88. {
  89. _EManager.DestroyEntity(e);
  90. }
  91. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  92. public void RemoveComponent<T>(Entity dotsEntity)
  93. {
  94. _EManager.RemoveComponent<T>(dotsEntity);
  95. }
  96. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  97. public void AddComponent<T>(Entity dotsEntity)
  98. where T : unmanaged, IComponentData
  99. {
  100. _EManager.AddComponent<T>(dotsEntity);
  101. }
  102. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  103. public void AddComponent<T>(Entity dotsEntity, in T component)
  104. where T : unmanaged, IComponentData
  105. {
  106. _EManager.AddComponent<T>(dotsEntity);
  107. _EManager.SetComponentData(dotsEntity, component);
  108. }
  109. public T GetComponent<T>(Entity dotsEntity) where T : unmanaged, IComponentData
  110. {
  111. #if UNITY_ECS_100
  112. return _EManager.GetComponentData<T>(dotsEntity);
  113. #else
  114. return _EManager.GetComponentData<T>(dotsEntity);
  115. #endif
  116. }
  117. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  118. public void AddSharedComponent<T>(Entity dotsEntity, in T component)
  119. where T : unmanaged, ISharedComponentData
  120. {
  121. #if UNITY_ECS_100
  122. _EManager.AddSharedComponent(dotsEntity, component);
  123. #else
  124. _EManager.AddSharedComponentData(dotsEntity, component);
  125. #endif
  126. }
  127. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  128. public void AddBuffer<T>(Entity dotsEntity)
  129. where T : unmanaged, IBufferElementData
  130. {
  131. _EManager.AddBuffer<T>(dotsEntity);
  132. }
  133. #if !(DEBUG && !PROFILE_SVELTO)
  134. [System.Diagnostics.Conditional("NO_SENSE")]
  135. #endif
  136. public void SetDebugName(Entity dotsEntity, string name)
  137. {
  138. _EManager.SetName(dotsEntity, name);
  139. }
  140. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  141. public void SetSharedComponentBatched<SharedComponentData>(NativeArray<Entity> nativeArray, SharedComponentData SCD)
  142. where SharedComponentData : unmanaged, ISharedComponentData
  143. {
  144. #if UNITY_ECS_100
  145. _EManager.SetSharedComponent(nativeArray, SCD);
  146. #else
  147. for (int i = 0; i < nativeArray.Length; i++)
  148. {
  149. _EManager.SetSharedComponentData(nativeArray[i], SCD);
  150. }
  151. #endif
  152. }
  153. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  154. public void AddComponentBatched<T>(NativeArray<Entity> DOTSEntities)
  155. {
  156. _EManager.AddComponent<T>(DOTSEntities);
  157. }
  158. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  159. NativeArray<Entity> CreateDOTSEntityFromSveltoBatched(Entity prefab, (uint rangeStart, uint rangeEnd) range,
  160. ExclusiveGroupStruct groupID, NB<DOTSEntityComponent> DOSTEntityComponents)
  161. {
  162. unsafe
  163. {
  164. _jobHandle->Complete();
  165. var count = (int)(range.rangeEnd - range.rangeStart);
  166. var nativeArray = _EManager.Instantiate(prefab, count, _EManager.World.UpdateAllocator.ToAllocator);
  167. #if UNITY_ECS_100
  168. _EManager.AddSharedComponent(nativeArray, new DOTSSveltoGroupID(groupID));
  169. #else
  170. for (int i = 0; i < nativeArray.Length; i++)
  171. {
  172. _EManager.AddSharedComponentData(nativeArray[i], new DOTSSveltoGroupID(groupID));
  173. }
  174. #endif
  175. //Set Svelto DOTSEntityComponent dotsEntity field to the DOTS entity
  176. //Svelto entities track the DOTS entities through this component
  177. var setDOTSEntityComponentsJob = new SetDOTSEntityComponents
  178. {
  179. sveltoStartIndex = range.rangeStart,
  180. createdEntities = nativeArray,
  181. DOSTEntityComponents = DOSTEntityComponents
  182. };
  183. *_jobHandle = JobHandle.CombineDependencies(*_jobHandle, setDOTSEntityComponentsJob.ScheduleParallel(count, default));
  184. return nativeArray;
  185. }
  186. }
  187. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  188. public NativeArray<Entity> CreateDOTSEntityFromSveltoBatched(Entity prefab, (uint rangeStart, uint rangeEnd) range,
  189. ExclusiveGroupStruct groupID, NB<DOTSEntityComponent> DOSTEntityComponents, NativeEntityIDs sveltoIds, out JobHandle creationJob)
  190. {
  191. var nativeArray = CreateDOTSEntityFromSveltoBatched(prefab, range, groupID, DOSTEntityComponents);
  192. unsafe
  193. {
  194. var count = (int)(range.rangeEnd - range.rangeStart);
  195. //DOTS entities track Svelto entities through this component
  196. _EManager.AddComponent<DOTSSveltoEGID>(nativeArray);
  197. //set the DOTSSveltoEGID values
  198. var setDOTSSveltoEGIDJob = new SetDOTSSveltoEGID
  199. {
  200. sveltoStartIndex = range.rangeStart,
  201. createdEntities = nativeArray,
  202. entityManager = _EManager,
  203. ids = sveltoIds,
  204. groupID = groupID
  205. };
  206. creationJob = *_jobHandle = JobHandle.CombineDependencies(*_jobHandle, setDOTSSveltoEGIDJob.ScheduleParallel(count, default));
  207. return nativeArray;
  208. }
  209. }
  210. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  211. public void AddJobToComplete(JobHandle jobHandle)
  212. {
  213. unsafe
  214. {
  215. *_jobHandle = JobHandle.CombineDependencies(*_jobHandle, jobHandle);
  216. }
  217. }
  218. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  219. public void DestroyEntitiesBatched(NativeArray<Entity> nativeArray)
  220. {
  221. _EManager.DestroyEntity(nativeArray);
  222. }
  223. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  224. public void Complete()
  225. {
  226. unsafe
  227. {
  228. _jobHandle->Complete();
  229. }
  230. }
  231. [BurstCompile]
  232. struct SetDOTSEntityComponents: IJobParallelFor
  233. {
  234. public uint sveltoStartIndex;
  235. [ReadOnly] public NativeArray<Entity> createdEntities;
  236. public NB<DOTSEntityComponent> DOSTEntityComponents;
  237. public void Execute(int currentIndex)
  238. {
  239. int index = (int)(sveltoStartIndex + currentIndex);
  240. var dotsEntity = createdEntities[currentIndex];
  241. DOSTEntityComponents[index].dotsEntity = dotsEntity;
  242. }
  243. }
  244. [BurstCompile]
  245. public struct SetDOTSSveltoEGID: IJobParallelFor
  246. {
  247. public uint sveltoStartIndex;
  248. [ReadOnly] public NativeArray<Entity> createdEntities;
  249. [NativeDisableParallelForRestriction] public EntityManager entityManager;
  250. public NativeEntityIDs ids;
  251. public ExclusiveGroupStruct groupID;
  252. public void Execute(int currentIndex)
  253. {
  254. int index = (int)(sveltoStartIndex + currentIndex);
  255. var dotsEntity = createdEntities[currentIndex];
  256. entityManager.SetComponentData(
  257. dotsEntity, new DOTSSveltoEGID
  258. {
  259. egid = new EGID(ids[index], groupID)
  260. });
  261. }
  262. }
  263. readonly EntityManager _EManager;
  264. [NativeDisableUnsafePtrRestriction] readonly unsafe JobHandle* _jobHandle;
  265. }
  266. }
  267. #endif