简单的有限状态机(FSM)的示例一

news2025/1/9 0:47:01

一个简单的有限状态机,

三种状态:
  1. 停止状态
  2. 运行状态
  3. 暂停状态
三个事件
  1. Start
  2. Pause
  3. Stop
    在这里插入图片描述

状态转换说明:

  1. Stopped状态:通过Start事件转换为Running状态
  2. Running状态:通过Pause事件可转换为Pause状态
  3. Pause状态:通过Start事件可转换为Running状态

实现方式有多种

使用if-else或switch-case

使用if-else或switch-case判断并设置状态之间的转换,比较小儿科,如果写不好会有很多很多的bug,最后当状态变得很多很复杂的时候,bug可能不好找完,尤其是在加入新的状态以后.
有一个明显的优点:就是想怎么改就怎么改,容易上手
有一个明显的缺点:很难扩展新的状态,增加新的事件

不做过多的解释哈。

基于boost的state_machine来实现,如下:

state_machine.h

#pragma once

#include <iostream>

#include <boost/statechart/event.hpp>
#include <boost/statechart/result.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/custom_reaction.hpp>

//Pre-declarations
class StoppedState;
class RunningState;
class PauseState;

//Three events declaration
class StopEvent : public boost::statechart::event<StopEvent>
{
public:
  StopEvent()
  {
    std::cout << "StopEvent" << std::endl;
  }
  virtual ~StopEvent() = default;
};

class StartEvent : public boost::statechart::event<StartEvent>
{
public:
  StartEvent()
  {
    std::cout << "StartEvent" << std::endl;
  }
  virtual ~StartEvent() = default;
};

class PauseEvent : public boost::statechart::event<PauseEvent>
{
public:
  PauseEvent()
  {
    std::cout << "PauseEvent" << std::endl;
  }
  virtual ~PauseEvent() = default;
};

//enum state declaration
enum class State : std::int8_t
{
  Stopped = 83, //S, S for Stopped status
  Running = 82, //R, R for Running status
  Pause = 80    //P, P for Pause status
};


//StateMachine main class
class StateMachine : public boost::statechart::state_machine<StateMachine, StoppedState> //the initialized status is Stopped
{
public:
  StateMachine() = default;
  virtual ~StateMachine() = default;

  State state_; //should not set it to public, but for simple, so so 
};

//Three states
class StoppedState : public boost::statechart::simple_state<StoppedState, StateMachine>
{
public:
  typedef boost::statechart::custom_reaction<StartEvent> reactions;
  boost::statechart::result react(const StartEvent & event) // StartEvent, will set the status from Stopped to Running
  {
    context<StateMachine>().state_ = State::Running;
    std::cout << "CurrentState = " << static_cast<std::underlying_type<State>::type>(context<StateMachine>().state_) << std::endl << std::endl;
    return transit<RunningState>();
  }
  virtual ~StoppedState() = default;
};

class RunningState : public boost::statechart::simple_state<RunningState, StateMachine>
{
public:
  typedef boost::statechart::custom_reaction<PauseEvent> reactions;
  boost::statechart::result react(const PauseEvent & event)// PauseEvent, will set the status from Running to Paused
  {
    context<StateMachine>().state_ = State::Pause;
    std::cout << "CurrentState = " << static_cast<std::underlying_type<State>::type>(context<StateMachine>().state_) << std::endl << std::endl;
    return transit<PauseState>();
  }
  virtual ~RunningState() = default;
};

class PauseState : public boost::statechart::simple_state<PauseState, StateMachine>
{
public:
  typedef boost::statechart::custom_reaction<StartEvent> reactions;
  boost::statechart::result react(const StartEvent & event) // StartEvent, will set the status from Paused to Running
  {
    context<StateMachine>().state_ = State::Running;
    std::cout << "CurrentState = " << static_cast<std::underlying_type<State>::type>(context<StateMachine>().state_) << std::endl << std::endl;
    return transit<RunningState>();
  }
  virtual ~PauseState() = default;
};

state_machine.cc

#include "state_machine.h"
//It is an empty file, all code is in its header file

main.cc

#include <iostream>

#include "state_machine.h"

