using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace FurnaceRT.Equipments.Systems { public class ModuleFsmDevice : FsmDevice { public bool IsInstalled { get { if (!SC.ContainsItem($"System.SetUp.Is{Module}Installed")) return true; return SC.GetValue($"System.SetUp.Is{Module}Installed"); } } public virtual bool IsOnline { get; set; } protected Queue QueueRoutine { get { return _routine; } } private Queue _routine = new Queue(); public ModuleFsmDevice() : base() { } public override bool Initialize() { return base.Initialize(); } public Result StartRoutine(IRoutine routine) { QueueRoutine.Clear(); QueueRoutine.Enqueue(routine); return QueueRoutine.Peek().Start(); } public Result StartRoutine() { if (_routine.Count == 0) return Result.DONE; Result ret = Result.DONE; var lst = _routine.ToList(); for (int i = 0; i < lst.Count; i++) { ret = lst[i].Start(); if (ret == Result.DONE) { _routine.Dequeue(); continue; } else { break; } } return Result.RUN; } public Result MonitorRoutine() { if (_routine.Count == 0) return Result.DONE; IRoutine routine = _routine.Peek(); Result ret = routine.Monitor(); if (ret == Result.DONE) { _routine.Dequeue(); var lst = _routine.ToList(); for (int i = 0; i < lst.Count; i++) { ret = lst[i].Start(); if (ret == Result.DONE) { _routine.Dequeue(); continue; } else { break; } } } return ret; } public void AbortRoutine() { if (_routine != null && _routine.Any()) { _routine.Peek().Abort(); _routine.Clear(); } } } public class FsmDevice : BaseDevice, IDevice { private Thread _thread = null; private IStateMachine _fsm = null; public int FsmState { get { return _fsm.State; } } public int FsmPreviousState { get { return _fsm.PrevState; } } public string StringFsmStatus { get { return _fsmStateMap.ContainsKey(FsmState) ? _fsmStateMap[FsmState] : FsmState.ToString(); } } Dictionary _fsmStateMap = new Dictionary(); Dictionary _fsmMessageMap = new Dictionary(); public FsmDevice() : base() { } public void MapState(int state, string stringState) { _fsmStateMap[state] = stringState; } public void MapMessage(int msg, string stringMessage) { _fsmMessageMap[msg] = stringMessage; } public void EnableFsm(int fsmInterval, object initState) { EnableFsm(fsmInterval, (int)initState); } public void EnableFsm(int fsmInterval, int initState) { _fsm = new StateMachine($"{Module} {Name} FSM", initState, fsmInterval); _fsm.Start(); _thread = new Thread(new ThreadStart(_fsm.Loop)); _thread.Name = _fsm.Name; _thread.Start(); while (!_thread.IsAlive) Thread.Sleep(1); } public virtual bool Initialize() { return true; } public virtual void Monitor() { } public virtual void Terminate() { if (_fsm != null) { _fsm.Stop(); } if (_thread != null) { if (_thread.IsAlive) { Thread.Sleep(100); if (_thread.IsAlive) { try { _thread.Abort(); } catch (Exception ex) { LOG.Error(String.Format("Entity terminate has exception."), ex); } } } } //Term(); } public virtual void Reset() { } protected void Transition(T state, V msg, FsmFunc func, T next) { Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum); int _state = Convert.ToInt32(state); int _next = Convert.ToInt32(next); int _msg = Convert.ToInt32(msg); Transition(_state, _msg, func, _next); } protected void Transition(int state, int msg, FsmFunc func, int next) { if (_fsm != null) _fsm.Transition(state, msg, func, next); } protected void AnyStateTransition(int msg, FsmFunc func, int next) { if (_fsm != null) _fsm.AnyStateTransition(msg, func, next); } protected void AnyStateTransition(V msg, FsmFunc func, T next) { Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum); int _next = Convert.ToInt32(next); int _msg = Convert.ToInt32(msg); AnyStateTransition(_msg, func, _next); } protected void EnterExitTransition(T state, FsmFunc enter, Nullable msg, FsmFunc exit) where V : struct { Debug.Assert(typeof(T).IsEnum && ((msg == null) || typeof(V).IsEnum)); int _state = Convert.ToInt32(state); int _msg = msg == null ? (int)FSM_MSG.NONE : Convert.ToInt32(msg); EnterExitTransition(_state, enter, _msg, exit); } protected void EnterExitTransition(int state, FsmFunc enter, int msg, FsmFunc exit) { if (_fsm != null) _fsm.EnterExitTransition(state, enter, msg, exit); } public void PostMsg(T msg, params object[] args) where T : struct { Debug.Assert(typeof(T).IsEnum); int id = Convert.ToInt32(msg); PostMsg(id, args); } public void PostMsg(int msg, params object[] args) { if (_fsm == null) { LOG.Error($"fsm is null, post msg {msg}"); return; } _fsm.PostMsgWithoutLock(msg, args); } public bool CheckAllMessageProcessed() { return _fsm.CheckExecuted(); } public bool CheckToPostMessage(T msg, params object[] args) { return CheckToPostMessage(Convert.ToInt32(msg)); } public bool CheckToPostMessage(int msg, params object[] args) { int state = _fsm.State; string status = _fsmStateMap[state]; if (!_fsm.FindTransition(_fsm.State, msg)) { string message = string.Empty; if (_fsmMessageMap.ContainsKey(msg)) message = _fsmMessageMap[msg]; else { message = msg.ToString(); } EV.PostWarningLog(Module, $"{Name} is in {status} state,can not do {message}"); return false; } _fsm.PostMsg(msg, args); return true; } } }