boost 有限状态机(FSM)

下载boost库 (boost_1_55_0 本文使用版本)

下载地址:http://c9.yunpan.360.cn/my/?sid=#%2F%E5%8D%9A%E5%AE%A2%E8%B5%84%E6%BA%90%2F

添加到应用项目中,通过项目属性 配置好库目录  (路径根据具体情况进行配置,主要看你放在项目的哪个路径下)



编码开始了:


#include "stdafx.h"
#include <iostream>

#include "boost/statechart/state_machine.hpp"     // 注意使用 " " , 如果 < > 报错
#include "boost/statechart/simple_state.hpp"

namespace sc = boost::statechart;

struct Greeting;

/*
boost::statechart 大量应用模板模式。 派生类必须将自己作为基类模板的第一个参数。
状态机必须知道当其初始化后进行的第一个状态。 这里将 Greeting 定义为其进入后的第一个状态。
state_machine
*/
struct Machine : sc::state_machine< Machine, Greeting > { };

/*
对于每一个状态,我们需要为其指明:它属于哪一个状态机  simple_state<> 指定
*/
struct Greeting : sc::simple_state< Greeting, Machine >
{
	/*
	状态机进入一个状态,就会创建一个相应的该状态的对象 (Constructor)。
	保持当前状态,这个对象才会一直存在。 状态机离开该状态时,对象被销毁 (Destructor)。
	*/
	Greeting() { std::cout<<"Greeting Constructor !\n"; }
	~Greeting() { std::cout<<"Greeting Destructor !"<<std::endl; }
};


int _tmain(int argc, _TCHAR* argv[])
{
	Machine myMachine;
	//构造完状态机后,它并未开始运行。我们要通过调用它的initiate()来启动它。
	//同时,它也将触发它的初始状态(Greeting)的构造。

	myMachine.initiate();
	// 当我们离开main()函数时,myMachine将被销毁,这将导致它销毁它内部的所有活动的状态类。
	// (译者注:为什么会说所有?这是因为一个状态机可以同时 保持在多个状态中)
	return 0;
}




FSM(有限状态机) 的简单使用示例代码 

#include "stdafx.h"
#include <iostream>
#include <ctime>

#include "boost/statechart/state_machine.hpp"
#include "boost/statechart/simple_state.hpp"
#include "boost/statechart/transition.hpp"
#include "boost/statechart/event.hpp"

namespace sc = boost::statechart;

//定义事件    《根据事件 切换 状态》
class EvtStartStop : public sc::event< EvtStartStop > {};
class EvtReset : public sc::event< EvtReset > {};
class EvtGo : public sc::event< EvtGo > {};

class MainState;
class StopState;
class RunState;
class TwoState;

//定义状态机                             初始化状态 MainState
class Machine : public sc::state_machine< Machine, MainState > {};  

//定义 MainState 状态 , 它属于Machine, 它的子状态为 StopState
class MainState : public sc::simple_state< MainState, Machine, StopState >
{
public:
    typedef sc::transition< EvtReset, MainState > reactReset;	//状态切换
    typedef sc::transition< EvtGo, TwoState > reactGo;			//状态切换

    typedef boost::mpl::list< reactReset, reactGo > reactions;  //reactions 切不可拼写错误
	//一个状态可以定义任意数量的动作。这就是为什么当多于一个时,我们不得不将它们放到一个mpl::list<> 里。

    MainState(void)
	{
        std::cout<<"Enter MainState"<<std::endl;
        mTime = 0;
    }

    ~MainState(void)
	{
        std::cout<<"Exit MainState"<<std::endl;
    }

    double mTime;
};


// 该状态属于无用状态,用于测试mpl::list的多transition用法
class TwoState : public sc::simple_state< TwoState, Machine >
{
public:
    typedef sc::transition< EvtGo, MainState > reactions; //状态切换

    TwoState(void)
	{
        std::cout<<"Enter TwoState"<<std::endl;
    }

    ~TwoState(void)
	{
        std::cout<<"Exit TwoState"<<std::endl;
    }
};


class StopState : public sc::simple_state< StopState, MainState >
{
public:
    typedef sc::transition< EvtStartStop, RunState > reactions; //状态切换

    StopState(void)
	{
        std::cout<<"Enter StopState"<<std::endl;
    }

    ~StopState(void)
	{
        std::cout<<"Exit StopState"<<std::endl;
    }
};

class RunState : public sc::simple_state< RunState, MainState >
{
public:
    typedef sc::transition< EvtStartStop, StopState > reactions;
    RunState(void)
	{
        std::cout<<"Enter RunState"<<std::endl;
        mStartTime = 0;
    }

    ~RunState(void)
	{
        std::cout<<"Exit RunState"<<std::endl;
        context<MainState>().mTime += std::difftime(std::time(0), mStartTime);
    }

    std::time_t mStartTime;
};


int _tmain(int argc, _TCHAR* argv[])
{
    Machine mc;
    mc.initiate();

    mc.process_event(EvtStartStop());
	std::cout<<std::endl;
    mc.process_event(EvtStartStop());
	std::cout<<std::endl;
    mc.process_event(EvtReset());
	std::cout<<std::endl;
    mc.process_event(EvtGo());
	std::cout<<std::endl;
    mc.process_event(EvtGo());

    return 0;
}







  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值