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.

201 lines
9.4KB

  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, [CallerMemberName] string memberName = "") where T :
  21. IEntityDescriptor, new()
  22. {
  23. RemoveEntity<T>(new EGID(entityID, groupID), memberName);
  24. }
  25. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  26. public void RemoveEntity<T>(EGID entityEGID, [CallerMemberName] string memberName = "") where T : IEntityDescriptor, new()
  27. {
  28. DBC.ECS.Check.Require(entityEGID.groupID != 0, "invalid group detected");
  29. var descriptorComponentsToBuild = EntityDescriptorTemplate<T>.descriptor.componentsToBuild;
  30. _enginesRoot.Target.CheckRemoveEntityID(entityEGID, TypeCache<T>.type, memberName);
  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 != 0, "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, (uint) toGroupID));
  100. }
  101. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  102. public void SwapEntityGroup<T>(EGID fromID, ExclusiveBuildGroup toGroupID
  103. , ExclusiveBuildGroup mustBeFromGroup)
  104. where T : IEntityDescriptor, new()
  105. {
  106. if (fromID.groupID != mustBeFromGroup)
  107. throw new ECSException("Entity is not coming from the expected group");
  108. SwapEntityGroup<T>(fromID, toGroupID);
  109. }
  110. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  111. public void SwapEntityGroup<T>(EGID fromID, EGID toID
  112. , ExclusiveBuildGroup mustBeFromGroup)
  113. where T : IEntityDescriptor, new()
  114. {
  115. if (fromID.groupID != mustBeFromGroup)
  116. throw new ECSException("Entity is not coming from the expected group");
  117. SwapEntityGroup<T>(fromID, toID);
  118. }
  119. #if UNITY_NATIVE
  120. public NativeEntityRemove ToNativeRemove<T>(string memberName) where T : IEntityDescriptor, new()
  121. {
  122. return _enginesRoot.Target.ProvideNativeEntityRemoveQueue<T>(memberName);
  123. }
  124. public NativeEntitySwap ToNativeSwap<T>(string memberName) where T : IEntityDescriptor, new()
  125. {
  126. return _enginesRoot.Target.ProvideNativeEntitySwapQueue<T>(memberName);
  127. }
  128. #endif
  129. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  130. public void SwapEntityGroup<T>(EGID fromID, EGID toID)
  131. where T : IEntityDescriptor, new()
  132. {
  133. DBC.ECS.Check.Require(fromID.groupID != 0, "invalid group detected");
  134. DBC.ECS.Check.Require(toID.groupID != 0, "invalid group detected");
  135. var enginesRootTarget = _enginesRoot.Target;
  136. var descriptorComponentsToBuild = EntityDescriptorTemplate<T>.descriptor.componentsToBuild;
  137. enginesRootTarget.CheckRemoveEntityID(fromID, TypeCache<T>.type);
  138. enginesRootTarget.CheckAddEntityID(toID, TypeCache<T>.type);
  139. enginesRootTarget.QueueEntitySubmitOperation<T>(
  140. new EntitySubmitOperation(EntitySubmitOperationType.Swap,
  141. fromID, toID, descriptorComponentsToBuild));
  142. }
  143. //enginesRoot is a weakreference because GenericEntityStreamConsumerFactory can be injected inside
  144. //engines of other enginesRoot
  145. readonly Svelto.DataStructures.WeakReference<EnginesRoot> _enginesRoot;
  146. }
  147. void QueueEntitySubmitOperation(EntitySubmitOperation entitySubmitOperation)
  148. {
  149. #if DEBUG && !PROFILE_SVELTO
  150. entitySubmitOperation.trace = new System.Diagnostics.StackFrame(1, true);
  151. #endif
  152. _entitiesOperations.Add((ulong) entitySubmitOperation.fromID, entitySubmitOperation);
  153. }
  154. void QueueEntitySubmitOperation<T>(EntitySubmitOperation entitySubmitOperation) where T : IEntityDescriptor
  155. {
  156. #if DEBUG && !PROFILE_SVELTO
  157. entitySubmitOperation.trace = new System.Diagnostics.StackFrame(1, true);
  158. if (_entitiesOperations.TryGetValue((ulong) entitySubmitOperation.fromID, out var entitySubmitedOperation))
  159. {
  160. if (entitySubmitedOperation != entitySubmitOperation)
  161. throw new ECSException("Only one entity operation per submission is allowed"
  162. .FastConcat(" entityComponentType: ")
  163. .FastConcat(typeof(T).Name)
  164. .FastConcat(" submission type ", entitySubmitOperation.type.ToString(),
  165. " from ID: ", entitySubmitOperation.fromID.entityID.ToString())
  166. .FastConcat(" previous operation type: ",
  167. _entitiesOperations[(ulong) entitySubmitOperation.fromID].type
  168. .ToString()));
  169. }
  170. else
  171. #endif
  172. _entitiesOperations[(ulong) entitySubmitOperation.fromID] = entitySubmitOperation;
  173. }
  174. }
  175. }