using System; using System.Collections.Generic; using Aitex.Core.Util; namespace Aitex.Core.RT.Routine { public class SeqenecRoutine { private enum STATE { IDLE = 0, WAIT = 1 } protected DeviceTimer counter = new DeviceTimer(); protected DeviceTimer delayTimer = new DeviceTimer(); private int _id; private Stack _steps = new Stack(); private STATE state; private int loop = 0; private int loopCount = 0; private int loopID = 0; private DeviceTimer timer = new DeviceTimer(); protected RoutineResult RoutineToken = new RoutineResult { Result = RoutineState.Running }; public int TokenId => _id; public int LoopCounter => loop; public int LoopTotalTime => loopCount; public int Elapsed => (int)(timer.GetElapseTime() / 1000.0); public void Reset() { _id = 0; _steps.Clear(); loop = 0; loopCount = 0; state = STATE.IDLE; counter.Start(360000.0); RoutineToken.Result = RoutineState.Running; } protected void PerformRoutineStep(int id, Func execution, RoutineResult result) { if (Acitve(id)) { result.Result = execution(); } } public void StopLoop() { loop = loopCount; } public Tuple Loop(T id, Func func, int count) { int id2 = Convert.ToInt32(id); bool flag = Acitve(id2); if (flag) { if (!func()) { return Tuple.Create(flag, Result.FAIL); } loopID = id2; loopCount = count; next(); return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } public Tuple EndLoop(T id, Func func) { int id2 = Convert.ToInt32(id); bool flag = Acitve(id2); if (flag) { if (++loop >= loopCount) { if (!func()) { return Tuple.Create(flag, Result.FAIL); } loop = 0; loopCount = 0; next(); return Tuple.Create(item1: true, Result.RUN); } next(loopID); return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } public Tuple ExecuteAndWait(T id, IRoutine routine, params object[] args) { int id2 = Convert.ToInt32(id); if (Acitve(id2)) { if (state == STATE.IDLE) { switch (routine.Start(args)) { case Result.FAIL: return Tuple.Create(item1: true, Result.FAIL); case Result.DONE: next(); return Tuple.Create(item1: true, Result.DONE); } state = STATE.WAIT; } Result result = routine.Monitor(); switch (result) { case Result.DONE: next(); return Tuple.Create(item1: true, Result.DONE); default: if (result != Result.TIMEOUT) { return Tuple.Create(item1: true, Result.RUN); } goto case Result.FAIL; case Result.FAIL: return Tuple.Create(item1: true, Result.FAIL); } } return Tuple.Create(item1: false, Result.RUN); } public Tuple ExecuteAndWait(T id, List<(IRoutine routine, object[] args)> routines) { int id2 = Convert.ToInt32(id); if (Acitve(id2)) { if (state == STATE.IDLE) { foreach (var item in routines) { if (item.routine.Start(item.args) == Result.FAIL) { return Tuple.Create(item1: true, Result.FAIL); } } state = STATE.WAIT; } bool flag = false; bool flag2 = true; foreach (var item in routines) { var result = item.routine.Monitor(); flag2 = flag2 && result is Result.FAIL or Result.DONE; flag = flag || result == Result.FAIL; } if (flag2) { next(); if (flag) { return Tuple.Create(item1: true, Result.FAIL); } return Tuple.Create(item1: true, Result.DONE); } return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } public Tuple ExecuteAndWait(T id, List routines) { int id2 = Convert.ToInt32(id); if (Acitve(id2)) { if (state == STATE.IDLE) { foreach (IRoutine routine in routines) { if (routine.Start() == Result.FAIL) { return Tuple.Create(item1: true, Result.FAIL); } } state = STATE.WAIT; } bool flag = false; bool flag2 = true; foreach (IRoutine routine2 in routines) { Result result = routine2.Monitor(); flag2 = flag2 && (result == Result.FAIL || result == Result.DONE); flag = flag || result == Result.FAIL; } if (flag2) { next(); if (flag) { return Tuple.Create(item1: true, Result.FAIL); } return Tuple.Create(item1: true, Result.DONE); } return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } public Tuple Check(T id, Func func) { return Check(Check(Convert.ToInt32(id), func)); } public Tuple Execute(T id, Func func) { return Check(execute(Convert.ToInt32(id), func)); } public Tuple Wait(T id, Func func, double timeout = 2147483647.0) { return Check(wait(Convert.ToInt32(id), func, timeout)); } public Tuple Wait(T id, Func func, double timeout = 2147483647.0) { return Check(wait(Convert.ToInt32(id), func, timeout)); } public Tuple ExecuteAndWait(T id, Func execute, Func check, double timeout = 2147483647.0) { int id2 = Convert.ToInt32(id); bool flag = Acitve(id2); bool? flag2 = false; if (flag) { if (state == STATE.IDLE) { if (!execute()) { return Tuple.Create(flag, Result.FAIL); } timer.Start(timeout); state = STATE.WAIT; } flag2 = check(); if (!flag2.HasValue) { return Tuple.Create(flag, Result.FAIL); } if (flag2.Value) { next(); return Tuple.Create(item1: true, Result.RUN); } if (timer.IsTimeout()) { return Tuple.Create(item1: true, Result.TIMEOUT); } return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } public Tuple ExecuteAndWait(T id, Func execute, Func check, Func time) { int id2 = Convert.ToInt32(id); bool flag = Acitve(id2); bool? flag2 = false; double num = 0.0; if (flag) { if (state == STATE.IDLE) { num = time(); if (!execute()) { return Tuple.Create(item1: true, Result.FAIL); } timer.Start(num); state = STATE.WAIT; } flag2 = check(); if (!flag2.HasValue) { return Tuple.Create(item1: true, Result.FAIL); } if (flag2.Value) { next(); return Tuple.Create(item1: true, Result.RUN); } if (timer.IsTimeout()) { return Tuple.Create(item1: true, Result.TIMEOUT); } return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } public Tuple Wait(T id, IRoutine rt) { int id2 = Convert.ToInt32(id); if (Acitve(id2)) { if (state == STATE.IDLE) { rt.Start(); state = STATE.WAIT; } Result item = rt.Monitor(); return Tuple.Create(item1: true, item); } return Tuple.Create(item1: false, Result.RUN); } public Tuple Monitor(T id, Func func, Func check, double time) { int id2 = Convert.ToInt32(id); bool flag = Acitve(id2); bool flag2 = false; if (flag) { if (state == STATE.IDLE) { if (func != null && !func()) { return Tuple.Create(item1: true, Result.FAIL); } timer.Start(time); state = STATE.WAIT; } if (!check()) { return Tuple.Create(item1: true, Result.FAIL); } if (timer.IsTimeout()) { next(); } return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } public Tuple Delay(T id, Func func, double time) { int id2 = Convert.ToInt32(id); if (Acitve(id2)) { if (state == STATE.IDLE) { if (func != null && !func()) { return Tuple.Create(item1: true, Result.FAIL); } timer.Start(time); state = STATE.WAIT; } if (timer.IsTimeout()) { next(); } return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } public Tuple DelayCheck(T id, Func func, double time) { int id2 = Convert.ToInt32(id); if (Acitve(id2)) { if (state == STATE.IDLE) { timer.Start(time); state = STATE.WAIT; } if (timer.IsTimeout()) { if (func != null && !func()) { return Tuple.Create(item1: true, Result.FAIL); } next(); } return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } private Tuple execute(int id, Func func) { bool flag = Acitve(id); bool flag2 = false; if (flag) { flag2 = func(); if (flag2) { next(); } } return Tuple.Create(flag, flag2); } private Tuple Check(int id, Func func) { bool flag = Acitve(id); bool item = false; if (flag) { item = func(); next(); } return Tuple.Create(flag, item); } private Tuple wait(int id, Func func, double timeout = 2147483647.0) { bool flag = Acitve(id); bool flag2 = false; bool item = false; if (flag) { if (state == STATE.IDLE) { timer.Start(timeout); state = STATE.WAIT; } flag2 = func(); if (flag2) { next(); } item = timer.IsTimeout(); } return Tuple.Create(flag, flag2, item); } private Tuple wait(int id, Func func, double timeout = 2147483647.0) { bool flag = Acitve(id); bool? item = false; bool item2 = false; if (flag) { if (state == STATE.IDLE) { timer.Start(timeout); state = STATE.WAIT; } item = func(); if (item.HasValue && item.Value) { next(); } item2 = timer.IsTimeout(); } return Tuple.Create(flag, item, item2); } private Tuple Check(Tuple value) { if (value.Item1) { if (!value.Item2) { return Tuple.Create(item1: true, Result.FAIL); } return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } private Tuple Check(Tuple value) { if (value.Item1) { if (CheckTimeout(value)) { return Tuple.Create(item1: true, Result.TIMEOUT); } return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } private Tuple Check(Tuple value) { if (value.Item1) { if (!value.Item2.HasValue) { return Tuple.Create(item1: true, Result.FAIL); } if (value.Item2 == false && value.Item3) { return Tuple.Create(item1: true, Result.TIMEOUT); } return Tuple.Create(item1: true, Result.RUN); } return Tuple.Create(item1: false, Result.RUN); } private bool CheckTimeout(Tuple value) { return value.Item1 && !value.Item2 && value.Item3; } private bool Acitve(int id) { if (_steps.Contains(id)) { return false; } _id = id; return true; } private void next() { _steps.Push(_id); state = STATE.IDLE; } private void next(int step) { while (_steps.Pop() != step) { } state = STATE.IDLE; } public void Delay(int id, double delaySeconds) { Tuple tuple = Delay(id, () => true, delaySeconds * 1000.0); if (tuple.Item1 && tuple.Item2 == Result.RUN) { throw new RoutineBreakException(); } } public bool IsActived(int id) { return _steps.Contains(id); } } }