`

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

 

分享到:
评论

相关推荐

    StateMachine:使用 C++11 的简单状态机实现

    以下是一个基于 C++11 的简单状态机实现的详细解释: 1. **状态枚举**:首先,我们需要定义状态枚举,这将用于表示对象可以处于的不同状态。例如: ```cpp enum class State { Initial, Running, Paused, ...

    自动售货机C++程序设计.doc

    在给定的“自动售货机C++程序设计”文档中,主要展示了如何使用C++编程语言实现一个简单的自动售货机模拟系统。这个系统包括了用户与售货机交互的...通过这个程序,开发者可以学习到如何用C++实现一个简单的模拟系统。

    C++自动售货机源码

    在本项目中,"C++自动售货机源码"是一个使用C++编程语言实现的模拟自动售货机系统。这个系统已经成功运行,并且具备友好的用户界面和简单的操作流程,适合初学者理解C++面向对象编程的概念以及实际应用。 1. **面向...

    简单状态机控制步进电机

    在这个项目中,“简单状态机控制步进电机”是利用状态机的设计思想来实现对步进电机的精确控制。状态机是一种用于描述系统行为的模型,它按照预定义的一系列状态进行转换,每个状态对应于特定的操作或行为。 首先,...

    c++自动售货机

    在本项目中,"c++自动售货机"是一个典型的控制台应用程序,它模拟了现实生活中自动售货机的功能,让学生能够通过编程更好地理解和掌握C++语言。这个课程设计的目标是帮助学生熟悉面向对象编程(OOP)的概念,以及...

    状态机的使用

    总结来说,状态机是一种强大的工具,不仅在TCP/IP协议栈的分析中发挥着关键作用,还可以应用于各种其他场景,如文本处理、编译器设计、自动测试等。理解和熟练运用状态机对于深入理解计算机网络以及开发高效、准确的...

    c++自动驾驶系统实现.zip

    在本项目中,我们主要探讨的是使用C++编程语言实现一套自动驾驶系统,该系统搭建在嵌入式硬件平台上,特别是NVIDIA的Jetson TX2计算模块以及Arduino Uno控制器。车载平台是一个RC-car(遥控车),它配备了一系列...

    FSM状态机生成工具

    3. **生成源代码**:运行工具,它会根据提供的文本文件自动生成对应语言(C、C++或JAVA)的状态机源代码。 4. **整合到项目**:将生成的源代码导入到开发项目中,与现有代码进行集成。 5. **测试和调试**:对生成的...

    用C++实现简易ATM

    在本文中,我们将深入探讨如何使用C++编程语言来实现一个简易的ATM(自动取款机)系统。这个系统是基于Windows 32控制台的,因此它将利用WinAPI函数来创建用户界面和处理输入输出。我们将涵盖以下几个关键知识点: ...

    C++实现的西门子S7-200 PPI通讯

    ### C++实现的西门子S7-200 PPI通讯 #### 一、引言 西门子S7-200是一款小型可编程逻辑控制器(PLC),广泛应用于工业自动化领域。该PLC提供了多种通讯方式,其中PPI(Point-to-Point Interface)协议是一种简单且...

    自动寻路贪吃蛇C++源码

    这通常通过状态机或条件判断来实现。 综上所述,"自动寻路贪吃蛇C++源码"项目涵盖了贪吃蛇游戏的基本设计、C++编程技巧、自动寻路算法的应用以及在Visual Studio中的项目管理。通过研究这个项目,开发者不仅可以...

    a-Save-the-document.rar_C++ 自动贩卖机_vending machine_自动贩卖机_贩卖机

    标题中的"a-Save-the-document.rar_C++ 自动贩卖机_vending machine_自动贩卖机_贩卖机"表明这是一个关于C++编程实现的自动贩卖机模拟项目。这个项目采用模块化编程方法,旨在帮助学习者理解如何用C++语言设计一个...

    zhuangtaiji.rar_状态机_状态机PPT

    例如,可能会介绍如何使用伪代码或具体编程语言(如C++或Python)来实现一个简单的状态机,比如一个自动化售货机的状态管理。 此外,PPT可能还会涉及以下主题: - 状态机的类型:有限状态机(FSM)、Mealy型状态机...

    WorkFlow C++ 工作流图形

    5. **状态机**:工作流的每个任务可能处于不同的状态(如等待、运行、完成等),实现一个状态机可以帮助跟踪和管理这些状态。 6. **编译与解析**:工作流模型的图形表示需要转换为可执行代码,这涉及XML或JSON等...

    打飞机游戏源码 c++实现

    总结来说,通过这个C++实现的打飞机游戏项目,你可以学习到面向对象编程、图形渲染、用户输入处理、游戏循环的设计、碰撞检测、时间管理和基本的AI实现等核心概念。这不仅有助于提升C++编程技能,也为深入学习游戏...

    C++实现飞机大战介绍和讲解

    总的来说,C++实现飞机大战游戏需要掌握面向对象编程、图形编程、事件处理和碰撞检测等技能。通过这个游戏项目,不仅可以锻炼C++编程能力,还能深入了解游戏开发的基本流程和设计思路。希望这个介绍能为你提供一个...

    PLC课程设计自动售货机

    理解I/O接口的工作原理和配置是实现自动售货机控制的关键。 6. 实际操作与调试: 完成编程后,需要在真实的自动售货机上进行硬件连接和功能测试,调试程序以确保所有部分协同工作。 7. 安全考虑: 自动售货机...

    课程设计-简易自动售货机设计

    【简易自动售货机设计】课程设计主要涵盖了电子工程领域中的硬件设计与嵌入式系统应用,特别是基于VHDL的FPGA实现。这个项目旨在让学生掌握基础的电子支付系统设计,包括货币识别、计数、找零逻辑以及用户交互界面的...

    C++控制台飞机大战

    《C++控制台飞机大战》是一款使用C++编程语言实现的简单但富有挑战性的控制台游戏。游戏的核心机制包括玩家飞机的移动与射击、敌机的生成与移动、以及各种增益系统的应用,旨在提供一个在命令行界面下的娱乐体验。 ...

Global site tag (gtag.js) - Google Analytics