#pragma once #define CCOSSMACHINE_API #define CCOSSMACHINE_C_API extern "C" #include "MsgCircle.h" #include "ModuleDevice.h" #include "ConditionEvent.h" #include "StateMachineDevicePool.h" //#include "SMachineDlg.h" using namespace std; #define Debug_HTTP 0 #define SME_MaxWaitEventNum 20 //状态机状态 enum SMSTATETYPE { SMST_NULL, SMST_INIT,//初始化,包括加载工作流文件、初始化事件参数 SMST_BEGIN,//开始执行状态机,启动状态流转线程 SMST_RUN,//状态机执行中,包括当前状态条件判断动作执行、跳转至下一个状态 SMST_STOP,//状态机暂停,一般用于状态发生跳转后、对应动作执行前,给子系统执行的时机 SMST_ERROR,//状态机执行出错 SMST_END,//状态机结束,包括直接退出和执行到最后一个状态 SMST_EXIT,//状态机退出 SMST_MAX }; //状态变化回调 using StateChangedCallback = std::function; //标准状态机 class CCOSSMACHINE_API CcosSMachine : public Ccos_Thread, public CcosLock #if Debug_HTTP , public ModuleDevice #endif // Debug_HTTP { protected: //测试模式 bool m_bDebugEnable{ false }; //是否启用Debug模式 //SMachineDlg* m_pUIDebugObj{ nullptr }; //调试窗口 //状态机自身使用 atomic m_nSMState; //状态机状态 string m_strCurrentState; //当前流程状态 std::shared_ptr m_hRunningEvt; //状态机运行状态指示事件 vector>m_hCurrentWaitEvtArray; //当前状态等待事件数组 //配置中获取 string m_strMachineName; //状态机名称 map m_StateMap; //全局状态路由表,状态名:状态定义 vector m_EventsList; //事件列表 ResDataObject m_resUserVariable; //用户临时系统变量 string m_strBeginState; //流程起始状态 string m_strEndState; //流程终止状态 //上层所需 StateChangedCallback m_StateNotify{ nullptr }; //上报回调 std::shared_ptr m_hTransStateEvt; //状态机跳转指示事件 //设备池所需 StateMachineDevicePool m_DevicePool; //设备订阅池 map m_DeviceMap; //启动的设备列表,设备类型:设备路径 map m_AttributeCountMap; //关注的设备属性列表,[设备类型:属性名]:引用计数 protected: void ClearState(); //清理当前所有状态 virtual bool Exec() override; //状态机运转线程,循环执行,由父类StartThread启动 virtual bool OnStartThread() override;//Exec之前 virtual bool OnEndThread() override;//Exec返回false之后 bool ExecStateMachine(); //状态流转线程执行方法 CCOSSTMRET StateMachineEntry(DWORD timeout);//Begin状态点 CCOSSTMRET StateMachineExit(DWORD timeout);//End状态点 DWORD GetCurrentStateTimeout(string& timeoutState); //获取当前状态中的超时定义 CCOSSTMRET CheckExternal(string eventFrom = ""); //检查是否有直接跳转满足 void WaitNotfiyProcess(string& Pathkey, string& Context); //检查是否有条件判断满足 CCOSSTMRET TransToPos(const char* pPosName);//状态跳转 CCOSSTMRET StateMachineAction(const char* pState, DWORD timeout); //状态点Action执行动作,检查是否有条件判断满足 public: CcosSMachine(void); virtual ~CcosSMachine(void); #if Debug_HTTP //http接口,可用于后续自测调用 RET_STATUS OnUpdate(const char* pszProperty, const char* pszValueUpdate, ResDataObject& resRespons) override; RET_STATUS OnDel(const char* pszPropery, ResDataObject& resDelValue, ResDataObject& resResponse) override; RET_STATUS OnAdd(const char* pszPropery, ResDataObject& reAddValue, ResDataObject& resResponse) override; RET_STATUS SetItem(const char* pszPropery, ResDataObject& resSetValue, ResDataObject& resResponse) override; RET_STATUS GetItem(const char* pszPropery, ResDataObject& resResponse) override; RET_STATUS OnAction(const char* pszActionName, const char* pszParams, ResDataObject& resResponse) override; #endif //设置Debug模式,启用或者禁用 void SetDebugMode(bool bEnable); //********************************外部启用状态机执行步骤******************************** bool Reset(DWORD Timeout); //清除所有的状态和设备(步骤4.0之前、8.0之后执行) bool TriggerEvent(string EventName); //手动触发状态机事件(步骤4.0~8.0之间执行) void GetStateMachineState(SMSTATETYPE& state); //获取状态机运行、暂停等状态 //================以下顺序执行================ //1.0(必须).从状态机配置文件中加载当前状态机定义:配置文件格式见 TemplateWorkFlow.json bool LoadMachine(ResDataObject& Machine); //1.1(可选).设置、获取系统变量 void SetUserVariable(const char* pKey, ResDataObject& resValue); void GetUserVariable(const char* pKey, ResDataObject& resValue); //1.2(可选).设置、获取状态机名称 void SetStateMachineName(string Name); string GetStateMachineName(); //1.3(可选).设置通知回调 void SetNotifyCallback(StateChangedCallback callback); //1.4(可选).添加状态点映射,各个状态点的Actions bool AddStateActions(ResDataObject& ActionMap); //1.5(可选).添加事件映射,所有的抽象事件的物理映射 bool AddStateEvents(ResDataObject& EventMap); //2.0(必须).设置状态机条件获取、动作执行的设备列表, //如果上层未Open对应WS的LogicClient,则参数WS为空;如果状态机配置文件中的DeviceList的不为空,则可以不调用该接口 //DevList:类型:设备路径; WS:字符串 bool AddDevices(ResDataObject& DevList, string WS); //3.0(可选).设备属性初始化 bool PrePareStateMachine(); //4.0(必须).状态机开始 bool StartStateMachine(); //5.0(必须).获取状态跳转事件句柄 std::shared_ptr GetStateTransEvent(); //6.0(必须).获取当前激活状态(等待到步骤4后触发) void GetCurrentState(string& State); //7.0(必须).设置状态机运行状态(步骤5对应的上层执行后触发,告诉状态机继续执行) void SetRunningState(bool Running); //8.0(必须).停止状态机 void StopStateMachine(DWORD timeout); };