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.

107 lines
4.5KB

  1. using Svelto.DataStructures;
  2. using Svelto.Common;
  3. namespace Svelto.ECS
  4. {
  5. /// <summary>
  6. /// SortedEnginesGroup is a practical way to group engines that can be ticked together. The class requires a
  7. /// SequenceOrder struct that define the order of execution. The pattern to use is the following:
  8. /// First define as many enums as you want with the ID of the engines to use. E.G.:
  9. /// public enum WiresCompositionEngineNames
  10. ///{
  11. /// WiresTimeRunningGroup,
  12. /// WiresPreInitTimeRunningGroup,
  13. /// WiresInitTimeStoppedGroup,
  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>g {}
  21. ///
  22. /// Note that the engine can be another group itself (like in this example).
  23. ///
  24. /// then define the ISequenceOrder struct. 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.
  39. /// While the system may look convoluted, is an effective way to keep the engines assemblies decoupled from
  40. /// each other
  41. /// The class is abstract and it requires a user defined interface to push the user to use recognisable names meaningful
  42. /// to the context where they are used.
  43. /// </summary>
  44. /// <typeparam name="Interface">user defined interface that implements IStepEngine</typeparam>
  45. public abstract class SortedEnginesGroup<Interface, SequenceOrder> : IStepGroupEngine
  46. where SequenceOrder : struct, ISequenceOrder where Interface : IStepEngine
  47. {
  48. protected SortedEnginesGroup(FasterList<Interface> engines)
  49. {
  50. _name = "SortedEnginesGroup - "+this.GetType().Name;
  51. _instancedSequence = new Sequence<Interface, SequenceOrder>(engines);
  52. }
  53. public void Step()
  54. {
  55. var sequenceItems = _instancedSequence.items;
  56. using (var profiler = new PlatformProfiler(_name))
  57. {
  58. for (var index = 0; index < sequenceItems.count; index++)
  59. {
  60. var engine = sequenceItems[index];
  61. using (profiler.Sample(engine.name)) engine.Step();
  62. }
  63. }
  64. }
  65. public string name => _name;
  66. readonly string _name;
  67. readonly Sequence<Interface, SequenceOrder> _instancedSequence;
  68. }
  69. /// <summary>
  70. /// Similar to SortedEnginesGroup except for the fact that an optional parameter can be passed to the engines
  71. /// </summary>
  72. /// <typeparam name="Interface"></typeparam>
  73. /// <typeparam name="Parameter">Specialised Parameter that can be passed to all the engines in the group</typeparam>
  74. public abstract class SortedEnginesGroup<Interface, Parameter, SequenceOrder>: IStepGroupEngine<Parameter>
  75. where SequenceOrder : struct, ISequenceOrder where Interface : IStepEngine<Parameter>
  76. {
  77. protected SortedEnginesGroup(FasterList<Interface> engines)
  78. {
  79. _name = "SortedEnginesGroup - "+this.GetType().Name;
  80. _instancedSequence = new Sequence<Interface, SequenceOrder>(engines);
  81. }
  82. public void Step(in Parameter param)
  83. {
  84. var sequenceItems = _instancedSequence.items;
  85. using (var profiler = new PlatformProfiler(_name))
  86. {
  87. for (var index = 0; index < sequenceItems.count; index++)
  88. {
  89. var engine = sequenceItems[index];
  90. using (profiler.Sample(engine.name)) engine.Step(param);
  91. }
  92. }
  93. }
  94. public string name => _name;
  95. readonly string _name;
  96. readonly Sequence<Interface, SequenceOrder> _instancedSequence;
  97. }
  98. }