// An ActionSequence encapsulates a series of IBlockActions to perform. // It represents a single logical coordinated "action". The action may have // multiple steps, each with multiple actions. It provides a method to asynchronously // perform those steps in sequence. using System.Collections.Generic; namespace IngameScript { partial class Program { public class ActionSequence { public string Name { get; private set; } public bool Running { get; private set; } = false; private SortedDictionary<int, List<BlockAction>> _steps = new SortedDictionary<int, List<BlockAction>>(); public ActionSequence(string name) { Name = name; } public void Add(int step, BlockAction action) { if (!_steps.ContainsKey(step)) _steps[step] = new List<BlockAction>(); _steps[step].Add(action); } public IEnumerator<bool> Run() { if (Running) yield break; Running = true; List<IEnumerator<bool>> jobs = new List<IEnumerator<bool>>(); foreach (List<BlockAction> step in _steps.Values) { foreach (BlockAction action in step) { jobs.Add(action.Run()); } bool stepRunning = true; while (stepRunning) { stepRunning = false; foreach (IEnumerator<bool> job in jobs) { if (job.MoveNext()) stepRunning = true; } yield return true; } foreach (IEnumerator<bool> job in jobs) { job.Dispose(); } jobs.Clear(); } Running = false; } } } }