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.

106 line
4.4KB

  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. /// WiresInitTimeRunningGroup
  14. ///}
  15. ///
  16. /// then link these ID to the actual engines, using the attribute Sequenced:
  17. ///
  18. /// [Sequenced(nameof(WiresCompositionEngineNames.WiresTimeRunningGroup))]
  19. /// class WiresTimeRunningGroup : UnsortedDeterministicEnginesGroup<IDeterministicTimeRunning>g {}
  20. ///
  21. /// Note that the engine can be another group itself (like in this example).
  22. ///
  23. /// then define the ISequenceOrder struct. E.G.:
  24. /// public struct DeterministicTimeRunningEnginesOrder: ISequenceOrder
  25. /// {
  26. /// private static readonly string[] order =
  27. /// {
  28. /// nameof(TriggerEngineNames.PreWiresTimeRunningTriggerGroup),
  29. /// nameof(TimerEnginesNames.PreWiresTimeRunningTimerGroup),
  30. /// nameof(WiresCompositionEngineNames.WiresTimeRunningGroup),
  31. /// nameof(SyncGroupEnginesGroups.UnsortedDeterministicTimeRunningGroup)
  32. /// };
  33. /// public string[] enginesOrder => order;
  34. /// }
  35. ///
  36. /// Now you can use the Type you just created (i.e.: DeterministicTimeRunningEnginesOrder) as generic parameter
  37. /// of the SortedEnginesGroup.
  38. /// While the system may look convoluted, is an effective way to keep the engines assemblies decoupled from
  39. /// each other
  40. /// The class is abstract and it requires a user defined interface to push the user to use recognisable names meaningful
  41. /// to the context where they are used.
  42. /// </summary>
  43. /// <typeparam name="Interface">user defined interface that implements IStepEngine</typeparam>
  44. public abstract class SortedEnginesGroup<Interface, SequenceOrder> : IStepGroupEngine
  45. where SequenceOrder : struct, ISequenceOrder where Interface : IStepEngine
  46. {
  47. protected SortedEnginesGroup(FasterList<Interface> engines)
  48. {
  49. _name = "SortedEnginesGroup - "+GetType().Name;
  50. _instancedSequence = new Sequence<Interface, SequenceOrder>(engines);
  51. }
  52. public void Step()
  53. {
  54. var sequenceItems = _instancedSequence.items;
  55. using (var profiler = new PlatformProfiler(_name))
  56. {
  57. for (var index = 0; index < sequenceItems.count; index++)
  58. {
  59. var engine = sequenceItems[index];
  60. using (profiler.Sample(engine.name)) engine.Step();
  61. }
  62. }
  63. }
  64. public string name => _name;
  65. readonly string _name;
  66. readonly Sequence<Interface, SequenceOrder> _instancedSequence;
  67. }
  68. /// <summary>
  69. /// Similar to SortedEnginesGroup except for the fact that an optional parameter can be passed to the engines
  70. /// </summary>
  71. /// <typeparam name="Interface"></typeparam>
  72. /// <typeparam name="Parameter">Specialised Parameter that can be passed to all the engines in the group</typeparam>
  73. public abstract class SortedEnginesGroup<Interface, Parameter, SequenceOrder>: IStepGroupEngine<Parameter>
  74. where SequenceOrder : struct, ISequenceOrder where Interface : IStepEngine<Parameter>
  75. {
  76. protected SortedEnginesGroup(FasterList<Interface> engines)
  77. {
  78. _name = "SortedEnginesGroup - "+GetType().Name;
  79. _instancedSequence = new Sequence<Interface, SequenceOrder>(engines);
  80. }
  81. public void Step(in Parameter param)
  82. {
  83. var sequenceItems = _instancedSequence.items;
  84. using (var profiler = new PlatformProfiler(_name))
  85. {
  86. for (var index = 0; index < sequenceItems.count; index++)
  87. {
  88. var engine = sequenceItems[index];
  89. using (profiler.Sample(engine.name)) engine.Step(param);
  90. }
  91. }
  92. }
  93. public string name => _name;
  94. readonly string _name;
  95. readonly Sequence<Interface, SequenceOrder> _instancedSequence;
  96. }
  97. }