int main(int argc, char * argv[])
{

  StateMachine sm;
  sm.initiate();

  //exception testing
  sm.process_event(PauseEvent()); //can't pause

  sm.process_event(StartEvent());
  sm.process_event(PauseEvent());

  sm.process_event(StartEvent());
  sm.process_event(PauseEvent());

  sm.process_event(StopEvent());  //can't stop

  sm.process_event(StartEvent());
  
  sm.process_event(StopEvent()); //can't stop
  
  sm.process_event(StopEvent());  //can't stop

  return 0;
}

It is easy to use.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/75530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是零知识证明(ZK Proof)?Web2.0通往Web3.0的入口技术

古老的难题 女&#xff1a;你爱我吗&#xff1f; 男&#xff1a;爱&#xff01; 女&#xff1a;怎么证明&#xff1f; 男&#xff1a;…… 零知识证明的定义 零知识证明(Zero-Knowledge Proof)也叫做最小泄露证明&#xff0c;能充分证明自己是某种权益的合法拥有者&#xff0c…

【Docker】第四章 容器管理

4.1 创建容器常用选项 指令 描述 -i, --interactive 交互式 -t, --tty 分配一个伪终端 -d, --detach 运行容器到后台 -a, --attach list 附加到运行的容器 --dns list 设置DNS服务器 -e, --env list 设置环境变量 --env-file list 从文件读取环境变量 -p, --p…

知识点14--搭建k8s本地测试集群

首先要做安装前的准备&#xff1a; 1、最少三台节点&#xff0c;CentOS 7系统&#xff0c;每台不低于4核4G资源&#xff0c;并配置host域名 [roothdp1 ~] cat /etc/hosts 192.168.88.186 hdp1 192.168.88.187 hdp2 192.168.88.188 hdp32、所有节点保证时间同步、并做SSH互信 …

离散数学与组合数学-数理逻辑-01命题与联结词

文章目录1. 命题与联结词1.1 命题1.2 常用联结词1.3 命题公式1.4 命题的等值演算与推理等价关系式基本等价式1. 命题与联结词 1.1 命题 命题&#xff1a;我们对确定对象做出的陈述句称为命题&#xff08;propositions and statements 命题或陈述&#xff09;。当判断为真时&a…

《小猫猫大课堂》2—开启C语言的世界,喵!

更新不易&#xff0c;麻烦多多点赞&#xff0c;欢迎你的提问&#xff0c;感谢你的转发&#xff0c; 最后的最后&#xff0c;关注我&#xff0c;关注我&#xff0c;关注我&#xff0c;你会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我…

学不会的python之正则表达式详解(re模块)

本篇博客介绍了正则表达式与在python中的应用(re模块)&#xff0c;及一些在开发中常见的模式示例。参考书籍《python核心编程(第三版)》 学不会的python之正则表达式正则表达式(模式)简介正则应用搜索与匹配注意特殊符号与字符择一匹配匹配单个字符注意问题起始、结尾、单词边界…

天津教育杂志天津教育杂志社天津教育编辑部2022年第35期目录

卷首语《天津教育》投稿&#xff1a;cn7kantougao163.com 强化教学保障意识 助力基础教育又好又快发展 本刊编辑部; 1 本刊视线_关注 家校协同下的青少年心理健康问题探讨 袁玉萍; 4-6 本刊视线_学校体育 中学体育课程主体活动教学模式的实施 张强;李聚虎; 7-9 本刊…

Python制作粒子烟花,提前开始跨年?

前言 跨年倒计时20天&#xff1f;我已经开始整烟花了&#xff0c;虽然不是很好看吧&#xff0c;但是也能将就看看 &#x1f625; 这个的背景图&#xff0c;音乐&#xff0c;还有文字都是可以自己修改的哦 效果展示 导入库 import random import pygame as py import tkinte…

CENTOS上的网络安全工具(十五)cascade的部署

这一篇&#xff0c;我们尝试在CentOS上安装并运用一款“小众”安全工具——Cascade。这个工具给人的感觉只是作为验证ATT&CK理念的一个存在&#xff0c;而且由于其运转还需要依托CAR&#xff0c;所以对数据的处理停留在主机log类的层面&#xff0c;可能暂时还不太受安全公司…

