DiosSMachine.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. #pragma once
  2. // 下列 ifdef 块是创建使从 DLL 导出更简单的
  3. // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DIOSSMACHINE_EXPORTS
  4. // 符号编译的。在使用此 DLL 的
  5. // 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
  6. // DIOSSMACHINE_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
  7. // 符号视为是被导出的。
  8. #ifndef DIOSSMACHINE_EXPORTS
  9. #ifdef _WIN64
  10. #ifdef _DEBUG
  11. #pragma comment(lib, "DiosSMachineX64D.lib")
  12. #else
  13. #pragma comment(lib, "DiosSMachineX64.lib")
  14. #endif
  15. #else
  16. #ifdef _DEBUG
  17. #pragma comment(lib, "DiosSMachineD.lib")
  18. #else
  19. #pragma comment(lib, "DiosSMachine.lib")
  20. #endif
  21. #endif
  22. #endif
  23. #ifdef DIOSSMACHINE_EXPORTS
  24. #define DIOSSMACHINE_API __declspec(dllexport)
  25. #define DIOSSMACHINE_C_API extern "C" __declspec(dllexport)
  26. #else
  27. #define DIOSSMACHINE_API __declspec(dllimport)
  28. #define DIOSSMACHINE_C_API extern "C" __declspec(dllimport)
  29. #endif
  30. #include "ResDataObject.h"
  31. #include "DiosThread.h"
  32. #include "MsgCircle.h"
  33. #include "DiosLock.h"
  34. #include <map>
  35. using namespace std;
  36. #define TIMEOUT_TEMP (3000)
  37. #define DiosErrorType "Error"
  38. //行为,失败,超时等正常执行时错误
  39. #define DiosFrameError "Frame"
  40. //人为的错误发送
  41. #define DiosSeqError "Seq"
  42. #define DiosStmEntryPosName "StateMachineEntry"
  43. #define DiosStmExitPosName "StateMachineExit"
  44. typedef enum _DiosStMachineRet
  45. {
  46. DIOSSMRET_NG,
  47. DIOSSMRET_OK,
  48. DIOSSMRET_TIMEOUT,
  49. DIOSSMRET_MAX
  50. }DIOSSTMRET;
  51. //assert,通用的事件和錯誤的事件處理上有所不同
  52. //最终有个==的判断,到时候错误和事件的处理方案不一样
  53. #define DiosStmEvtInfo "DiosStmEvtInfo"
  54. //JSON格式,EVT事件相关的必须有,而INFO相关的是附加内容,可有可无
  55. /*
  56. {
  57. "evtkey" : "evt内容",
  58. "DiosStmEvtInfo" : "错误内容 or 事件INFO or 其他附加信息"
  59. }
  60. */
  61. class DIOSSMACHINE_API DiosStMEvt
  62. {
  63. ResDataObject *m_pEvt;
  64. ResDataObject *m_pInfo;
  65. public:
  66. DiosStMEvt();
  67. DiosStMEvt(const DiosStMEvt &tValue);
  68. ~DiosStMEvt();
  69. bool SetEvt(const char* pKey, INT Val, const char *pInfo = NULL);
  70. bool SetEvt(const char* pKey, const char *pVal, const char *pInfo = NULL);
  71. DiosStMEvt& operator = (const DiosStMEvt &tValue);
  72. bool operator == (const DiosStMEvt &Obj);
  73. const char *encode();
  74. bool decode(const char *pdata);
  75. bool IsEmpty();
  76. };
  77. //state route pos
  78. class DIOSSMACHINE_API DiosStMRouteLine
  79. {
  80. bool m_ActiveState;
  81. bool m_InRoute;
  82. DWORD m_Timeout;
  83. DiosStMEvt *m_pEvt;
  84. string *m_pSrcRoutePos;
  85. string *m_pGuard;
  86. string *m_pDesRoutePos;
  87. public:
  88. DiosStMRouteLine();
  89. DiosStMRouteLine(const DiosStMRouteLine &tValue);
  90. virtual ~DiosStMRouteLine();
  91. void SetRoute(DiosStMEvt &evt, const char* pGuard, const char* pDes);
  92. void SetRoute(DiosStMEvt &evt, const char* pSrc,const char* pGuard, const char* pDes);
  93. const char* GetDesName();
  94. const char* GetSrcName();
  95. const char* GetGuardName();
  96. bool GetRouteType();//true:in,false:out
  97. void Active(bool state, DWORD timeout);
  98. bool GetActiveState();
  99. operator DiosStMEvt *();
  100. DiosStMRouteLine& operator = (const DiosStMRouteLine &tValue);
  101. DWORD GetTimeout();
  102. };
  103. class DIOSSMACHINE_API DiosStMRoutePos
  104. {
  105. bool m_ActiveState;
  106. DWORD m_Timeout;
  107. string *m_pRoutePosName;
  108. vector<DiosStMRouteLine *> *m_pOutRouteLineVec;
  109. public:
  110. DiosStMRoutePos();
  111. DiosStMRoutePos(const char *pName);
  112. virtual ~DiosStMRoutePos();
  113. virtual bool IsSMachine();//no
  114. void SetName(const char *pName);
  115. const char* GetName();
  116. bool PosAddOutRouteLine(DiosStMEvt &Evt, const char *pSrcPosName, const char *pGuardName, const char *pDesPosName);
  117. DWORD GetRouteLineCount();
  118. DiosStMRouteLine **GetOutRouteLineVec();
  119. DiosStMRouteLine *operator [](DiosStMEvt &Evt);
  120. void Active(bool state, DWORD timeout);
  121. bool GetActiveState();
  122. DWORD GetTimeout();
  123. };
  124. class DIOSSMACHINE_API DiosSMachineIF : public DiosLock
  125. {
  126. HANDLE m_StateCangeEvt;
  127. HANDLE m_RunningState;
  128. DiosStMRouteLine* StateMachineWaitForEvents(int &ExtEvtIndex);//[< 0]:Local or outline, [>= 0]: externalEvtIndex
  129. protected:
  130. DiosStMRoutePos *m_pCurrentRoutePos;
  131. MsgCircle<DiosStMEvt> *m_pArrivedEvts;
  132. //routepos
  133. map<string, DiosStMRoutePos*> *m_pRoutePosMap;
  134. //inline
  135. vector<DiosStMRouteLine*> *m_pRouteInLineMap;
  136. //external
  137. size_t m_RouteExternalEvtCount;
  138. DiosStMRouteLine** m_pRouteExternalMap;
  139. void ClearState();//reset
  140. DIOSSTMRET TransToPos(const char *pPosName);
  141. void PostError(const char *pErrorVal,const char *pErrorInfo = NULL);
  142. DiosStMRouteLine *GetEntryRouteLine();
  143. INT ExecStateMachine(DiosStMRouteLine *pExternalWaitEvts[], size_t WaitCount);
  144. INT EnterSubStateMachine();
  145. bool PrePareStateMachine();
  146. bool GetRunningState(DWORD waittime = 0);
  147. void SetRunningState(bool Running);
  148. public:
  149. DiosSMachineIF(void);
  150. virtual ~DiosSMachineIF(void);
  151. //for this IF
  152. virtual bool IsSMachine();//yes
  153. void CopyEvtTo(DiosSMachineIF *pDes);
  154. //init state machine
  155. //第一个节点的接入比较特殊,所以做了个函数
  156. bool AddEntryRoutePos(DiosStMRoutePos *pPos);
  157. bool AddRoutePos(DiosStMRoutePos *pPos);
  158. bool AddInRouteLine(DiosStMEvt &Evt, const char *pGuardName, const char *pDesPosName);
  159. bool AddOutRouteLine(DiosStMEvt &Evt,const char *pSrcPosName,const char *pGuardName,const char *pDesPosName);
  160. //active state machine
  161. bool ActiveRoutePos(const char *pPosName, DWORD timeout = TIMEOUT_TEMP);
  162. bool ActiveRouteLine(DiosStMEvt &Evt, DWORD timeout = TIMEOUT_TEMP);
  163. bool DeActiveAll();
  164. DiosStMRoutePos *GetCurrentRoutePos();
  165. //evt
  166. bool PushEvent(DiosStMEvt &Evt);
  167. bool PopEvent(DiosStMEvt &Evt);
  168. bool PeekEvent(DiosStMEvt &Evt);
  169. HANDLE GetEvtNotifyHandle();
  170. HANDLE GetStateChangeEvtHandle();
  171. //for state machine thread
  172. virtual DIOSSTMRET StateMachineEntry(DWORD timeout);//Begin状态点
  173. virtual DIOSSTMRET StateMachineExit(DWORD timeout);//End状态点
  174. virtual DIOSSTMRET StateMachineAction(const char *pAction, DWORD timeout);
  175. virtual DIOSSTMRET StateMachineGuard(const char *pGuard, DWORD timeout);
  176. //返回值的定义
  177. //因为全局事件,本状态机事件,本状态点事件都需要监控
  178. //所以
  179. //返回值为负:退出状态机
  180. //返回值为正: 0 <= EvtIdx < CountOfLocal + CountOfExternal + CountOfOutpath
  181. // 至于那个数组的事件,可以自行推算
  182. // 例: Outpath第二个事件 => EvtIdx = CountOfLocal + CountOfExternal + 1
  183. //关于TIMEOUT:函数中wait的是OutpathEvts,LocalEvts和ExternalEvts是没有必要等待,有就有,没有就没有....
  184. virtual int StateMachineWaitForEvents(
  185. DiosStMRouteLine *pLocalEvts[], DWORD CountOfLocal,
  186. DiosStMRouteLine *pExternalEvts[], DWORD CountOfExternal,
  187. DiosStMRouteLine *pOutpathEvts[], DWORD CountOfOutpath,
  188. DWORD timeout
  189. );
  190. };
  191. class DIOSSMACHINE_API DiosSMachine : public Dios_Thread,public DiosSMachineIF
  192. {
  193. protected:
  194. virtual bool OnStartThread();
  195. virtual bool Exec();
  196. public:
  197. DiosSMachine(void);
  198. virtual ~DiosSMachine(void);
  199. //for other threads to call
  200. bool StartStateMachine(DiosStMRouteLine *pExternalWaitEvts[], DWORD WaitCount);
  201. void StopStateMachine(DWORD timeout);
  202. };
  203. class DIOSSMACHINE_API DiosSubSMachine : public DiosStMRoutePos, public DiosSMachineIF
  204. {
  205. protected:
  206. public:
  207. DiosSubSMachine(void);
  208. DiosSubSMachine(const char *pName);
  209. virtual ~DiosSubSMachine(void);
  210. virtual bool IsSMachine();//yes
  211. };