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. centos安装lrzsz

    yum -y install lrzsz 使用rz打开上传框

  2. Windows bat 学习(初级)

    http://steve-jansen.github.io/guides/windows-batch-scripting/part-1-getting-started.html 注释:REM 或 :: ...

  3. 20155212 2016-2017-2 《Java程序设计》第8周学习总结

    20155212 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 Chapter14 1. Channel架构与操作 想要取得Channel的实作对象,可以使 ...

  4. 20155233 2016-2017-2 《Java程序设计》第5周学习总结

    20155233 2016-2017-2 <Java程序设计>第5周学习总结 学习目标 理解异常架构 牚握try...catch...finally处理异常的方法 会用throw,thro ...

  5. 2016最新的中国省市区三级数据库表.sql mssql

    /****** Object: Table [dbo].[t_Area] Script Date: 09/10/2016 09:35:46 ******/ SET ANSI_NULLS ON GO S ...

  6. 如何新建Quartus工程—FPGA入门教程【钛白Logic】

    这一章我们来实现第一个FPGA工程—LED流水灯.我们将通过流水灯例程向大家介绍一次完整的FPGA开发流程,从新建工程,代码设计,综合实现,管脚约束,下载FPGA程序.掌握本章内容,大家就算正式的开始 ...

  7. Wireshark按照域名过滤

    HTTP协议 http.host == "http://baidu.net" DNS协议 dns.qry.name=="www.baidu.com"

  8. 【译】EntityFramework6与EntityFrameworkCore的区别

    EntityFramework6 EF6 是一个久经考验的数据库访问技术,发展多年,拥有许多特性,并且成熟稳定.2008年EF作为 .Net 3.5 Sp1 和Visual Studio 2008 S ...

  9. PhpStorm,Pycharm,Goland破解

    phpstorm是一个轻量级且便捷的PHP IDE,其旨在提供用户效率,可深刻理解用户的编码,提供智能代码补全,快速导航以及即时错误检查.不但是php开发的利器,前端开发也是毫不逊色的.下面记录Php ...

  10. [java笔记]JDK的安装和配置

    1.JDK安装下载java JDK:点击下载(http://www.oracle.com/technetwork/java/javase/downloads/index.html )JDK(Java ...