123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- #pragma once
- // 下列 ifdef 块是创建使从 DLL 导出更简单的
- // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DIOSSMACHINE_EXPORTS
- // 符号编译的。在使用此 DLL 的
- // 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
- // DIOSSMACHINE_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
- // 符号视为是被导出的。
- #ifndef DIOSSMACHINE_EXPORTS
- #ifdef _WIN64
- #ifdef _DEBUG
- #pragma comment(lib, "DiosSMachineX64D.lib")
- #else
- #pragma comment(lib, "DiosSMachineX64.lib")
- #endif
- #else
- #ifdef _DEBUG
- #pragma comment(lib, "DiosSMachineD.lib")
- #else
- #pragma comment(lib, "DiosSMachine.lib")
- #endif
- #endif
- #endif
- #ifdef DIOSSMACHINE_EXPORTS
- #define DIOSSMACHINE_API __declspec(dllexport)
- #define DIOSSMACHINE_C_API extern "C" __declspec(dllexport)
- #else
- #define DIOSSMACHINE_API __declspec(dllimport)
- #define DIOSSMACHINE_C_API extern "C" __declspec(dllimport)
- #endif
- #include "ResDataObject.h"
- #include "DiosThread.h"
- #include "MsgCircle.h"
- #include "DiosLock.h"
- #include "MsgQueue.h"
- #include <map>
- using namespace std;
- #define TIMEOUT_TEMP (3000)
- #define DiosErrorType "Error"
- //行为,失败,超时等正常执行时错误
- #define DiosFrameError "Frame"
- //人为的错误发送
- #define DiosSeqError "Seq"
- #define DiosStmEntryPosName "StateMachineEntry"
- #define DiosStmExitPosName "StateMachineExit"
- #define DiosTopStateMachineName ("SMOuter")
- typedef enum _DiosStMachineRet
- {
- DIOSSMRET_NG,
- DIOSSMRET_OK,
- DIOSSMRET_TIMEOUT,
- DIOSSMRET_EXIT,
- DIOSSMRET_MAX
- }DIOSSTMRET;
- //assert,通用的事件和錯誤的事件處理上有所不同
- //最终有个==的判断,到时候错误和事件的处理方案不一样
- #define DiosStmEvtInfo "DiosStmEvtInfo"
- //JSON格式,EVT事件相关的必须有,而INFO相关的是附加内容,可有可无
- /*
- {
- "evtkey" : "evt内容",
- "DiosStmEvtInfo" : "错误内容 or 事件INFO or 其他附加信息"
- }
- */
- class DIOSSMACHINE_API DiosStMEvt
- {
- ResDataObject *m_pEvt;
- ResDataObject *m_pInfo;
- public:
- DiosStMEvt();
- DiosStMEvt(const DiosStMEvt &tValue);
- ~DiosStMEvt();
- bool SetEvt(const char* pKey, INT Val, const char *pInfo = NULL);
- bool SetEvt(const char* pKey, const char *pVal, const char *pInfo = NULL);
- DiosStMEvt& operator = (const DiosStMEvt &tValue);
- bool operator == (const DiosStMEvt &Obj);
- const char *encode();
- bool decode(const char *pdata);
- bool IsEmpty();
- ResDataObject& GetEvtContext();
- };
- //state route pos
- class DIOSSMACHINE_API DiosStMRouteLine
- {
- bool m_ActiveState;
- bool m_InRoute;
- DWORD m_Timeout;
- DiosStMEvt *m_pEvt;
- string *m_pSrcRoutePos;
- string *m_pGuard;
- string *m_pDesRoutePos;
- public:
- DiosStMRouteLine();
- DiosStMRouteLine(const DiosStMRouteLine &tValue);
- virtual ~DiosStMRouteLine();
- void SetRoute(DiosStMEvt &evt, const char* pGuard, const char* pDes);
- void SetRoute(DiosStMEvt &evt, const char* pSrc,const char* pGuard, const char* pDes);
- const char* GetDesName();
- const char* GetSrcName();
- const char* GetGuardName();
- bool GetRouteType();//true:in,false:out
- void Active(bool state, DWORD timeout);
- bool GetActiveState();
- operator DiosStMEvt *();
- DiosStMRouteLine& operator = (const DiosStMRouteLine &tValue);
- DWORD GetTimeout();
- };
- class DIOSSMACHINE_API DiosStMRoutePos
- {
- bool m_ActiveState;
- DWORD m_Timeout;
- string *m_pRoutePosName;
- vector<DiosStMRouteLine *> *m_pOutRouteLineVec;
- public:
- DiosStMRoutePos();
- DiosStMRoutePos(const char *pName);
- virtual ~DiosStMRoutePos();
- virtual bool IsSMachine();//no
- void SetName(const char *pName);
- const char* GetName();
- bool PosAddOutRouteLine(DiosStMEvt &Evt, const char *pSrcPosName, const char *pGuardName, const char *pDesPosName);
- DWORD GetRouteLineCount();
- DiosStMRouteLine **GetOutRouteLineVec();
- DiosStMRouteLine *operator [](DiosStMEvt &Evt);
- void Active(bool state, DWORD timeout);
- bool GetActiveState();
- DWORD GetTimeout();
- };
- class DIOSSMACHINE_API DiosSMachineIF : public DiosLock
- {
- DiosSMachineIF *m_pParent;
- string *m_pStateMachineName;
- HANDLE m_StateCangeEvt;
- HANDLE m_RunningState;
- DiosStMRouteLine* StateMachineWaitForEvents(int &ExtEvtIndex, DiosStMEvt& Evt);//[< 0]:Local or outline, [>= 0]: externalEvtIndex
- protected:
- DiosStMRoutePos *m_pCurrentRoutePos;
- MsgCircle<DiosStMEvt> *m_pArrivedEvts;
- //routepos
- map<string, DiosStMRoutePos*> *m_pRoutePosMap;
- //inline
- vector<DiosStMRouteLine*> *m_pRouteInLineMap;
- //external
- size_t m_RouteExternalEvtCount;
- DiosStMRouteLine** m_pRouteExternalMap;
- void ClearState(bool bClearEvent = true);//reset
- DIOSSTMRET TransToPos(const char *pPosName);
- void PostError(const char *pErrorVal,const char *pErrorInfo = NULL);
- DiosStMRouteLine *GetEntryRouteLine();
- INT ExecStateMachine(HANDLE ThreadExitEvt,DiosStMRouteLine *pExternalWaitEvts[], size_t , bool bClear = true);
- INT EnterSubStateMachine(HANDLE ThreadExitEvt, DiosStMEvt& Evt);
- bool PrePareStateMachine();
- bool GetRunningState(DWORD waittime = 0);
- void SetRunningState(bool Running);
- virtual void PushStateChange(ResDataObject &ChangedPos);//statemachinename:statemachinepos
- public:
- DiosSMachineIF(void);
- virtual ~DiosSMachineIF(void);
- void SetStateMachineName(const char *pszName);
-
- const char *GetStateMachineName();
- void SetParentSMachine(DiosSMachineIF *pParent);
- //for this IF
- virtual bool IsSMachine();//yes
- void CopyEvtTo(DiosSMachineIF *pDes);
- //init state machine
- //第一个节点的接入比较特殊,所以做了个函数
- bool AddEntryRoutePos(DiosStMRoutePos *pPos);
- bool AddRoutePos(DiosStMRoutePos *pPos);
- bool AddInRouteLine(DiosStMEvt &Evt, const char *pGuardName, const char *pDesPosName);
- bool AddOutRouteLine(DiosStMEvt &Evt,const char *pSrcPosName,const char *pGuardName,const char *pDesPosName);
- //active state machine
- bool ActiveRoutePos(const char *pPosName, DWORD timeout = TIMEOUT_TEMP);
- bool ActiveRouteLine(DiosStMEvt &Evt, DWORD timeout = TIMEOUT_TEMP);
- bool DeActiveAll();
- DiosStMRoutePos *GetCurrentRoutePos();
- //evt
- bool PushEvent(DiosStMEvt &Evt);
- bool PopEvent(DiosStMEvt &Evt);
- bool PeekEvent(DiosStMEvt &Evt);
- HANDLE GetEvtNotifyHandle();
- HANDLE GetStateChangeEvtHandle();
- //for state machine thread
- virtual DIOSSTMRET StateMachineEntry(DWORD timeout);//Begin状态点
- virtual DIOSSTMRET StateMachineExit(DWORD timeout);//End状态点
- virtual DIOSSTMRET StateMachineAction(const char *pAction, DWORD timeout);
- virtual DIOSSTMRET StateMachineGuard(const char *pGuard, DWORD timeout);
- //返回值的定义
- //因为全局事件,本状态机事件,本状态点事件都需要监控
- //所以
- //返回值为负:退出状态机
- //返回值为正: 0 <= EvtIdx < CountOfLocal + CountOfExternal + CountOfOutpath
- // 至于那个数组的事件,可以自行推算
- // 例: Outpath第二个事件 => EvtIdx = CountOfLocal + CountOfExternal + 1
- //关于TIMEOUT:函数中wait的是OutpathEvts,LocalEvts和ExternalEvts是没有必要等待,有就有,没有就没有....
- virtual int StateMachineWaitForEvents(
- DiosStMRouteLine *pLocalEvts[], DWORD CountOfLocal,
- DiosStMRouteLine *pExternalEvts[], DWORD CountOfExternal,
- DiosStMRouteLine *pOutpathEvts[], DWORD CountOfOutpath,
- DWORD timeout, DiosStMEvt& Evt
- );
- };
- class DIOSSMACHINE_API DiosSMachine : public Dios_Thread,public DiosSMachineIF
- {
- protected:
- virtual bool OnStartThread();
- virtual bool Exec();
- HANDLE m_StateQuedEvent;
- ResDataObject m_LastHitStatePos;
- MsgQueue<ResDataObject> *m_pStatePosList;
- virtual void PushStateChange(ResDataObject &ChangedPos);//statemachinename:statemachinepos
- public:
- DiosSMachine(void);
- virtual ~DiosSMachine(void);
- void SetStateMachineLog(const char *pszLogTitle);
- bool PopStateChange(ResDataObject &LastPos);
- HANDLE GetStateQuedEvent();
- //for other threads to call
- bool StartStateMachine(DiosStMRouteLine *pExternalWaitEvts[], DWORD WaitCount);
- void StopStateMachine(DWORD timeout);
- };
- class DIOSSMACHINE_API DiosSubSMachine : public DiosStMRoutePos, public DiosSMachineIF
- {
- protected:
- public:
- DiosSubSMachine(void);
- DiosSubSMachine(const char *pName);
- virtual ~DiosSubSMachine(void);
- virtual bool IsSMachine();//yes
- };
|