当前位置:首页 > 开发 > IT生活 > 正文

C++实现简单有限自动状态机

发表于: 2015-01-19   作者:ciaos   来源:转载   浏览次数:
C++
摘要: 使用示例如下: #include <stdio.h> #include <unistd.h> #include "simple_server.hpp" using namespace SimpleServerFrame; extern "C" { StateFSM fsm; enum TestState{

使用示例如下:

#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
	}
}

 

C++实现简单有限自动状态机

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
有限状态机的C++实现(2)-bayonet开源网络服务器框架 | Vimer的程序世界 有限状态机的C++实现(2)-bay
有限状态机(Finite-state machine)是一个非常有用的模型,可以模拟世界上大部分事物。 简单说,它
以下内容摘自吴军的《数学之美》第113页: 一个有限状态机是一个特殊的有向图,它包括一些状态(节
DUAL 有限状态机 (FSM) EIGRP 的核心就是 DUAL 以及 DUAL 的 EIGRP 路由计算引擎。此技术的确切名称
有限状态机(Finite-state machine)是一个非常有用的模型,可以模拟世界上大部分事物。 简单说,它
状 态 描 述 CLOSED 关闭状态,没有连接活动或正在进行 LISTEN 监听状态,服务器正在等待连接进入 S
Ruby世界里有很多非常可爱的plugin供我们来使用,AASM就是其中之一,通过使用这个plugin,我们可以把
转自:http://book.51cto.com/art/200911/162899.htm 有限状态机有两种基本类型:米利(Mealy)机和
转自:http://book.51cto.com/art/200911/162899.htm 有限状态机有两种基本类型:米利(Mealy)机和
转自:http://book.51cto.com/art/200911/162899.htm 有限状态机有两种基本类型:米利(Mealy)机和
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号