using System; using System.Collections; using System.Collections.Generic; namespace Svelto.ECS { public class Steps { internal readonly Dictionary _steps; public Steps(params Step[] values) { _steps = new Dictionary(); for (var i = 0; i < values.Length; i++) _steps.Add(values[i].from, values[i].to); } } public class To { public To(IStep engine) { this.engine = engine; } public To(params IStep[] engines) { this.engines = engines; } public IStep engine { get; set; } public IStep[] engines { get; set; } } public class To:To, IEnumerable where C : struct, IConvertible { internal readonly Dictionary[]> _tos = new Dictionary[]>(); public IEnumerator GetEnumerator() { throw new NotImplementedException(); } public void Add(C condition, params IStep[] engine) { _tos[condition] = engine; } } public interface IStep { void Step(EGID id); } public interface IStep where C:struct,IConvertible { void Step(C condition, EGID id); } public struct Step { public IEngine from { get; set; } public To to { get; set; } } /// /// The sequencer has just one goal: define a complex sequence of engines to call. The sequence is not /// just "sequential", but can create branches and loops. /// With the time, I figure out that the majority of the times this class is useful in the rare cases where /// order execution of the engine is necessary/ /// Using branching is even rarer, but still useful sometimes. /// I used loops only once. /// There is the chance that this class will become obsolete over the time, as by design engines should /// never rely on the order of execution /// Using this class to let engines from different EnginesRoot communicate will also become obsolete, as /// better solution will be implemented once I have the time /// Trying to work out how to initialize this structure can be painful. This is by design as this class must /// be initialized using the following pattern: /// instancedSequence.SetSequence( /// new Steps //list of steps /// ( /// new Step // first step /// { /// from = menuOptionEnablerEngine, //starting engine /// to = new To //targets /// { /// { /// ItemActionsPanelEnableCondition.Enable, //condition 1 /// menuPanelEnablerEngine //targets for condition 1 /// }, /// { /// ItemActionsPanelEnableCondition.Disable,//condition 2 /// menuPanelEnablerEngine //targets for condition 2 /// } /// } /// }) /// ); /// public class Sequencer where S: Sequencer, new() { public void SetSequence(Steps steps) { _steps = steps; } public void Next(IEngine engine, C condition, EGID id) where C:struct, IConvertible { var branch = condition; var to = (_steps._steps[engine] as To); var steps = to._tos[branch]; for (var i = 0; i < steps.Length; i++) steps[i].Step(condition, id); } public void Next(IEngine engine, EGID id) { var to = _steps._steps[engine]; var steps = to.engines; if (steps != null && steps.Length > 1) for (var i = 0; i < steps.Length; i++) steps[i].Step(id); else to.engine.Step(id); } Steps _steps; } }