| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468 | 
							- using System;
 
- using System.Diagnostics;
 
- using System.Threading;
 
- using System.Collections.Generic;
 
- using System.Collections.Concurrent;
 
- using Aitex.Core.RT.Log;
 
- using Aitex.Core.Utilities;
 
- using System.Linq;
 
- namespace Aitex.Core.RT.Fsm
 
- {
 
-     /// <summary>
 
-     /// FSM transition function
 
-     /// 返回值: true  需要转换状态
 
-     ///          false 保持状态不变
 
-     /// </summary>
 
-     /// <param name="param"></param>
 
-     /// <returns></returns>
 
-     public enum FSM_MSG
 
-     {
 
-         TIMER = 0x0FFFFFF0,
 
-         NONE,
 
-         WARNING,
 
-         ALARM,      
 
-     }
 
-     public enum FSM_STATE
 
-     {
 
-         UNDEFINE = 0x0FFFFFF0,
 
-         SAME,
 
-         ANY,
 
-     }
 
-     public class StateMachine : StateMachine<object>
 
-     {
 
-         public StateMachine(string name = "FSM", int initState = (int)FSM_STATE.UNDEFINE, int interval = 100) : base(name, initState, interval)
 
-         {
 
-         }
 
-     }
 
-     public class StateMachine<T> : IStateMachine
 
-     {
 
-         public string Name { get; set; }
 
-         public int ElapsedTime
 
-         {
 
-             get
 
-             {
 
-                 int ticket = Environment.TickCount;
 
-                 return ticket > enterTime ? ticket - enterTime : 0x7FFFFFFF + ticket - enterTime;
 
-             }
 
-         }
 
-         public int EnterTime { set { enterTime = value; } }
 
-         public int State { get; set; }
 
-         public int PrevState { get; set; }
 
-         public int LastMsg { get; private set; }
 
-         private int enterTime;
 
-         public int MaxMsgInQueue { get; set; }
 
-         private int interval;
 
-         private bool _enableRepeatedMsg;
 
-         private CancellationTokenSource cancelToken;
 
-         private BlockingCollection<KeyValuePair<int, object[]>> _msgQueue;
 
-         private object _lockerMsgQueue = new object();
 
-         private KeyValuePair<int, object[]> timeoutMsg = new KeyValuePair<int, object[]>((int)FSM_MSG.TIMER, null);
 
-         /// <summary>
 
-         /// 状态迁移表           当前状态, 消息, 函数, 迁移状态
 
-         /// AnyState迁移表       消息, 函数, 迁移状态
 
-         /// 状态进入/退出迁移表  状态,进入函数,进入消息,退出函数, 
 
-         /// </summary>
 
-         private Dictionary<int, Dictionary<int, Tuple<FsmFunc, int>>> transition;
 
-         private Dictionary<int, Tuple<FsmFunc, int>> anyStateTransition;
 
-         private Dictionary<int, Tuple<FsmFunc, int, FsmFunc>> enterExitTransition;
 
-         private Dictionary<int, string> _stringState = new Dictionary<int, string>();
 
-         private Dictionary<int, string> _stringMessage = new Dictionary<int, string>();
 
-         private KeyValuePair<int, object[]> _msgInProcess = new KeyValuePair<int, object[]>((int)FSM_MSG.TIMER, null);
 
-         private long _msgCounter = 0;
 
-         List<FsmFunc> fsmFuncs = new List<FsmFunc>();
 
-         public StateMachine(string name, int initState = (int)FSM_STATE.UNDEFINE, int interval = 100)
 
-         {
 
-             Name = name + " FSM";
 
-             MaxMsgInQueue = 500;
 
-             this.State = initState;
 
-             this.PrevState = initState;
 
-             this.interval = interval;
 
-             cancelToken = new CancellationTokenSource();
 
-             _msgQueue = new BlockingCollection<KeyValuePair<int, object[]>>();
 
-             transition = new Dictionary<int, Dictionary<int, Tuple<FsmFunc, int>>>();
 
-             anyStateTransition = new Dictionary<int, Tuple<FsmFunc, int>>();
 
-             enterExitTransition = new Dictionary<int, Tuple<FsmFunc, int, FsmFunc>>();
 
-             EnumLoop<FSM_STATE>.ForEach((item) =>
 
-             {
 
-                 MapState((int)item, item.ToString());
 
-             });
 
-             EnumLoop<FSM_MSG>.ForEach((item) =>
 
-             {
 
-                 MapMessage((int)item, item.ToString());
 
-             });
 
-         }
 
-         #region Interface
 
-         public void Init(int initState, int intervalTimeMs)
 
-         {
 
-             State = initState;
 
-             interval = intervalTimeMs;
 
-         }
 
-         public void Start()
 
-         {
 
-             OnEnterState(this.State);
 
-         }
 
-         public void Loop()
 
-         {
 
-             while (!cancelToken.IsCancellationRequested)
 
-             {
 
-                 //_msgInProcess = timeoutMsg;
 
-                 try
 
-                 {
 
-                     KeyValuePair<int, object[]> msg = timeoutMsg;
 
-                     lock (_lockerMsgQueue)
 
-                     {
 
-                         if (!_msgQueue.TryTake(out msg, interval, cancelToken.Token))
 
-                             _msgInProcess = timeoutMsg;
 
-                         else
 
-                         {
 
-                             _msgInProcess = msg;
 
-                         }
 
-                     }
 
-                     //Loop AnyState迁移表
 
-                     
 
-                     if (anyStateTransition.ContainsKey(_msgInProcess.Key))
 
-                     {
 
-                         //if (anyStateTransition[_msgInProcess.Key].Item3 != null && !fsmFuncs.Keys.Contains(_msgInProcess.Key))
 
-                         //{
 
-                         //    fsmFuncs.Add(_msgInProcess.Key,anyStateTransition[_msgInProcess.Key].Item3);
 
-                         //}
 
-                         if (anyStateTransition[_msgInProcess.Key].Item1 != null)
 
-                         {
 
-                             if (anyStateTransition[_msgInProcess.Key].Item1(_msgInProcess.Value))  //need ChangeState
 
-                             {
 
-                                 if (anyStateTransition[_msgInProcess.Key].Item2 != State && anyStateTransition[_msgInProcess.Key].Item2 != (int)FSM_STATE.SAME)
 
-                                 {
 
-                                     OnExitState((int)FSM_STATE.ANY);
 
-                                     OnExitState(State);
 
-                                     enterTime = Environment.TickCount;
 
-                                     LastMsg = msg.Key;
 
-                                     PrevState = State;
 
-                                     State = anyStateTransition[_msgInProcess.Key].Item2;
 
-                                     ///add log
 
-                                     //if (Name == "EFEM FSM")
 
-                                     {
 
-                                         LOG.Write(eEvent.EV_FSM_NOTIFY, MECF.Framework.Common.Equipment.ModuleName.System, $"状态机 {Name}收到消息 {GetStringMessage(_msgInProcess.Key)}, 状态 {GetStringState(PrevState)}==>{GetStringState(State)}");
 
-                                     }
 
-                                     OnEnterState((int)FSM_STATE.ANY);
 
-                                     OnEnterState((int)State);
 
-                                 }
 
-                             }
 
-                         }
 
-                         if (_msgInProcess.Key != timeoutMsg.Key)
 
-                         {
 
-                             Interlocked.Decrement(ref _msgCounter);
 
-                             //System.Diagnostics.Trace.WriteLine($"message out1: {Name}--> {_msgCounter}");
 
-                         }
 
-                         continue;
 
-                     }
 
-                     foreach (var func in fsmFuncs)
 
-                     {
 
-                         func.Invoke(null);
 
-                     }
 
-                     if (!transition.ContainsKey(State))
 
-                     {
 
-                         if (_msgInProcess.Key != (int)FSM_MSG.TIMER)
 
-                         {
 
-                             LOG.Write(eEvent.WARN_FSM_WARN, MECF.Framework.Common.Equipment.ModuleName.System, $"StateMachine [{Name}] no definition of state [{GetStringState(State)}] ");
 
-                         }
 
-                         if (_msgInProcess.Key != timeoutMsg.Key)
 
-                         {
 
-                             Interlocked.Decrement(ref _msgCounter);
 
-                             //System.Diagnostics.Trace.WriteLine($"message out2: {Name} --> {_msgCounter}");
 
-                         }
 
-                         continue;
 
-                     }
 
-                     if (!transition[State].ContainsKey(_msgInProcess.Key))
 
-                     {
 
-                         if (_msgInProcess.Key != (int)FSM_MSG.TIMER)
 
-                         {
 
-                             LOG.Write(eEvent.WARN_FSM_WARN, MECF.Framework.Common.Equipment.ModuleName.System, $"StateMachine {Name} no definition of [state={GetStringState(State)}], [message={GetStringMessage(_msgInProcess.Key)}]");
 
-                         }
 
-                         if (_msgInProcess.Key != timeoutMsg.Key)
 
-                         {
 
-                             Interlocked.Decrement(ref _msgCounter);
 
-                             // System.Diagnostics.Trace.WriteLine($"message out3:{Name}--> {_msgCounter}");
 
-                         }
 
-                         continue;
 
-                     }
 
-                     //Loop Transition 
 
-                     //if fun is null or fun return true need change
 
-                     if (transition[State][_msgInProcess.Key].Item1 == null || transition[State][_msgInProcess.Key].Item1(_msgInProcess.Value))
 
-                     {
 
-                         if (transition[State][_msgInProcess.Key].Item2 != State && transition[State][_msgInProcess.Key].Item2 != (int)FSM_STATE.SAME)
 
-                         {
 
-                             OnExitState((int)FSM_STATE.ANY);
 
-                             OnExitState(State);
 
-                             enterTime = Environment.TickCount;
 
-                             PrevState = State;
 
-                             State = transition[State][_msgInProcess.Key].Item2;
 
-                             ///add log
 
-                             //if (Name == "EFEM FSM")
 
-                             {
 
-                                 LOG.Write(eEvent.EV_FSM_NOTIFY, MECF.Framework.Common.Equipment.ModuleName.System, $"状态机 {Name}收到消息 {GetStringMessage(_msgInProcess.Key)}, 状态 {GetStringState(PrevState)}==>{GetStringState(State)}");
 
-                             }
 
-                             OnEnterState((int)FSM_STATE.ANY);
 
-                             OnEnterState((int)State);
 
-                         }
 
-                     }
 
-                     if (_msgInProcess.Key != timeoutMsg.Key)
 
-                     {
 
-                         Interlocked.Decrement(ref _msgCounter);
 
-                         //System.Diagnostics.Trace.WriteLine($"message out4: {Name}--> {_msgCounter}");
 
-                     }
 
-                     _msgInProcess = timeoutMsg;
 
-                 }
 
-                 catch (OperationCanceledException)
 
-                 {
 
-                     LOG.Write(eEvent.EV_FSM_NOTIFY, MECF.Framework.Common.Equipment.ModuleName.System, $"FSM {Name} is canceled");
 
-                 }
 
-                 catch (Exception ex)
 
-                 {
 
-                     LOG.Write(eEvent.EV_FSM_NOTIFY, MECF.Framework.Common.Equipment.ModuleName.System, ex.StackTrace + ex.Message);
 
-                 }
 
-             }
 
-         }
 
-         public void Stop()
 
-         {
 
-             cancelToken.Cancel();
 
-         }
 
-         string GetStringState(int state)
 
-         {
 
-             if (_stringState.ContainsKey(state))
 
-                 return _stringState[state];
 
-             return state.ToString();
 
-         }
 
-         string GetStringMessage(int message)
 
-         {
 
-             if (_stringMessage.ContainsKey(message))
 
-                 return _stringMessage[message];
 
-             return message.ToString();          
 
-         }
 
-         public void MapState(int state, string stringState)
 
-         {
 
-             System.Diagnostics.Debug.Assert(!_stringState.ContainsKey(state));
 
-             _stringState[state] = stringState;
 
-         }
 
-         public  void MapMessage(int message, string stringMessage)
 
-         {
 
-             System.Diagnostics.Debug.Assert(!_stringMessage.ContainsKey(message));
 
-             _stringMessage[message] = stringMessage;
 
-         }
 
-         public bool FindTransition(int state, int msg)
 
-         {
 
-             if (anyStateTransition.ContainsKey(msg))
 
-                 return true;
 
-             if (transition.ContainsKey(state) && transition[state] != null)
 
-             {
 
-                 Dictionary<int, Tuple<FsmFunc, int>> table = transition[state];
 
-                 if (table.ContainsKey(msg))
 
-                     return true;
 
-             }
 
-             return false;
 
-         }
 
-         public void Transition(int state, int msg, FsmFunc func, int next)
 
-         {
 
-             if (!transition.ContainsKey(state) || transition[state] == null)
 
-             {
 
-                 transition[state] = new Dictionary<int, Tuple<FsmFunc, int>>();
 
-             }
 
-             transition[state][msg] = new Tuple<FsmFunc, int>(func, next);
 
-         }
 
-         public void AnyStateTransition(int msg, FsmFunc func, int next)
 
-         {
 
-             if (msg != timeoutMsg.Key)
 
-             {
 
-                 anyStateTransition[msg] = new Tuple<FsmFunc, int>(func, next);
 
-             }
 
-             else
 
-             {
 
-                 fsmFuncs.Add(func);
 
-             }
 
-         }
 
-         //public void AnyStateTransition(int msg, FsmFunc func, int next, FsmFunc monitorFunc)
 
-         //{
 
-         //    anyStateTransition[msg] = new Tuple<FsmFunc, int,FsmFunc>(func, next,monitorFunc);
 
-         //}
 
-         public void EnterExitTransition(int state, FsmFunc enter, int msg, FsmFunc exit)
 
-         {
 
-             enterExitTransition[state] = new Tuple<FsmFunc, int, FsmFunc>(enter, msg, exit);
 
-         }
 
-         public void EnableRepeatedMsg(bool enable)
 
-         {
 
-             _enableRepeatedMsg = enable;
 
-         }
 
-         public void PostMsg(int msg, params object[] args)
 
-         {
 
-             Interlocked.Increment(ref _msgCounter);
 
-             //lock (_lockerMsgQueue)
 
-             {
 
-                 _msgQueue.Add(new KeyValuePair<int, object[]>(msg, args));
 
-             }
 
-             //System.Diagnostics.Trace.WriteLine($"PostMsg: {msg}--> {_msgCounter}");
 
-         }
 
-         public void PostMsgWithoutLock(int msg, params object[] args)
 
-         {
 
-             Interlocked.Increment(ref _msgCounter);
 
-             _msgQueue.Add(new KeyValuePair<int, object[]>(msg, args));
 
-             //System.Diagnostics.Trace.WriteLine($"PostMsgWithoutLock: {msg}--> {_msgCounter}");
 
-         }
 
-         #endregion
 
-         private void OnEnterState(int state)
 
-         {
 
-             if (enterExitTransition.ContainsKey(state))
 
-             {
 
-                 if (enterExitTransition[state].Item1 != null)
 
-                 {
 
-                     enterExitTransition[state].Item1(null);
 
-                 }
 
-                 if (enterExitTransition[state].Item2 != (int)FSM_MSG.NONE)
 
-                 {
 
-                     PostMsg(enterExitTransition[state].Item2, null);
 
-                 }
 
-             }
 
-         }
 
-         private void OnExitState(int state)
 
-         {
 
-             if (enterExitTransition.ContainsKey(state))
 
-             {
 
-                 if (enterExitTransition[state].Item3 != null)
 
-                 {
 
-                     enterExitTransition[state].Item3(null);
 
-                 }
 
-             }
 
-         }
 
-         public bool CheckExecuted(int msg)
 
-         {
 
-             return _msgCounter == 0;
 
-             //lock (_lockerMsgQueue)
 
-             //{
 
-             //    foreach (var keyValuePair in _msgQueue)
 
-             //    {
 
-             //        if (keyValuePair.Key == msg)
 
-             //            return false;
 
-             //    }
 
-             //    if (_msgInProcess.Key == msg)
 
-             //        return false;
 
-             //}
 
-             //return true;
 
-         }
 
-         public bool CheckExecuted()
 
-         {
 
-             //System.Diagnostics.Trace.WriteLine($"CheckExecuted: --> {_msgCounter}");
 
-             return _msgCounter == 0;
 
-             //return Interlocked.CompareExchange(ref _msgCounter, 0, 0) == 0;
 
-             ////lock (_lockerMsgQueue)
 
-             //{
 
-             //    return _msgQueue.Count == 0 && _msgInProcess.Key==(int)FSM_MSG.TIMER;
 
-             //}
 
-         }
 
-         public bool CheckExecuted(int msg, out int currentMsg, out List<int> msgQueue)
 
-         {
 
-             currentMsg = 0;
 
-             msgQueue = new List<int>();
 
-             return _msgCounter == 0;
 
-             //lock (_lockerMsgQueue)
 
-             //{
 
-             //    currentMsg = 0;
 
-             //    msgQueue = new List<int>();
 
-             //    foreach (var keyValuePair in _msgQueue)
 
-             //    {
 
-             //        if (keyValuePair.Key == msg)
 
-             //            return false;
 
-             //        msgQueue.Add(keyValuePair.Key);
 
-             //    }
 
-             //    if (_msgInProcess.Key == msg)
 
-             //    {
 
-             //        return false;
 
-             //    }
 
-             //    currentMsg = _msgInProcess.Key;
 
-             //}
 
-             //return true;
 
-         }
 
-     }
 
- }
 
 
  |