Boost 提供了状态机的实现接口,采用了CRTP技术实现,下面以秒表为例子实现一个状态机,这是一个官方的例子,也可以参考资料:Boost Statechart 庫,状态机的状态转换图如下所示:

实现代码如下:

#include <stdio.h>
#include <stdlib.h> #include <iostream> // std::cout
#include <thread> // std::thread
#include <string>
#include <vector>
#include <ros/ros.h>
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/state.hpp>
#include <boost/statechart/event.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/custom_reaction.hpp>
#include <boost/range/irange.hpp>
#include <boost/thread/thread.hpp> #include <ctime> using namespace std;
namespace sc = boost::statechart; class EvStartStop : public sc::event<EvStartStop>
{
};
class EvReset : public sc::event<EvReset>
{
}; /*虚类,用于状态机获取状态*/
class IElapsedTime
{
public:
virtual double elapsedTime() const = ;
virtual ~IElapsedTime(){};
}; class Active;
/*秒表,状态机*/
class StopWatch : public sc::state_machine<StopWatch, Active>
{
public:
double elapsedTime() const
{
return state_cast<const IElapsedTime &>().elapsedTime();
}
}; class Stopped;
/*活动状态*/
class Active : public IElapsedTime, public sc::state<Active, StopWatch, Stopped>
{
public:
typedef sc::transition<EvReset, Active> reactions; Active(my_context ctx)
: my_base(ctx),
elapsed_time_()
{
cout << "Entry Active" << endl;
}
~Active()
{
cout << "Exit Active" << endl;
} double elapsedTime() const
{
return elapsed_time_;
}
double& elapsedTime()
{
return elapsed_time_;
} private:
double elapsed_time_;
}; /*计时状态*/
class Running : public IElapsedTime, public sc::state<Running, Active>
{
public:
typedef sc::transition<EvStartStop, Stopped> reactions;
Running(my_context ctx)
: my_base(ctx),
start_time_(std::time())
{
cout << "Entry Running" << endl;
}
~Running()
{
context<Active>().elapsedTime() = elapsedTime();
cout << "Exit Running" << endl;
}
virtual double elapsedTime() const
{
return context<Active>().elapsedTime()
+ std::difftime(std::time(), start_time_);
}
private:
std::time_t start_time_;
}; /*停止状态*/
class Stopped : public IElapsedTime, public sc::state<Stopped, Active>
{
public:
typedef sc::transition<EvStartStop, Running> reactions;
Stopped(my_context ctx)
: my_base(ctx)
{
cout << "Entry Stopped" << endl;
}
~Stopped()
{
cout << "Exit Stopped" << endl;
}
virtual double elapsedTime() const
{
return context<Active>().elapsedTime();
} }; int main(int argc, char** argv)
{
StopWatch myWatch;
myWatch.initiate();
cout << "---" << endl; myWatch.process_event(EvStartStop());
for(int i = ; i < ; i++)
{
boost::this_thread::sleep(boost::posix_time::seconds()); //休眠1秒
std::cout << "time:" << myWatch.elapsedTime() << "\n";
}
myWatch.process_event(EvStartStop());
boost::this_thread::sleep(boost::posix_time::seconds());
std::cout << "current time:" << myWatch.elapsedTime() << "\n";
cout << "---" << endl;
myWatch.process_event(EvReset());
std::cout << "reset time:" << myWatch.elapsedTime() << "\n";
cout << "---" << endl;
return ;
}

运行效果如下:

Entry Active
Entry Stopped
---
Exit Stopped
Entry Running
time:
time:
time:
time:
time:
time:
time:
time:
time:
time:
Exit Running
Entry Stopped
current time:
---
Exit Stopped
Exit Active
Entry Active
Entry Stopped
reset time:
---
Exit Stopped
Exit Active

