CcosSMachine.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. #pragma once
  2. #define CCOSSMACHINE_API
  3. #define CCOSSMACHINE_C_API extern "C"
  4. #include "ResDataObject.h"
  5. #include "CcosThread.h"
  6. #include "MsgCircle.h"
  7. #include "CcosLock.h"
  8. #include "MsgQueue.h"
  9. #include <map>
  10. using namespace std;
  11. #define TIMEOUT_TEMP (3000)
  12. #define CcosErrorType "Error"
  13. //行为,失败,超时等正常执行时错误
  14. #define CcosFrameError "Frame"
  15. //人为的错误发送
  16. #define CcosSeqError "Seq"
  17. #define CcosStmEntryPosName "StateMachineEntry"
  18. #define CcosStmExitPosName "StateMachineExit"
  19. #define CcosTopStateMachineName ("SMOuter")
  20. typedef enum _CcosStMachineRet
  21. {
  22. CCOSSMRET_NG,
  23. CCOSSMRET_OK,
  24. CCOSSMRET_TIMEOUT,
  25. CCOSSMRET_EXIT,
  26. CCOSSMRET_MAX
  27. }CCOSSTMRET;
  28. //assert,通用的事件和錯誤的事件處理上有所不同
  29. //最终有个==的判断,到时候错误和事件的处理方案不一样
  30. #define CcosStmEvtInfo "CcosStmEvtInfo"
  31. //JSON格式,EVT事件相关的必须有,而INFO相关的是附加内容,可有可无
  32. /*
  33. {
  34. "evtkey" : "evt内容",
  35. "CcosStmEvtInfo" : "错误内容 or 事件INFO or 其他附加信息"
  36. }
  37. */
  38. class CCOSSMACHINE_API CcosStMEvt
  39. {
  40. ResDataObject *m_pEvt;
  41. ResDataObject *m_pInfo;
  42. public:
  43. CcosStMEvt();
  44. CcosStMEvt(const CcosStMEvt &tValue);
  45. ~CcosStMEvt();
  46. bool SetEvt(const char* pKey, int Val, const char *pInfo = NULL);
  47. bool SetEvt(const char* pKey, const char *pVal, const char *pInfo = NULL);
  48. CcosStMEvt& operator = (const CcosStMEvt &tValue);
  49. bool operator == (const CcosStMEvt &Obj);
  50. const char *encode();
  51. bool decode(const char *pdata);
  52. bool IsEmpty();
  53. ResDataObject& GetEvtContext();
  54. };
  55. //state route pos
  56. class CCOSSMACHINE_API CcosStMRouteLine
  57. {
  58. bool m_ActiveState;
  59. bool m_InRoute;
  60. DWORD m_Timeout;
  61. CcosStMEvt *m_pEvt;
  62. string *m_pSrcRoutePos;
  63. string *m_pGuard;
  64. string *m_pDesRoutePos;
  65. public:
  66. CcosStMRouteLine();
  67. CcosStMRouteLine(const CcosStMRouteLine &tValue);
  68. virtual ~CcosStMRouteLine();
  69. void SetRoute(CcosStMEvt &evt, const char* pGuard, const char* pDes);
  70. void SetRoute(CcosStMEvt &evt, const char* pSrc,const char* pGuard, const char* pDes);
  71. const char* GetDesName();
  72. const char* GetSrcName();
  73. const char* GetGuardName();
  74. bool GetRouteType();//true:in,false:out
  75. void Active(bool state, DWORD timeout);
  76. bool GetActiveState();
  77. operator CcosStMEvt *();
  78. CcosStMRouteLine& operator = (const CcosStMRouteLine &tValue);
  79. DWORD GetTimeout();
  80. };
  81. class CCOSSMACHINE_API CcosStMRoutePos
  82. {
  83. bool m_ActiveState;
  84. DWORD m_Timeout;
  85. string *m_pRoutePosName;
  86. vector<CcosStMRouteLine *> *m_pOutRouteLineVec;
  87. public:
  88. CcosStMRoutePos();
  89. CcosStMRoutePos(const char *pName);
  90. virtual ~CcosStMRoutePos();
  91. virtual bool IsSMachine();//no
  92. void SetName(const char *pName);
  93. const char* GetName();
  94. bool PosAddOutRouteLine(CcosStMEvt &Evt, const char *pSrcPosName, const char *pGuardName, const char *pDesPosName);
  95. DWORD GetRouteLineCount();
  96. CcosStMRouteLine **GetOutRouteLineVec();
  97. CcosStMRouteLine *operator [](CcosStMEvt &Evt);
  98. void Active(bool state, DWORD timeout);
  99. bool GetActiveState();
  100. DWORD GetTimeout();
  101. };
  102. class CCOSSMACHINE_API CcosSMachineIF : public CcosLock
  103. {
  104. CcosSMachineIF *m_pParent;
  105. string *m_pStateMachineName;
  106. std::shared_ptr<LinuxEvent> m_StateCangeEvt;
  107. std::shared_ptr<LinuxEvent> m_RunningState;
  108. CcosStMRouteLine* StateMachineWaitForEvents(int &ExtEvtIndex, CcosStMEvt& Evt);//[< 0]:Local or outline, [>= 0]: externalEvtIndex
  109. protected:
  110. CcosStMRoutePos *m_pCurrentRoutePos;
  111. MsgCircle<CcosStMEvt> *m_pArrivedEvts;
  112. //routepos
  113. map<string, CcosStMRoutePos*> *m_pRoutePosMap;
  114. //inline
  115. vector<CcosStMRouteLine*> *m_pRouteInLineMap;
  116. //external
  117. size_t m_RouteExternalEvtCount;
  118. CcosStMRouteLine** m_pRouteExternalMap;
  119. void ClearState(bool bClearEvent = true);//reset
  120. CCOSSTMRET TransToPos(const char *pPosName);
  121. void PostError(const char *pErrorVal,const char *pErrorInfo = NULL);
  122. CcosStMRouteLine *GetEntryRouteLine();
  123. int ExecStateMachine(std::shared_ptr<LinuxEvent> ThreadExitEvt,CcosStMRouteLine *pExternalWaitEvts[], size_t , bool bClear = true);
  124. int EnterSubStateMachine(std::shared_ptr<LinuxEvent> ThreadExitEvt, CcosStMEvt& Evt);
  125. bool PrePareStateMachine();
  126. bool GetRunningState(DWORD waittime = 0);
  127. void SetRunningState(bool Running);
  128. virtual void PushStateChange(ResDataObject &ChangedPos);//statemachinename:statemachinepos
  129. public:
  130. CcosSMachineIF(void);
  131. virtual ~CcosSMachineIF(void);
  132. void SetStateMachineName(const char *pszName);
  133. const char *GetStateMachineName();
  134. void SetParentSMachine(CcosSMachineIF *pParent);
  135. //for this IF
  136. virtual bool IsSMachine();//yes
  137. void CopyEvtTo(CcosSMachineIF *pDes);
  138. //init state machine
  139. //第一个节点的接入比较特殊,所以做了个函数
  140. bool AddEntryRoutePos(CcosStMRoutePos *pPos);
  141. bool AddRoutePos(CcosStMRoutePos *pPos);
  142. bool AddInRouteLine(CcosStMEvt &Evt, const char *pGuardName, const char *pDesPosName);
  143. bool AddOutRouteLine(CcosStMEvt &Evt,const char *pSrcPosName,const char *pGuardName,const char *pDesPosName);
  144. //active state machine
  145. bool ActiveRoutePos(const char *pPosName, DWORD timeout = TIMEOUT_TEMP);
  146. bool ActiveRouteLine(CcosStMEvt &Evt, DWORD timeout = TIMEOUT_TEMP);
  147. bool DeActiveAll();
  148. CcosStMRoutePos *GetCurrentRoutePos();
  149. //evt
  150. bool PushEvent(CcosStMEvt &Evt);
  151. bool PopEvent(CcosStMEvt &Evt);
  152. bool PeekEvent(CcosStMEvt &Evt);
  153. std::shared_ptr<LinuxEvent> GetEvtNotifyHandle();
  154. std::shared_ptr<LinuxEvent> GetStateChangeEvtHandle();
  155. //for state machine thread
  156. virtual CCOSSTMRET StateMachineEntry(DWORD timeout);//Begin状态点
  157. virtual CCOSSTMRET StateMachineExit(DWORD timeout);//End状态点
  158. virtual CCOSSTMRET StateMachineAction(const char *pAction, DWORD timeout);
  159. virtual CCOSSTMRET StateMachineGuard(const char *pGuard, DWORD timeout);
  160. //返回值的定义
  161. //因为全局事件,本状态机事件,本状态点事件都需要监控
  162. //所以
  163. //返回值为负:退出状态机
  164. //返回值为正: 0 <= EvtIdx < CountOfLocal + CountOfExternal + CountOfOutpath
  165. // 至于那个数组的事件,可以自行推算
  166. // 例: Outpath第二个事件 => EvtIdx = CountOfLocal + CountOfExternal + 1
  167. //关于TIMEOUT:函数中wait的是OutpathEvts,LocalEvts和ExternalEvts是没有必要等待,有就有,没有就没有....
  168. virtual int StateMachineWaitForEvents(
  169. CcosStMRouteLine *pLocalEvts[], DWORD CountOfLocal,
  170. CcosStMRouteLine *pExternalEvts[], DWORD CountOfExternal,
  171. CcosStMRouteLine *pOutpathEvts[], DWORD CountOfOutpath,
  172. DWORD timeout, CcosStMEvt& Evt
  173. );
  174. };
  175. class CCOSSMACHINE_API CcosSMachine : public Ccos_Thread,public CcosSMachineIF
  176. {
  177. protected:
  178. virtual bool OnStartThread();
  179. virtual bool Exec();
  180. std::shared_ptr<LinuxEvent> m_StateQuedEvent;
  181. ResDataObject m_LastHitStatePos;
  182. MsgQueue<ResDataObject> *m_pStatePosList;
  183. virtual void PushStateChange(ResDataObject &ChangedPos);//statemachinename:statemachinepos
  184. public:
  185. CcosSMachine(void);
  186. virtual ~CcosSMachine(void);
  187. void SetStateMachineLog(const char *pszLogTitle);
  188. bool PopStateChange(ResDataObject &LastPos);
  189. std::shared_ptr<LinuxEvent> GetStateQuedEvent();
  190. //for other threads to call
  191. bool StartStateMachine(CcosStMRouteLine *pExternalWaitEvts[], DWORD WaitCount);
  192. void StopStateMachine(DWORD timeout);
  193. };
  194. class CCOSSMACHINE_API CcosSubSMachine : public CcosStMRoutePos, public CcosSMachineIF
  195. {
  196. protected:
  197. public:
  198. CcosSubSMachine(void);
  199. CcosSubSMachine(const char *pName);
  200. virtual ~CcosSubSMachine(void);
  201. virtual bool IsSMachine();//yes
  202. };