Mirror of Svelto.ECS because we're a fan of it
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

134 строки
5.5KB

  1. using System.Collections.Generic;
  2. using Svelto.DataStructures;
  3. using Svelto.Common;
  4. namespace Svelto.ECS
  5. {
  6. /// <summary>
  7. /// SortedEnginesGroup is a practical way to group engines that need to be ticked in order. The class requires a
  8. /// SequenceOrder struct that defines the order of execution. The pattern to use is the following:
  9. /// First define as many enums as you want with the IDs of the engines to use. E.G.:
  10. /// public enum WiresCompositionEngineNames
  11. ///{
  12. /// WiresTimeRunningGroup,
  13. /// WiresPreInitTimeRunningGroup,
  14. /// WiresInitTimeRunningGroup
  15. ///}
  16. ///
  17. /// then link these ID to the actual engines, using the attribute Sequenced:
  18. ///
  19. /// [Sequenced(nameof(WiresCompositionEngineNames.WiresTimeRunningGroup))]
  20. /// class WiresTimeRunningGroup : UnsortedDeterministicEnginesGroup<IDeterministicTimeRunning> {}
  21. ///
  22. /// Note that the engine can be another engines group itself.
  23. ///
  24. /// then define the ISequenceOrder struct to define the order of execution. E.G.:
  25. /// public struct DeterministicTimeRunningEnginesOrder: ISequenceOrder
  26. /// {
  27. /// private static readonly string[] order =
  28. /// {
  29. /// nameof(TriggerEngineNames.PreWiresTimeRunningTriggerGroup),
  30. /// nameof(TimerEnginesNames.PreWiresTimeRunningTimerGroup),
  31. /// nameof(WiresCompositionEngineNames.WiresTimeRunningGroup),
  32. /// nameof(SyncGroupEnginesGroups.UnsortedDeterministicTimeRunningGroup)
  33. /// };
  34. /// public string[] enginesOrder => order;
  35. /// }
  36. ///
  37. /// Now you can use the Type you just created (i.e.: DeterministicTimeRunningEnginesOrder) as generic parameter
  38. /// of the SortedEnginesGroup. like this:
  39. ///
  40. /// public class SortedDoofusesEnginesExecutionGroup : SortedEnginesGroup<IUpdateEngine, DeterministicTimeRunningEnginesOrder>
  41. /// {
  42. /// public SortedDoofusesEnginesExecutionGroup(FasterList<IUpdateEngine> engines) : base(engines)
  43. /// {
  44. /// }
  45. /// }
  46. ///
  47. /// This will then Tick the engines passed by constructor with the order defined in the DeterministicTimeRunningEnginesOrder
  48. /// calling _enginesGroup.Step();
  49. ///
  50. /// While the system may look convoluted, is an effective way to keep the engines assemblies decoupled from
  51. /// each other
  52. /// The class is abstract and it requires a user defined interface to push the user to use recognisable names meaningful
  53. /// to the context where they are used.
  54. /// </summary>
  55. /// <typeparam name="Interface">user defined interface that implements IStepEngine</typeparam>
  56. public abstract class SortedEnginesGroup<Interface, SequenceOrder> : IStepGroupEngine
  57. where SequenceOrder : struct, ISequenceOrder where Interface : class, IStepEngine
  58. {
  59. protected SortedEnginesGroup(FasterList<Interface> engines)
  60. {
  61. _name = "SortedEnginesGroup - "+GetType().Name;
  62. _instancedSequence = new Sequence<Interface, SequenceOrder>(engines);
  63. }
  64. public void Step()
  65. {
  66. var sequenceItems = _instancedSequence.items;
  67. using (var profiler = new PlatformProfiler(_name))
  68. {
  69. for (var index = 0; index < sequenceItems.count; index++)
  70. {
  71. var engine = sequenceItems[index];
  72. using (profiler.Sample(engine.name)) engine.Step();
  73. }
  74. }
  75. }
  76. public string name => _name;
  77. public IEnumerable<IEngine> engines
  78. {
  79. get
  80. {
  81. for (int i = 0; i < _instancedSequence.items.count; i++)
  82. yield return _instancedSequence.items[i];
  83. }
  84. }
  85. readonly string _name;
  86. readonly Sequence<Interface, SequenceOrder> _instancedSequence;
  87. }
  88. /// <summary>
  89. /// Similar to SortedEnginesGroup except for the fact that an optional parameter can be passed to the engines
  90. /// </summary>
  91. /// <typeparam name="Interface"></typeparam>
  92. /// <typeparam name="Parameter">Specialised Parameter that can be passed to all the engines in the group</typeparam>
  93. public abstract class SortedEnginesGroup<Interface, Parameter, SequenceOrder>: IStepGroupEngine<Parameter>
  94. where SequenceOrder : struct, ISequenceOrder where Interface : class, IStepEngine<Parameter>
  95. {
  96. protected SortedEnginesGroup(FasterList<Interface> engines)
  97. {
  98. _name = "SortedEnginesGroup - "+GetType().Name;
  99. _instancedSequence = new Sequence<Interface, SequenceOrder>(engines);
  100. }
  101. public void Step(in Parameter time)
  102. {
  103. var sequenceItems = _instancedSequence.items;
  104. using (var profiler = new PlatformProfiler(_name))
  105. {
  106. for (var index = 0; index < sequenceItems.count; index++)
  107. {
  108. var engine = sequenceItems[index];
  109. using (profiler.Sample(engine.name)) engine.Step(time);
  110. }
  111. }
  112. }
  113. public string name => _name;
  114. public IEnumerable<IEngine> engines
  115. {
  116. get
  117. {
  118. for (int i = 0; i < _instancedSequence.items.count; i++)
  119. yield return _instancedSequence.items[i];
  120. }
  121. }
  122. readonly string _name;
  123. readonly Sequence<Interface, SequenceOrder> _instancedSequence;
  124. }
  125. }