using System; using System.Collections.Generic; using System.Threading; using System.Diagnostics; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using CyberX8_Core; using System.Reflection; using DocumentFormat.OpenXml.Wordprocessing; namespace Aitex.Core.RT.Fsm { public class Entity { protected Thread thread = null; protected IStateMachine fsm = null; public bool Running { get; protected set;} /// /// 剩余时长ToReady /// public virtual int TimeToReady { get { return int.MaxValue / 2; } } public Entity() { } public bool Initialize() { Init(); if (fsm != null) { fsm.Start(); thread = new Thread(new ThreadStart(fsm.Loop)); thread.Name = fsm.Name; thread.Start(); LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"Create Entity Thread {fsm.Name}"); while (!thread.IsAlive) Thread.Sleep(1); } return true; } public void Terminate() { if (fsm != null) { fsm.Stop(); } Term(); if (thread!=null&&thread.IsAlive) { Thread.Sleep(100); if (thread.IsAlive) { try { thread.Abort(); } catch (Exception ex) { LOG.WriteExeption(String.Format("Entity terminate has exception."), ex); } } } //Term(); } protected virtual bool Init() { return true; } protected virtual void Term() { } 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(T state,V msg,FsmFunc func,FsmFunc waitFunc,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,waitFunc, _next); } protected void Transition(int state, int msg, FsmFunc func, int next) { if (fsm != null) fsm.Transition(state, msg, func, next); } protected void Transition(int state, int msg, FsmFunc func,FsmFunc waitFunc, int next) { if (fsm != null) fsm.Transition(state, msg, func,waitFunc, next); } protected void AnyStateTransition(int msg, FsmFunc func, int next) { if (fsm != null) fsm.AnyStateTransition(msg, func, next); } //protected void AnyStateTransition(int msg, FsmFunc func, int next, FsmFunc monitorFunc) //{ // if (fsm != null) // fsm.AnyStateTransition(msg, func, next,monitorFunc); //} 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 AnyStateTransition(V msg, FsmFunc func, T next, FsmFunc monitorFunc) { Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum); int _next = Convert.ToInt32(next); int _msg = Convert.ToInt32(msg); AnyStateTransition(_msg, func, _next, monitorFunc); } 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.PostMsg(msg, args); } public bool CheckToPostMessage(eEvent eEvent,string moduleName,int msg, params object[] args) { string state = Enum.GetName(typeof(T), fsm.State); string strMsg = Enum.GetName(typeof(V), msg); if (!fsm.FindTransition(fsm.State, msg)) { LOG.WriteLog(eEvent, moduleName, $"{moduleName} is in {state} state,can not do {strMsg}"); return false; } Running = true; fsm.PostMsg(msg, args); LOG.WriteLog(eEvent.EV_FSM_NOTIFY, moduleName, $"{moduleName} is in {state} state,do {strMsg}"); return true; } public bool NullFunc(object[] param) { return true; } } }