使用示例如下:
#include <stdio.h> #include <unistd.h> #include "simple_server.hpp" using namespace SimpleServerFrame; extern "C" { StateFSM fsm; enum TestState{ s_INIT = 0, s_STATE_1 = 1, s_STATE_2 = 2, s_END = 3, s_ERR = 4, }; enum TestEvent{ e_EVENT_1 = 100, e_EVENT_2 = 101, e_EVENT_3 = 102, e_EVENT_NOT_EXIST = 103, }; enum TestAction{ a_ACTION_1 = 200, a_ACTION_2 = 201, a_ACTION_3 = 202, a_ACTION_END = 203, a_ACTION_ERROR = 204, }; class Test:public IFsmCallback{ public: int FsmCallback(int actionID){ switch(actionID){ case a_ACTION_1: printf("s_INIT -> s_STATE_1\n"); fsm.PushEvent(e_EVENT_2); break; case a_ACTION_2: printf("s_INIT -> s_STATE_2\n"); break; case a_ACTION_3: printf("s_STATE_1 -> s_STATE_2\n"); fsm.PushEvent(e_EVENT_3); break; case a_ACTION_END: printf("s_STATE_2 -> s_END\n"); break; case a_ACTION_ERROR: printf("s_STATE_2 -> s_STATE_1 not allowed!\n"); break; default: printf("invalid action id\n"); break; } return 0; } }; // one time int init() { // ... fsm.AddFsmConfig(s_INIT, e_EVENT_1, s_STATE_1, a_ACTION_1); fsm.AddFsmConfig(s_INIT, e_EVENT_2, s_STATE_2, a_ACTION_2); fsm.AddFsmConfig(s_STATE_1, e_EVENT_2, s_STATE_2, a_ACTION_3); fsm.AddFsmConfig(s_STATE_2, e_EVENT_1, s_ERR, a_ACTION_ERROR); fsm.AddFsmConfig(s_STATE_2, e_EVENT_3, s_END, a_ACTION_END); } // each request sResponse doJob(sRequest req) { Test *tt = new Test(); fsm.StartFsm(s_INIT, tt); fsm.RunFsm(e_EVENT_1, tt); sleep(1); sResponse res; res.iResId = req.iReqId; return res; } }
FSM源码如下:
#ifndef __STATE_FSM_HPP__ #define __STATE_FSM_HPP__ #include <vector> #include <map> #include <queue> namespace SimpleServerFrame{ using std::queue; using std::vector; using std::map; typedef struct _fsmTransition{ int eventID; int nextState; int actionID; }fsmTransition; typedef struct _fsmState{ vector<fsmTransition> vecTransition; }fsmState; class IFsmCallback{ public: virtual int FsmCallback(int actionID) = 0; int FsmGetCurState(){ return _curState; } void FsmSetCurState(int curState){ _curState = curState; } private: int _curState; }; class StateFSM{ public: StateFSM(); virtual ~StateFSM(); int StartFsm(int stateID, IFsmCallback *fsmobj); int AddFsmConfig(int curState, int eventID, int nextState, int actionID); int RunFsm(int eventID, IFsmCallback *fsmobj); int PushEvent(int eventID); private: int doFsmEvent(int eventID, IFsmCallback *fsmobj); int getActionID(int curState, int eventID, int &nextState, int &actionID); private: map<int, fsmState> mapState; queue<int> queueEvent; }; } #endif
#include "state_fsm.hpp" using namespace SimpleServerFrame; using std::pair; StateFSM::StateFSM() { mapState.clear(); } StateFSM::~StateFSM() { } int StateFSM::StartFsm(int stateID, IFsmCallback *fsmobj) { map<int, fsmState>::iterator stateIter; stateIter = mapState.find(stateID); if(stateIter != mapState.end()) { fsmState state = stateIter->second; if(state.vecTransition.size() == 0){ return -2; // only one state } } else{ return -1; // no such state } fsmobj->FsmSetCurState(stateID); } int StateFSM::AddFsmConfig(int curState, int eventID, int nextState, int actionID) { fsmTransition transition; transition.eventID = eventID; transition.nextState = nextState; transition.actionID = actionID; map<int, fsmState>::iterator stateIter; stateIter = mapState.find(curState); if(stateIter != mapState.end()) { stateIter->second.vecTransition.push_back(transition); } else{ fsmState state; state.vecTransition.push_back(transition); mapState.insert ( pair <int, fsmState> ( curState, state ) ); } for(stateIter = mapState.begin(); stateIter!= mapState.end(); stateIter ++){ fsmState state = stateIter->second; for(int i = 0 ; i < state.vecTransition.size();i ++){ transition = state.vecTransition[i]; } } } int StateFSM::PushEvent(int eventID) { queueEvent.push(eventID); } int StateFSM::doFsmEvent(int eventID, IFsmCallback *fsmobj) { int curState = fsmobj->FsmGetCurState(); int actionID; int nextState; int iRet = getActionID(curState, eventID, nextState, actionID); if(iRet == 0){ fsmobj->FsmSetCurState(nextState); fsmobj->FsmCallback(actionID); } return 0; } int StateFSM::RunFsm(int eventID, IFsmCallback *fsmobj) { doFsmEvent(eventID, fsmobj); while(!queueEvent.empty()){ int eventID = queueEvent.front(); queueEvent.pop(); doFsmEvent(eventID, fsmobj); } return 0; } int StateFSM::getActionID(int curState, int eventID, int &nextState, int &actionID) { map<int, fsmState>::iterator stateIter; stateIter = mapState.find(curState); if(stateIter != mapState.end()) { fsmState state = stateIter->second; vector<fsmTransition>::iterator traniter; for ( traniter = state.vecTransition.begin() ; traniter != state.vecTransition.end() ; traniter++ ) { fsmTransition transition = *traniter; if(transition.eventID == eventID){ nextState = transition.nextState; actionID = transition.actionID; return 0; } } return -2; //curstate has no such event }else{ return -1; //no such state } }
相关推荐
Visual C++程序开发范例宝典配套光盘,因大小受限,所以分成8部分上传,必须全部下载才能正常解压! 第1章 窗体与界面设计 1.1 菜单应用实例 实例001 在系统菜单中添加菜单项 实例002 带图标的程序菜单 实例003...
下面简单讲述一下这种方法的实现方法: 代码如下 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() //}}AFX_MSG_MAP ON_COMMAND(ID_FONT_DROPDOWN, DoNothing) END_...
cc实例115 彩票抽奖机 3.12 OpenGL程序设计 cc实例116 制作OpenGL动画 cc实例117 利用OpenGL绘制立体模型 cc实例118 利用OpenGL绘制NURBS曲线 第4章 多媒体技术 4.1 动画 cc实例...
C++Builder精彩编程实例集锦的源代码(1,2,3部分): 第一部分 界面设计 实例001 如何实现程序闪屏效果 实例002 如何实现程序窗口闪烁 实例003 如何制作吸附窗口程序 实例004 如何制作透明程序窗口 实例005 如何...
C#源码,实现简单游览器。 RangeScan扫描器源代码 ip地址扫描,发送邮箱。 ResizableLib 测试开源界面库Resizable。 RsPicture 自定义了一个图片库,然后引用测试。 SimplePlayer 简单的媒体播放源码。 Skin_...
pg_auto_failover pg_auto_failover是PostgreSQL扩展和服务,用于监视和管理Postgres集群的自动故障转移...监视节点跟踪数据节点的运行状况,并实现故障转移状态机。 在PostgreSQL节点上,pg_autoctl程序与Post一起运行
cc实例161 判断文件是否被改动 第6章 操作系统与Windows相关程序 6.1 启动相关设置 cc实例 162 进入WindowscXP前发出警告 cc实例163 实现关机.c重启计算机 cc实例164 将程序设置成为开机自动执行的程序 ...
cc实例115 彩票抽奖机 3.12 OpenGL程序设计 cc实例116 制作OpenGL动画 cc实例117 利用OpenGL绘制立体模型 cc实例118 利用OpenGL绘制NURBS曲线 第4章 多媒体技术 4.1 动画 cc实例...
CarND路径规划项目 无人驾驶汽车工程师纳米学位课程 ... 第一个实现简单明了。 它允许汽车以我所谓的手动编码方式行驶。 第二种实施依赖于成本/轨迹; 它更具说服力,但更难实施,并且在该项目中并不一定效率更高。
2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。...
实例044 如何显示简单关于对话框 实例045 如何在程序中增加热键 实例046 如何在程序中自定义消息 实例047 如何在程序中自定义系统菜单 实例048 如何在执行程序间进行数据通信 实例049 如何使用OLE技术启动画图 ...
C#源码,实现简单游览器。 RangeScan扫描器源代码 ip地址扫描,发送邮箱。 ResizableLib 测试开源界面库Resizable。 RsPicture 自定义了一个图片库,然后引用测试。 SimplePlayer 简单的媒体播放源码。 Skin_...
实例044 如何显示简单关于对话框 实例045 如何在程序中增加热键 实例046 如何在程序中自定义消息 实例047 如何在程序中自定义系统菜单 实例048 如何在执行程序间进行数据通信 实例049 如何使用OLE技术启动画图 ...
Visual C++程序开发范例宝典配套光盘,因大小受限,所以分成8部分上传,必须全部下载才能正常解压! 第1章 窗体与界面设计 1.1 菜单应用实例 实例001 在系统菜单中添加菜单项 实例002 带图标的程序菜单 实例003...
4.2.4 通信错误与通信设备状态 4.2.5 串行通信事件 4.3 Windows API串行通信函数 4.4 Win32 API串口通信编程的一般流程和特殊实例 4.4.1 Win32 API串口通信编程的一般流程 4.4.2 用查询方式读串口 4.4.3...
C#源码,实现简单游览器。 RangeScan扫描器源代码 ip地址扫描,发送邮箱。 ResizableLib 测试开源界面库Resizable。 RsPicture 自定义了一个图片库,然后引用测试。 SimplePlayer 简单的媒体播放源码。 Skin_...
C#源码,实现简单游览器。 RangeScan扫描器源代码 ip地址扫描,发送邮箱。 ResizableLib 测试开源界面库Resizable。 RsPicture 自定义了一个图片库,然后引用测试。 SimplePlayer 简单的媒体播放源码。 Skin_...
C#源码,实现简单游览器。 RangeScan扫描器源代码 ip地址扫描,发送邮箱。 ResizableLib 测试开源界面库Resizable。 RsPicture 自定义了一个图片库,然后引用测试。 SimplePlayer 简单的媒体播放源码。 Skin_...
C#源码,实现简单游览器。 RangeScan扫描器源代码 ip地址扫描,发送邮箱。 ResizableLib 测试开源界面库Resizable。 RsPicture 自定义了一个图片库,然后引用测试。 SimplePlayer 简单的媒体播放源码。 Skin_...