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.

Sequencer.cs 4.5KB

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 years ago
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 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. namespace Svelto.ECS
  5. {
  6. public class Steps
  7. {
  8. internal readonly Dictionary<IEngine, To> _steps;
  9. public Steps(params Step[] values)
  10. {
  11. _steps = new Dictionary<IEngine, To>();
  12. for (var i = 0; i < values.Length; i++)
  13. _steps.Add(values[i].from, values[i].to);
  14. }
  15. }
  16. public class To
  17. {
  18. public To(IStep engine)
  19. {
  20. this.engine = engine;
  21. }
  22. public To(params IStep[] engines)
  23. {
  24. this.engines = engines;
  25. }
  26. public IStep engine { get; set; }
  27. public IStep[] engines { get; set; }
  28. }
  29. public class To<C>:To, IEnumerable where C : struct, IConvertible
  30. {
  31. internal readonly Dictionary<C, IStep<C>[]> _tos = new Dictionary<C, IStep<C>[]>();
  32. public IEnumerator GetEnumerator()
  33. {
  34. throw new NotImplementedException();
  35. }
  36. public void Add(C condition, params IStep<C>[] engine)
  37. {
  38. _tos[condition] = engine;
  39. }
  40. }
  41. public interface IStep
  42. {
  43. void Step(EGID id);
  44. }
  45. public interface IStep<in C> where C:struct,IConvertible
  46. {
  47. void Step(C condition, EGID id);
  48. }
  49. public struct Step
  50. {
  51. public IEngine from { get; set; }
  52. public To to { get; set; }
  53. }
  54. /// <summary>
  55. /// The sequencer has just one goal: define a complex sequence of engines to call. The sequence is not
  56. /// just "sequential", but can create branches and loops.
  57. /// With the time, I figure out that the majority of the times this class is useful in the rare cases where
  58. /// order execution of the engine is necessary/
  59. /// Using branching is even rarer, but still useful sometimes.
  60. /// I used loops only once.
  61. /// There is the chance that this class will become obsolete over the time, as by design engines should
  62. /// never rely on the order of execution
  63. /// Using this class to let engines from different EnginesRoot communicate will also become obsolete, as
  64. /// better solution will be implemented once I have the time
  65. /// Trying to work out how to initialize this structure can be painful. This is by design as this class must
  66. /// be initialized using the following pattern:
  67. /// instancedSequence.SetSequence(
  68. /// new Steps //list of steps
  69. /// (
  70. /// new Step // first step
  71. /// {
  72. /// from = menuOptionEnablerEngine, //starting engine
  73. /// to = new To<ItemActionsPanelEnableCondition> //targets
  74. /// {
  75. /// {
  76. /// ItemActionsPanelEnableCondition.Enable, //condition 1
  77. /// menuPanelEnablerEngine //targets for condition 1
  78. /// },
  79. /// {
  80. /// ItemActionsPanelEnableCondition.Disable,//condition 2
  81. /// menuPanelEnablerEngine //targets for condition 2
  82. /// }
  83. /// }
  84. /// })
  85. /// );
  86. /// </summary>
  87. public class Sequencer<S> where S: Sequencer<S>, new()
  88. {
  89. public void SetSequence(Steps steps)
  90. {
  91. _steps = steps;
  92. }
  93. public void Next<C>(IEngine engine, C condition, EGID id) where C:struct, IConvertible
  94. {
  95. var branch = condition;
  96. var to = (_steps._steps[engine] as To<C>);
  97. var steps = to._tos[branch];
  98. for (var i = 0; i < steps.Length; i++)
  99. steps[i].Step(condition, id);
  100. }
  101. public void Next(IEngine engine, EGID id)
  102. {
  103. var to = _steps._steps[engine];
  104. var steps = to.engines;
  105. if (steps != null && steps.Length > 1)
  106. for (var i = 0; i < steps.Length; i++)
  107. steps[i].Step(id);
  108. else
  109. to.engine.Step(id);
  110. }
  111. Steps _steps;
  112. }
  113. }