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

使用示例如下:

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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值