Boost StateChart实现状态机----秒表例程的更多相关文章

  1. c# 状态机实现

    c#仿boost statechart的状态机.去年转到unity使用c#,statechart原来的风格蛮爽的,缺点是编译忒慢,在c#则编译根本不是问题. 不一样的地方首先是简单!因为没做一些东西如 ...

  2. boost状态机学习二(秒表)

    基础主题:秒表 下面我们要为一个机械秒表建模一个状态机.这样一个秒表通常会有两个按钮. * Start/Stop * Reset 同时有两种状态: * Stoped: 表针停留在上次停止时的位置: o ...

  3. Boost的状态机库教程(1)

    介绍 Boost状态机库一个应用程序框架,你可以用它将UML状态图快速的转换为可执行的c++代码,而不需要任何的代码生成器.它支持几乎所有的UML特征,可以直接了当的转换,并且转换后的c++代码就像对 ...

  4. Boost 1.61.0 Library Documentation

    http://www.boost.org/doc/libs/1_61_0/ Boost 1.61.0 Library Documentation Accumulators Framework for ...

  5. Ceph源码解析:PG peering

    集群中的设备异常(异常OSD的添加删除操作),会导致PG的各个副本间出现数据的不一致现象,这时就需要进行数据的恢复,让所有的副本都达到一致的状态. 一.OSD的故障和处理办法: 1. OSD的故障种类 ...

  6. Ceph:pg peering过程分析

    转自:https://www.ustack.com/blog/ceph%ef%bc%8dpg-peering/ Peering:互为副本的三个(此处为设置的副本个数,通常设置为3)pg的元数据达到一致 ...

  7. 【资料下载区】【iCore3相关代码、资料下载地址】更新日期2017/1/5

    [iCore3 ARM代码下载地址][全部]DEMO1.0测试程序发布例程一:ARM驱动三色LED例程二:读取arm按键状态例程三:EXTI中断输入实验——读取ARM按键状态例程四:USART通信实验 ...

  8. Important Programming Concepts (Even on Embedded Systems) Part V: State Machines

    Earlier articles in this series: Part I: Idempotence Part II: Immutability Part III: Volatility Part ...

  9. 记录一次ceph recovery经历

    一次ceph recovery经历 背景 这是一个測试环境. 该环境中是cephfs 一共12个节点, 2个client.2个mds.8个osd mds: 2颗CPU,每一个4核.一共是8核. 128 ...

随机推荐

  1. elementUI 通用确认框

    Util.vue <script> import VueResource from 'vue-resource' function confirm(_this, operate, fun) ...

  2. 从零开始编写自己的JavaScript框架(一)

    1. 模块的定义和加载 1.1 模块的定义 一个框架想要能支撑较大的应用,首先要考虑怎么做模块化.有了内核和模块加载系统,外围的模块就可以一个一个增加.不同的JavaScript框架,实现模块化方式各 ...

  3. 关于SQL注入,你应该知道的那些事

    戴上你的黑帽,现在我们来学习一些关于SQL注入真正有趣的东西.请记住,你们都好好地用这些将要看到的东西,好吗? SQL注入攻击因如下几点而是一种特别有趣的冒险: 1.因为能自动规范输入的框架出现,写出 ...

  4. J2EE简介

    一,J2EE概念: J2EE的全称为,Java2 Platform Enterprise Edition,Java或java2平台企业版,他是基于java平台或java2平台的标准版,保留并扩展了J2 ...

  5. JavaScript 计时

    http://www.w3school.com.cn/js/js_timing.asp JavaScript 计时事件 通过使用 JavaScript,我们有能力作到在一个设定的时间间隔之后来执行代码 ...

  6. camera驱动框架分析(上)

    前言 camera驱动框架涉及到的知识点比较多,特别是camera本身的接口就有很多,有些是直接连接到soc的camif口上的,有些是通过usb接口导出的,如usb camera.我这里主要讨论前者, ...

  7. 启动tomcat的时候爆出如下错误

    The JRE_HOME environment variable is not defined correctly This environment 解决办法: https://blog.csdn. ...

  8. vue.js 解决空格报错!!!

    当我们初入vue.js的时候.使用cli脚手架快速创建项目的时候: 如果语法格式错误(这里主要指的是:空格多少引起的问题)!! 找到  webpack.base.config.js文件注释掉下面的东西 ...

  9. 前端如何在h5页面调用微信支付?

    在微信服务号开发的时候经常会遇到微信支付的功能实现,通过实际经验自己总结了一下,前端在H5页面调起微信支付有两种办法,一是利用内置对象,二是通过引用微信的js sdk,亲测都能支付成功,从写法上来看用 ...

  10. js中的prototype原型解析

    在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...