Mirror of Svelto.ECS because we're a fan of it
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

EnginesRoot.Submission.cs 8.7KB

Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anos atrás
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anos atrás
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anos atrás
Svelto.ECS 2.9 changes (random order of importance): New Serialization framework more thorough disposing of the EnginesRoot an EnginesRoot reference should never be held, unless it’s a weak reference. The code changed to stick to this rule IReactOnAddAndRemove callbacks are now guaranteed to be called after all the entity structs generated by the same entity have been added and before any is removed. both functions pass the EGID of the analysing entity by parameter now, so that the entity struct won’t need to implement INeedEGID for this sole purpose. The IReactOnSwap MovedFrom method has been removed, it is now redundant. Entities built or removed during the IReactOnAddAndRemove callbacks are now added and removed immediately and not on the next submission like used to happen. This avoid some awkward checks that were previously needed inside engines. EntityStreams can get (optionally) the EGID of the entity published, so that the EntityStruct won’t need an INeedEGID for this sole purpose. Groups are not trimmed anymore when they are emptied to avoid allocations. Removed a bunch of run-time allocations that weren’t supposed to happen in Release and/or when the Profile define is used in editor (for debugging reasons Svelto.ECS may need to use strings at run-time, but Svelto.ECS is allocation zero in Release and when the Profile keyword is used) A improved the DynamicEntityDescriptor and ExtendibleEntityDescriptor code and more notably, introduced the new method ExtendedWith<> to facilitate the writing of modular and reusable entity descriptors. Several minor code design improvements/optimisations
4 anos atrás
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. using System.Collections.Generic;
  2. using Svelto.Common;
  3. using Svelto.DataStructures;
  4. namespace Svelto.ECS
  5. {
  6. public partial class EnginesRoot
  7. {
  8. /// <summary>
  9. /// Todo: it would be probably better to split even further the logic between submission and callbacks
  10. /// Something to do when I will optimize the callbacks
  11. /// </summary>
  12. /// <param name="profiler"></param>
  13. /// <param name="maxNumberOfOperations"></param>
  14. IEnumerator<bool> SingleSubmission(PlatformProfiler profiler)
  15. {
  16. while (true)
  17. {
  18. DBC.ECS.Check.Require(_maxNumberOfOperationsPerFrame > 0);
  19. ClearChecks();
  20. uint numberOfOperations = 0;
  21. if (_entitiesOperations.count > 0)
  22. {
  23. using (var sample = profiler.Sample("Remove and Swap operations"))
  24. {
  25. _transientEntitiesOperations.FastClear();
  26. _entitiesOperations.CopyValuesTo(_transientEntitiesOperations);
  27. _entitiesOperations.FastClear();
  28. EntitySubmitOperation[] entitiesOperations =
  29. _transientEntitiesOperations.ToArrayFast(out var count);
  30. for (var i = 0; i < count; i++)
  31. {
  32. try
  33. {
  34. switch (entitiesOperations[i].type)
  35. {
  36. case EntitySubmitOperationType.Swap:
  37. MoveEntityFromAndToEngines(entitiesOperations[i].builders
  38. , entitiesOperations[i].fromID
  39. , entitiesOperations[i].toID);
  40. break;
  41. case EntitySubmitOperationType.Remove:
  42. MoveEntityFromAndToEngines(entitiesOperations[i].builders
  43. , entitiesOperations[i].fromID, null);
  44. break;
  45. case EntitySubmitOperationType.RemoveGroup:
  46. RemoveEntitiesFromGroup(entitiesOperations[i].fromID.groupID, profiler);
  47. break;
  48. case EntitySubmitOperationType.SwapGroup:
  49. SwapEntitiesBetweenGroups(entitiesOperations[i].fromID.groupID
  50. , entitiesOperations[i].toID.groupID, profiler);
  51. break;
  52. }
  53. }
  54. catch
  55. {
  56. var str = "Crash while executing Entity Operation ".FastConcat(
  57. entitiesOperations[i].type.ToString());
  58. Svelto.Console.LogError(str.FastConcat(" ")
  59. #if DEBUG && !PROFILE_SVELTO
  60. .FastConcat(entitiesOperations[i].trace.ToString())
  61. #endif
  62. );
  63. throw;
  64. }
  65. ++numberOfOperations;
  66. if ((uint) numberOfOperations >= (uint) _maxNumberOfOperationsPerFrame)
  67. {
  68. using (sample.Yield())
  69. yield return true;
  70. numberOfOperations = 0;
  71. }
  72. }
  73. }
  74. }
  75. _groupedEntityToAdd.Swap();
  76. if (_groupedEntityToAdd.AnyOtherEntityCreated())
  77. {
  78. using (var outerSampler = profiler.Sample("Add operations"))
  79. {
  80. try
  81. {
  82. using (profiler.Sample("Add entities to database"))
  83. {
  84. //each group is indexed by entity view type. for each type there is a dictionary indexed by entityID
  85. foreach (var groupToSubmit in _groupedEntityToAdd.other)
  86. {
  87. var groupID = groupToSubmit.Key;
  88. var groupDB = GetOrCreateDBGroup(groupID);
  89. //add the entityComponents in the group
  90. foreach (var entityComponentsToSubmit in groupToSubmit.Value)
  91. {
  92. var type = entityComponentsToSubmit.Key;
  93. var targetTypeSafeDictionary = entityComponentsToSubmit.Value;
  94. var wrapper = new RefWrapperType(type);
  95. var dbDic = GetOrCreateTypeSafeDictionary(
  96. groupID, groupDB, wrapper, targetTypeSafeDictionary);
  97. //Fill the DB with the entity components generated this frame.
  98. dbDic.AddEntitiesFromDictionary(targetTypeSafeDictionary, groupID, this);
  99. }
  100. }
  101. }
  102. //then submit everything in the engines, so that the DB is up to date with all the entity components
  103. //created by the entity built
  104. using (var sampler = profiler.Sample("Add entities to engines"))
  105. {
  106. foreach (var groupToSubmit in _groupedEntityToAdd.other)
  107. {
  108. var groupID = groupToSubmit.Key;
  109. var groupDB = GetDBGroup(groupID);
  110. //entityComponentsToSubmit is the array of components found in the groupID per component type.
  111. //if there are N entities to submit, and M components type to add for each entity, this foreach will run NxM times.
  112. foreach (var entityComponentsToSubmit in groupToSubmit.Value)
  113. {
  114. var realDic = groupDB[new RefWrapperType(entityComponentsToSubmit.Key)];
  115. entityComponentsToSubmit.Value.ExecuteEnginesAddOrSwapCallbacks(
  116. _reactiveEnginesAddRemove, realDic, null, groupID, in profiler);
  117. numberOfOperations += entityComponentsToSubmit.Value.count;
  118. if (numberOfOperations >= _maxNumberOfOperationsPerFrame)
  119. {
  120. using (outerSampler.Yield())
  121. using (sampler.Yield())
  122. {
  123. yield return true;
  124. }
  125. numberOfOperations = 0;
  126. }
  127. }
  128. }
  129. }
  130. }
  131. finally
  132. {
  133. using (profiler.Sample("clear double buffering"))
  134. {
  135. //other can be cleared now, but let's avoid deleting the dictionary every time
  136. _groupedEntityToAdd.ClearOther();
  137. }
  138. }
  139. }
  140. }
  141. yield return false;
  142. }
  143. }
  144. bool HasMadeNewStructuralChangesInThisIteration()
  145. {
  146. return _groupedEntityToAdd.AnyEntityCreated() || _entitiesOperations.count > 0;
  147. }
  148. readonly DoubleBufferedEntitiesToAdd _groupedEntityToAdd;
  149. readonly FasterDictionary<ulong, EntitySubmitOperation> _entitiesOperations;
  150. readonly FasterList<EntitySubmitOperation> _transientEntitiesOperations;
  151. uint _maxNumberOfOperationsPerFrame;
  152. }
  153. }