FsmDevice.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using Aitex.Core.RT.Device;
  9. using Aitex.Core.RT.Event;
  10. using Aitex.Core.RT.Fsm;
  11. using Aitex.Core.RT.Log;
  12. namespace MECF.Framework.RT.ModuleLibrary.Commons
  13. {
  14. public class FsmDevice : BaseDevice, IDevice
  15. {
  16. private Thread _thread = null;
  17. private IStateMachine _fsm = null;
  18. public int FsmState
  19. {
  20. get { return _fsm.State; }
  21. }
  22. public int FsmPreviousState
  23. {
  24. get { return _fsm.PrevState; }
  25. }
  26. public string StringFsmStatus
  27. {
  28. get
  29. {
  30. return _fsmStateMap.ContainsKey(FsmState) ? _fsmStateMap[FsmState] : FsmState.ToString();
  31. }
  32. }
  33. public int FsmLastMessage
  34. {
  35. get
  36. {
  37. return _fsm.LastMsg;
  38. }
  39. }
  40. Dictionary<int, string> _fsmStateMap = new Dictionary<int, string>();
  41. Dictionary<int, string> _fsmMessageMap = new Dictionary<int, string>();
  42. public FsmDevice() : base()
  43. {
  44. }
  45. public void MapState(int state, string stringState)
  46. {
  47. _fsmStateMap[state] = stringState;
  48. }
  49. public void MapMessage(int msg, string stringMessage)
  50. {
  51. _fsmMessageMap[msg] = stringMessage;
  52. }
  53. public void EnableFsm(int fsmInterval, object initState)
  54. {
  55. EnableFsm(fsmInterval, (int)initState);
  56. }
  57. public void EnableFsm(int fsmInterval, int initState)
  58. {
  59. _fsm = new StateMachine($"{Module} {Name} FSM", initState, fsmInterval);
  60. _fsm.Start();
  61. _thread = new Thread(new ThreadStart(_fsm.Loop));
  62. _thread.Name = _fsm.Name;
  63. _thread.Start();
  64. while (!_thread.IsAlive)
  65. Thread.Sleep(1);
  66. }
  67. public virtual bool Initialize()
  68. {
  69. return true;
  70. }
  71. public virtual void Monitor()
  72. {
  73. }
  74. public virtual void Terminate()
  75. {
  76. if (_fsm != null)
  77. {
  78. _fsm.Stop();
  79. }
  80. if (_thread != null)
  81. {
  82. if (_thread.IsAlive)
  83. {
  84. Thread.Sleep(100);
  85. if (_thread.IsAlive)
  86. {
  87. try
  88. {
  89. _thread.Abort();
  90. }
  91. catch (Exception ex)
  92. {
  93. LOG.Error(String.Format("Entity terminate has exception."), ex);
  94. }
  95. }
  96. }
  97. }
  98. //Term();
  99. }
  100. public virtual void Reset()
  101. {
  102. }
  103. protected void Transition<T, V>(T state, V msg, FsmFunc func, T next)
  104. {
  105. Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum);
  106. int _state = Convert.ToInt32(state);
  107. int _next = Convert.ToInt32(next);
  108. int _msg = Convert.ToInt32(msg);
  109. Transition(_state, _msg, func, _next);
  110. }
  111. protected void Transition(int state, int msg, FsmFunc func, int next)
  112. {
  113. if (_fsm != null)
  114. _fsm.Transition(state, msg, func, next);
  115. }
  116. protected void AnyStateTransition(int msg, FsmFunc func, int next)
  117. {
  118. if (_fsm != null)
  119. _fsm.AnyStateTransition(msg, func, next);
  120. }
  121. protected void AnyStateTransition<T, V>(V msg, FsmFunc func, T next)
  122. {
  123. Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum);
  124. int _next = Convert.ToInt32(next);
  125. int _msg = Convert.ToInt32(msg);
  126. AnyStateTransition(_msg, func, _next);
  127. }
  128. protected void EnterExitTransition<T, V>(T state, FsmFunc enter, Nullable<V> msg, FsmFunc exit) where V : struct
  129. {
  130. Debug.Assert(typeof(T).IsEnum && ((msg == null) || typeof(V).IsEnum));
  131. int _state = Convert.ToInt32(state);
  132. int _msg = msg == null ? (int)FSM_MSG.NONE : Convert.ToInt32(msg);
  133. EnterExitTransition(_state, enter, _msg, exit);
  134. }
  135. protected void EnterExitTransition(int state, FsmFunc enter, int msg, FsmFunc exit)
  136. {
  137. if (_fsm != null)
  138. _fsm.EnterExitTransition(state, enter, msg, exit);
  139. }
  140. public void PostMsg<T>(T msg, params object[] args) where T : struct
  141. {
  142. Debug.Assert(typeof(T).IsEnum);
  143. int id = Convert.ToInt32(msg);
  144. PostMsg(id, args);
  145. }
  146. public void PostMsg(int msg, params object[] args)
  147. {
  148. if (_fsm == null)
  149. {
  150. LOG.Error($"fsm is null, post msg {msg}");
  151. return;
  152. }
  153. _fsm.PostMsgWithoutLock(msg, args);
  154. }
  155. public bool CheckAllMessageProcessed()
  156. {
  157. return _fsm.CheckExecuted();
  158. }
  159. public bool CheckExecuted(int msg)
  160. {
  161. return _fsm.CheckExecuted(msg);
  162. }
  163. public bool CheckToPostMessage<T>(T msg, params object[] args)
  164. {
  165. return CheckToPostMessage(Convert.ToInt32(msg), args);
  166. }
  167. public bool CheckToPostMessage(int msg, params object[] args)
  168. {
  169. int state = _fsm.State;
  170. string status = _fsmStateMap[state];
  171. if (!_fsm.FindTransition(_fsm.State, msg))
  172. {
  173. string message = string.Empty;
  174. if (_fsmMessageMap.ContainsKey(msg))
  175. message = _fsmMessageMap[msg];
  176. else
  177. {
  178. message = msg.ToString();
  179. }
  180. EV.PostWarningLog(Module, $"{Name} is in {status} state,can not do {message}");
  181. return false;
  182. }
  183. _fsm.PostMsg(msg, args);
  184. return true;
  185. }
  186. }
  187. }