【Lilishop商城】No3-3.模块详细设计,会员信息(会员基本信息)、店铺设置(店铺信息、配送模板)的详细设计

仅涉及后端&#xff0c;全部目录看顶部专栏&#xff0c;代码、文档、接口路径在&#xff1a; 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑&#xff0c;其中重点包括接口类、业务类&#xff0c;具体的结合源代码…

Briefings in Bioinformatics2021 | 从头药物设计的深度生成模型的综合性评估

论文标题&#xff1a;Comprehensive assessment of deep generative architectures for de novo drug design 论文地址&#xff1a;Comprehensive assessment of deep generative architectures for de novo drug design | Briefings in Bioinformatics | Oxford Academic 一…

JMeter的三种参数化方式

一、 用户定义的变量 1.线程组-配置元件添加用户定义的变量 2.引用变量 ${变量} 二、 csv Data Set config &#xff08;1&#xff09;csv Data Set config之.CSV 1.造.csv格式文件的数据 2.设置CSV数据文件 3.消息体数据&#xff0c;引用变量名.{变量名} 4.设置线程组&…

关于Elasticsearch查询(match、match_phrase、query_string和term)

由上图看出&#xff0c; QueryBuilder 是整个查询操作的核心&#xff0c;决定了查询什么样的数据和期望得到什么结果这些核心的问题。 QueryBuilder 只是一个接口&#xff0c;需要具体的实体类才可以。那么如何创建 QueryBuilder 的实例呢&#xff1f;有两种方式 通过 QueryB…

AOP开发明确的的事项

12.2. AOP开发明确的的事项 12.2.1、需要编写的内容 编写核心业务代码&#xff08;目标类的目标方法&#xff09; 编写切面类&#xff0c;切面类中有通知(增强功能方法) 在配置文件中&#xff0c;配置织入关系&#xff0c;即将哪些通知与哪些连接点进行结合 12.2.2、AOP 技…

什么是MinIO

本文为joshua317原创文章,转载请注明&#xff1a;转载自joshua317博客 什么是MinIO - joshua317的博客 什么是MinIO&#xff1f; MinIO 是一款高性能、分布式的对象存储系统. 它是一款软件产品, 可以100%的运行在标准硬件。即X86等低成本机器也能够很好的运行MinIO。 MinIO提…

容灾演练月报 | 福莱特集团核心系统完成“跨云”容灾切换演练

11月&#xff0c;美创科技携手福莱特集团、金华银行、稠州银行、慈溪市卫健委及医疗行业等总计19家用户完成容灾切换演练&#xff0c;其中完成2次灾难切换&#xff0c;有效验证了各用户单位容灾系统的可靠性及高可用性&#xff01; 本月典型案例&#xff1a;福莱特集团 福莱特集…

CANoe.DiVa简单配置

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

RK3588核心板显示资源分配实操竟如此简单!飞凌嵌入式

前言 眼睛作为人类最重要的感觉器官&#xff0c;通过“视觉”帮助我们接收了大部分的外界信息&#xff0c;“视觉效果的好坏”直接影响着我们日常生产和生活质量的高低&#xff0c;因此“显示能力”成为了评价产品优劣的一项重要指标。在影音、游戏、智慧办公、工业自动化和交通…

OpenAI ChatGPT微信接入教程

OpenAI ChatGPT微信接入教程 OpenAI ChatGPT 接入 个人WeChat(微信)&#xff0c;让AI互动更方便&#xff01; 准备工作 Ⅰ&#xff0c;OpenAI 账号&#xff0c;参考ChatGPT注册试用全攻略 Ⅱ&#xff0c;微信账号&#xff08;需要绑定支付方式&#xff0c;需支持网页登录&am…

JVM篇之牛刀小试(三)年轻代参数优化探索

前言 在JVM 篇之 牛刀小试 &#xff08;一&#xff09;我们谈到了关于年轻代参数的问题&#xff0c;就是当我没有设置-Xmn的时候&#xff0c;gc时间居然比我设置了500m的时候&#xff0c;时间还短&#xff0c;然后当时我就停止了探索。 后来我在公司飞书文档写了一篇文章分享&…