zoukankan      html  css  js  c++  java
  • Boost StateChart实现状态机----秒表例程

     

    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 = 0;
      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_(0)
      {
        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(0))
      {
        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(0), 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 = 0; i < 10; i++)
      {
        boost::this_thread::sleep(boost::posix_time::seconds(1));  //休眠1秒
        std::cout << "time:" << myWatch.elapsedTime() << "
    ";
      }
      myWatch.process_event(EvStartStop());
      boost::this_thread::sleep(boost::posix_time::seconds(1));
      std::cout << "current time:" << myWatch.elapsedTime() << "
    ";
      cout << "---" << endl;
      myWatch.process_event(EvReset());
      std::cout << "reset time:" << myWatch.elapsedTime() << "
    ";
      cout << "---" << endl;
      return 0;
    }

     运行效果如下:

    Entry Active
    Entry Stopped
    ---
    Exit Stopped
    Entry Running
    time:1
    time:2
    time:3
    time:4
    time:5
    time:6
    time:7
    time:8
    time:9
    time:10
    Exit Running
    Entry Stopped
    current time:10
    ---
    Exit Stopped
    Exit Active
    Entry Active
    Entry Stopped
    reset time:0
    ---
    Exit Stopped
    Exit Active
  • 相关阅读:
    数据库的左右表连接
    数据库索引-索引的优点、缺点、分类、不走索引的情况
    selenium中日期控件的操作方法
    esdoc 自动生成接口文档介绍
    css设置背景图(背景图太大导致图片显示不全)
    k8s调度器及调度队列源码分析
    MIT6.824 2020 Lab1 MapReduce 实现
    git命令
    python3.6、3.9多版本安装共存
    使用蓝鲸平台登录态验证接入第三方系统
  • 原文地址:https://www.cnblogs.com/cv-pr/p/7598342.html
Copyright © 2011-2022 走看看