• 【boost::statechart】3状态机


    boost::statechart

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

    实现代码如下:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 #include <iostream> // std::cout
      5 #include <thread>   // std::thread
      6 #include <string>
      7 #include <vector>
      8 #include <ros/ros.h>
      9 #include <boost/statechart/state_machine.hpp>
     10 #include <boost/statechart/state.hpp>
     11 #include <boost/statechart/event.hpp>
     12 #include <boost/statechart/transition.hpp>
     13 #include <boost/statechart/custom_reaction.hpp>
     14 #include <boost/range/irange.hpp>
     15 #include <boost/thread/thread.hpp>
     16 
     17 #include <ctime>
     18 
     19 using namespace std;
     20 namespace sc = boost::statechart;
     21 
     22 class EvStartStop : public sc::event<EvStartStop>
     23 {
     24 };
     25 class EvReset : public sc::event<EvReset>
     26 {
     27 };
     28 
     29 /*虚类,用于状态机获取状态*/
     30 class IElapsedTime
     31 {
     32 public:
     33   virtual double elapsedTime() const = 0;
     34   virtual ~IElapsedTime(){};
     35 };
     36 
     37 class Active;
     38 /*秒表,状态机*/
     39 class StopWatch : public sc::state_machine<StopWatch, Active>
     40 {
     41 public:
     42   double elapsedTime() const
     43   {
     44     return state_cast<const IElapsedTime &>().elapsedTime();
     45   }
     46 };
     47 
     48 class Stopped;
     49 /*活动状态*/
     50 class Active : public IElapsedTime, public sc::state<Active, StopWatch, Stopped>
     51 {
     52 public:
     53   typedef sc::transition<EvReset, Active> reactions;
     54 
     55   Active(my_context ctx)
     56       : my_base(ctx),
     57         elapsed_time_(0)
     58   {
     59     cout << "Entry Active" << endl;
     60   }
     61   ~Active()
     62   {
     63     cout << "Exit Active" << endl;
     64   }
     65 
     66   double elapsedTime() const
     67   {
     68     return elapsed_time_;
     69   }
     70   double &elapsedTime()
     71   {
     72     return elapsed_time_;
     73   }
     74 
     75 private:
     76   double elapsed_time_;
     77 };
     78 
     79 /*计时状态*/
     80 class Running : public IElapsedTime, public sc::state<Running, Active>
     81 {
     82 public:
     83   typedef sc::transition<EvStartStop, Stopped> reactions;
     84   Running(my_context ctx)
     85       : my_base(ctx),
     86         start_time_(std::time(0))
     87   {
     88     cout << "Entry Running" << endl;
     89   }
     90   ~Running()
     91   {
     92     context<Active>().elapsedTime() = elapsedTime();
     93     cout << "Exit Running" << endl;
     94   }
     95   virtual double elapsedTime() const
     96   {
     97     return context<Active>().elapsedTime() + std::difftime(std::time(0), start_time_);
     98   }
     99 
    100 private:
    101   std::time_t start_time_;
    102 };
    103 
    104 /*停止状态*/
    105 class Stopped : public IElapsedTime, public sc::state<Stopped, Active>
    106 {
    107 public:
    108   typedef sc::transition<EvStartStop, Running> reactions;
    109   Stopped(my_context ctx)
    110       : my_base(ctx)
    111   {
    112     cout << "Entry Stopped" << endl;
    113   }
    114   ~Stopped()
    115   {
    116     cout << "Exit Stopped" << endl;
    117   }
    118   virtual double elapsedTime() const
    119   {
    120     return context<Active>().elapsedTime();
    121   }
    122 };
    123 
    124 int main(int argc, char **argv)
    125 {
    126   StopWatch myWatch;
    127   myWatch.initiate();
    128   cout << "---" << endl;
    129 
    130   myWatch.process_event(EvStartStop());
    131   for (int i = 0; i < 10; i++)
    132   {
    133     boost::this_thread::sleep(boost::posix_time::seconds(1)); //休眠1秒
    134     std::cout << "time:" << myWatch.elapsedTime() << "\n";
    135   }
    136   myWatch.process_event(EvStartStop());
    137   boost::this_thread::sleep(boost::posix_time::seconds(1));
    138   std::cout << "current time:" << myWatch.elapsedTime() << "\n";
    139   cout << "---" << endl;
    140   myWatch.process_event(EvReset());
    141   std::cout << "reset time:" << myWatch.elapsedTime() << "\n";
    142   cout << "---" << endl;
    143   return 0;
    144 }
  • 相关阅读:
    好尚不可为,其况恶乎(转)
    getResource(String name)用法及源码分析
    怎样从ext3升级到ext4?
    Java设计模式之适配器模式(Adapter Pattern)
    javascript实现图片无缝滚动(scrollLeft的使用方法介绍)
    PowerDesigner使用教程
    python 多线程编程
    java中接口的定义与实现
    Java调用cmd命令 打开一个站点
    C#中MessageBox使用方法大全(附效果图)
  • 原文地址:https://www.cnblogs.com/sunbines/p/15721429.html
Copyright © 2020-2023  润新知