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.

199 lines
9.5KB

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