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.

130 lines
5.7KB

  1. using System.Diagnostics;
  2. using System.Runtime.CompilerServices;
  3. using Svelto.DataStructures;
  4. namespace Svelto.ECS
  5. {
  6. public partial class EnginesRoot
  7. {
  8. /// <summary>
  9. /// todo: EnginesRoot was a weakreference to give the change to inject
  10. /// entityfunctions from other engines root. It probably should be reverted
  11. /// </summary>
  12. sealed class GenericEntityFunctions : IEntityFunctions
  13. {
  14. internal GenericEntityFunctions(EnginesRoot weakReference)
  15. {
  16. _enginesRoot = new WeakReference<EnginesRoot>(weakReference);
  17. }
  18. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  19. public void RemoveEntity<T>(uint entityID, ExclusiveGroup.ExclusiveGroupStruct groupID) where T :
  20. IEntityDescriptor, new()
  21. {
  22. RemoveEntity<T>(new EGID(entityID, groupID));
  23. }
  24. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  25. public void RemoveEntity<T>(EGID entityEGID) where T : IEntityDescriptor, new()
  26. {
  27. _enginesRoot.Target.CheckRemoveEntityID(entityEGID);
  28. _enginesRoot.Target.QueueEntitySubmitOperation<T>(
  29. new EntitySubmitOperation(EntitySubmitOperationType.Remove, entityEGID, entityEGID,
  30. EntityDescriptorTemplate<T>.descriptor.entitiesToBuild));
  31. }
  32. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  33. public void RemoveGroupAndEntities(ExclusiveGroup.ExclusiveGroupStruct groupID)
  34. {
  35. _enginesRoot.Target.RemoveGroupID(groupID);
  36. _enginesRoot.Target.QueueEntitySubmitOperation(
  37. new EntitySubmitOperation(EntitySubmitOperationType.RemoveGroup, new EGID(0, groupID), new EGID()));
  38. }
  39. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  40. public void SwapEntityGroup<T>(uint entityID, ExclusiveGroup.ExclusiveGroupStruct fromGroupID,
  41. ExclusiveGroup.ExclusiveGroupStruct toGroupID)
  42. where T : IEntityDescriptor, new()
  43. {
  44. SwapEntityGroup<T>(new EGID(entityID, fromGroupID), toGroupID);
  45. }
  46. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  47. public void SwapEntityGroup<T>(EGID fromID, ExclusiveGroup.ExclusiveGroupStruct toGroupID)
  48. where T : IEntityDescriptor, new()
  49. {
  50. SwapEntityGroup<T>(fromID, new EGID(fromID.entityID, (uint) toGroupID));
  51. }
  52. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  53. public void SwapEntityGroup<T>(EGID fromID, ExclusiveGroup.ExclusiveGroupStruct toGroupID
  54. , ExclusiveGroup.ExclusiveGroupStruct mustBeFromGroup)
  55. where T : IEntityDescriptor, new()
  56. {
  57. if (fromID.groupID != mustBeFromGroup)
  58. throw new ECSException("Entity is not coming from the expected group");
  59. SwapEntityGroup<T>(fromID, toGroupID);
  60. }
  61. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  62. public void SwapEntityGroup<T>(EGID fromID, EGID toID
  63. , ExclusiveGroup.ExclusiveGroupStruct mustBeFromGroup)
  64. where T : IEntityDescriptor, new()
  65. {
  66. if (fromID.groupID != mustBeFromGroup)
  67. throw new ECSException("Entity is not coming from the expected group");
  68. SwapEntityGroup<T>(fromID, toID);
  69. }
  70. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  71. public void SwapEntityGroup<T>(EGID fromID, EGID toID)
  72. where T : IEntityDescriptor, new()
  73. {
  74. _enginesRoot.Target.CheckRemoveEntityID(fromID);
  75. _enginesRoot.Target.CheckAddEntityID(toID);
  76. _enginesRoot.Target.QueueEntitySubmitOperation<T>(
  77. new EntitySubmitOperation(EntitySubmitOperationType.Swap,
  78. fromID, toID, EntityDescriptorTemplate<T>.descriptor.entitiesToBuild));
  79. }
  80. //enginesRoot is a weakreference because GenericEntityStreamConsumerFactory can be injected inside
  81. //engines of other enginesRoot
  82. readonly WeakReference<EnginesRoot> _enginesRoot;
  83. }
  84. void QueueEntitySubmitOperation(EntitySubmitOperation entitySubmitOperation)
  85. {
  86. #if DEBUG && !PROFILER
  87. entitySubmitOperation.trace = new StackFrame(1, true);
  88. #endif
  89. _entitiesOperations.Add((ulong) entitySubmitOperation.fromID, entitySubmitOperation);
  90. }
  91. void QueueEntitySubmitOperation<T>(EntitySubmitOperation entitySubmitOperation) where T : IEntityDescriptor
  92. {
  93. #if DEBUG && !PROFILER
  94. entitySubmitOperation.trace = new StackFrame(1, true);
  95. if (_entitiesOperations.TryGetValue((ulong) entitySubmitOperation.fromID, out var entitySubmitedOperation))
  96. {
  97. if (entitySubmitedOperation != entitySubmitOperation)
  98. throw new ECSException("Only one entity operation per submission is allowed"
  99. .FastConcat(" entityViewType: ")
  100. .FastConcat(typeof(T).Name)
  101. .FastConcat(" submission type ", entitySubmitOperation.type.ToString(),
  102. " from ID: ", entitySubmitOperation.fromID.entityID.ToString())
  103. .FastConcat(" previous operation type: ",
  104. _entitiesOperations[(ulong) entitySubmitOperation.fromID].type
  105. .ToString()));
  106. }
  107. else
  108. #endif
  109. _entitiesOperations.Set((ulong) entitySubmitOperation.fromID, entitySubmitOperation);
  110. }
  111. }
  112. }