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.

202 lines
9.3KB

  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using Svelto.Common;
  4. using Svelto.DataStructures;
  5. using Svelto.ECS.Internal;
  6. namespace Svelto.ECS
  7. {
  8. public partial class EnginesRoot
  9. {
  10. /// <summary>
  11. /// todo: EnginesRoot was a weakreference to give the change to inject
  12. /// entity functions from other engines root. It probably should be reverted
  13. /// </summary>
  14. class GenericEntityFunctions : IEntityFunctions
  15. {
  16. internal GenericEntityFunctions(EnginesRoot weakReference)
  17. {
  18. _enginesRoot = new Svelto.DataStructures.WeakReference<EnginesRoot>(weakReference);
  19. }
  20. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  21. public void RemoveEntity<T>(uint entityID, BuildGroup groupID) where T :
  22. IEntityDescriptor, new()
  23. {
  24. RemoveEntity<T>(new EGID(entityID, groupID));
  25. }
  26. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  27. public void RemoveEntity<T>(EGID entityEGID) where T : IEntityDescriptor, new()
  28. {
  29. DBC.ECS.Check.Require(entityEGID.groupID != 0, "invalid group detected");
  30. var descriptorComponentsToBuild = EntityDescriptorTemplate<T>.descriptor.componentsToBuild;
  31. _enginesRoot.Target.CheckRemoveEntityID(entityEGID, TypeCache<T>.type);
  32. _enginesRoot.Target.QueueEntitySubmitOperation<T>(
  33. new EntitySubmitOperation(EntitySubmitOperationType.Remove, entityEGID, entityEGID,
  34. descriptorComponentsToBuild));
  35. }
  36. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  37. public void RemoveEntitiesFromGroup(BuildGroup groupID)
  38. {
  39. DBC.ECS.Check.Require(groupID != 0, "invalid group detected");
  40. _enginesRoot.Target.RemoveGroupID(groupID);
  41. _enginesRoot.Target.QueueEntitySubmitOperation(
  42. new EntitySubmitOperation(EntitySubmitOperationType.RemoveGroup, new EGID(0, groupID), new EGID()));
  43. }
  44. // [MethodImpl(MethodImplOptions.AggressiveInlining)]
  45. // void RemoveAllEntities<D, S>(ExclusiveGroup group)
  46. // where D : IEntityDescriptor, new() where S : unmanaged, IEntityComponent
  47. // {
  48. // var targetEntitiesDB = _enginesRoot.Target._entitiesDB;
  49. // var (buffer, count) = targetEntitiesDB.QueryEntities<S>(@group);
  50. // for (uint i = 0; i < count; ++i)
  51. // {
  52. // RemoveEntity<D>(new EGID(i, group));
  53. // }
  54. // }
  55. //
  56. // [MethodImpl(MethodImplOptions.AggressiveInlining)]
  57. // void RemoveAllEntities<D, S>()
  58. // where D : IEntityDescriptor, new() where S : unmanaged, IEntityComponent
  59. // {
  60. // var targetEntitiesDB = _enginesRoot.Target._entitiesDB;
  61. // foreach (var ((buffer, count), exclusiveGroupStruct) in targetEntitiesDB.QueryEntities<S>())
  62. // for (uint i = 0; i < count; ++i)
  63. // {
  64. // RemoveEntity<D>(new EGID(i, exclusiveGroupStruct));
  65. // }
  66. // }
  67. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  68. public void SwapEntitiesInGroup<T>(BuildGroup fromGroupID, BuildGroup toGroupID)
  69. where T : IEntityDescriptor, new()
  70. {
  71. if (_enginesRoot.Target._groupEntityComponentsDB.TryGetValue(
  72. fromGroupID.group, out FasterDictionary<RefWrapperType, ITypeSafeDictionary> entitiesInGroupPerType)
  73. == true)
  74. {
  75. #if DEBUG && !PROFILE_SVELTO
  76. IComponentBuilder[] components = EntityDescriptorTemplate<T>.descriptor.componentsToBuild;
  77. var dictionary = entitiesInGroupPerType[new RefWrapperType(components[0].GetEntityComponentType())];
  78. dictionary.KeysEvaluator((key) =>
  79. {
  80. _enginesRoot.Target.CheckRemoveEntityID(new EGID(key, fromGroupID), TypeCache<T>.type);
  81. _enginesRoot.Target.CheckAddEntityID(new EGID(key, toGroupID), TypeCache<T>.type);
  82. });
  83. #endif
  84. _enginesRoot.Target.QueueEntitySubmitOperation(
  85. new EntitySubmitOperation(EntitySubmitOperationType.SwapGroup, new EGID(0, fromGroupID)
  86. , new EGID(0, toGroupID)));
  87. }
  88. }
  89. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  90. public void SwapEntityGroup<T>(uint entityID, BuildGroup fromGroupID,
  91. BuildGroup toGroupID)
  92. where T : IEntityDescriptor, new()
  93. {
  94. SwapEntityGroup<T>(new EGID(entityID, fromGroupID), toGroupID);
  95. }
  96. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  97. public void SwapEntityGroup<T>(EGID fromID, BuildGroup toGroupID)
  98. where T : IEntityDescriptor, new()
  99. {
  100. SwapEntityGroup<T>(fromID, new EGID(fromID.entityID, (uint) toGroupID));
  101. }
  102. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  103. public void SwapEntityGroup<T>(EGID fromID, BuildGroup toGroupID
  104. , BuildGroup mustBeFromGroup)
  105. where T : IEntityDescriptor, new()
  106. {
  107. if (fromID.groupID != mustBeFromGroup)
  108. throw new ECSException("Entity is not coming from the expected group");
  109. SwapEntityGroup<T>(fromID, toGroupID);
  110. }
  111. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  112. public void SwapEntityGroup<T>(EGID fromID, EGID toID
  113. , BuildGroup mustBeFromGroup)
  114. where T : IEntityDescriptor, new()
  115. {
  116. if (fromID.groupID != mustBeFromGroup)
  117. throw new ECSException("Entity is not coming from the expected group");
  118. SwapEntityGroup<T>(fromID, toID);
  119. }
  120. #if UNITY_NATIVE
  121. public NativeEntityRemove ToNativeRemove<T>(string memberName) where T : IEntityDescriptor, new()
  122. {
  123. return _enginesRoot.Target.ProvideNativeEntityRemoveQueue<T>(memberName);
  124. }
  125. public NativeEntitySwap ToNativeSwap<T>(string memberName) where T : IEntityDescriptor, new()
  126. {
  127. return _enginesRoot.Target.ProvideNativeEntitySwapQueue<T>(memberName);
  128. }
  129. #endif
  130. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  131. public void SwapEntityGroup<T>(EGID fromID, EGID toID)
  132. where T : IEntityDescriptor, new()
  133. {
  134. DBC.ECS.Check.Require(fromID.groupID != 0, "invalid group detected");
  135. DBC.ECS.Check.Require(toID.groupID != 0, "invalid group detected");
  136. var enginesRootTarget = _enginesRoot.Target;
  137. var descriptorComponentsToBuild = EntityDescriptorTemplate<T>.descriptor.componentsToBuild;
  138. enginesRootTarget.CheckRemoveEntityID(fromID, TypeCache<T>.type);
  139. enginesRootTarget.CheckAddEntityID(toID, TypeCache<T>.type);
  140. enginesRootTarget.QueueEntitySubmitOperation<T>(
  141. new EntitySubmitOperation(EntitySubmitOperationType.Swap,
  142. fromID, toID, descriptorComponentsToBuild));
  143. }
  144. //enginesRoot is a weakreference because GenericEntityStreamConsumerFactory can be injected inside
  145. //engines of other enginesRoot
  146. readonly Svelto.DataStructures.WeakReference<EnginesRoot> _enginesRoot;
  147. }
  148. void QueueEntitySubmitOperation(EntitySubmitOperation entitySubmitOperation)
  149. {
  150. #if DEBUG && !PROFILE_SVELTO
  151. entitySubmitOperation.trace = new System.Diagnostics.StackFrame(1, true);
  152. #endif
  153. _entitiesOperations.Add((ulong) entitySubmitOperation.fromID, entitySubmitOperation);
  154. }
  155. void QueueEntitySubmitOperation<T>(EntitySubmitOperation entitySubmitOperation) where T : IEntityDescriptor
  156. {
  157. #if DEBUG && !PROFILE_SVELTO
  158. entitySubmitOperation.trace = new System.Diagnostics.StackFrame(1, true);
  159. if (_entitiesOperations.TryGetValue((ulong) entitySubmitOperation.fromID, out var entitySubmitedOperation))
  160. {
  161. if (entitySubmitedOperation != entitySubmitOperation)
  162. throw new ECSException("Only one entity operation per submission is allowed"
  163. .FastConcat(" entityComponentType: ")
  164. .FastConcat(typeof(T).Name)
  165. .FastConcat(" submission type ", entitySubmitOperation.type.ToString(),
  166. " from ID: ", entitySubmitOperation.fromID.entityID.ToString())
  167. .FastConcat(" previous operation type: ",
  168. _entitiesOperations[(ulong) entitySubmitOperation.fromID].type
  169. .ToString()));
  170. }
  171. else
  172. #endif
  173. _entitiesOperations.Set((ulong) entitySubmitOperation.fromID, entitySubmitOperation);
  174. }
  175. }
  176. }