简单层次状态机的C语言实现

一年前同学推荐开个博客,还确实有写博客的想法,当时正在过年,可能吃的太好了吧,反正后来这事就不了了之。临近年关,突然又想起来这事。工作两年多来也积累了不少东西,不过一直苦于没有时间静下心来总结,正好最近有时间把自己的成长过程记录下,作为写博客的一个开端,万事开头难,能不能坚持下去以后再说,先开个头。好了废话少说,开始正题。

程序员一般都不会对状态机陌生,典型应用如通信数据解析。什么,你要我解释什么是状态机?LZ最不擅长名词解释了,请自行Google。那什么叫层次状态机呢,这里简单解释一下,层次状态机比普通状态机的优势是它能实现行为继承,所谓的行为继承可简单理解处理为状态机的多个子状态的都具有超状态的特性,子状态是超状态的特例。这里介绍一种用状态机实现的事件驱动程序框架,这源于LZ最近拜读了《UML 状态图的实用C/C++设计---嵌入式系统的事件驱动型编程技术 》这本书,推荐做嵌入式软件的读者研读一下,里面的一些思想还是很有价值的。

下面来实现简单的事件驱动状态机。 实现状态机一般有三种方法:1.简单swich-case结构。2.状态表。3函数指针。有时间再具体详细写篇博客介绍一下,这里使用第三种实现办法,上代码:

#include "stdafx.h" #include <stdio.h> //定义消息 enum SIG EAT_SIG , RUN_SIG , CANCEL_SIG //定义消息是否被子状态处理 enum HANDLEINFO HANDLED = 0 , NO_HANDLED struct Fsm ; typedef unsigned char handleinfo ; typedef handleinfo ( * State )( Fsm * , unsigned const ); struct Fsm State state ; 通过将与状态相关的行为封装在具体的状态类中,并通过上下文类进行状态的转换和处理,我们可以 实现 一个灵活、可扩展的 状态机 系统。在上下文类中,我们维护了一个当前状态的指针,通过调用状态对象的接口方法 实现 状态的进入、处理和退出。当需要增加新的状态时,只需创建新的具体状态类,并在状态转换时考虑新状态的条件即可,而无需修改原有的类。首先,我们定义一个抽象状态类(AbstractState),它声明了状态类的接口,包括状态的进入动作、状态的处理动作和状态的退出动作。在嵌入式 状态机 中,每个具体的状态类表示系统的一个状态。 这次我们一起来学习 C语言 实现 状态机 的三种方法解析。 状态机 实现 无非就是 3 个要素:状态、事件、响应。转换成具体的行为就 3 句话。发生了什么事?现在系统处在什么状态?在这样的状态下发生了这样的事,系统要干什么?用 C 语言 实现 状态机 主要有 3 种方法:switch—case 法、表格驱动法、函数指针法。 至此 层次 状态机 - HSM 应用解析到此结束,上一篇文章和本文章是紧密结合的,必须看懂前者才能看明白上述的相机工作例子。理解 HSM 的状态调度机制和事件调度机制非常重要,笔者总结能力有限,可能没办法很清晰的描述出来,但是建议读者使用笔将整个状态和事件关系列举出来,相信会有不一样的收获哦。 出处:http://www.cnblogs.com/tangerious/p/4565833.html 状态机 的好处不用多说,自己百度去,但传统的编程模式,无论是 C语言 ,或是硬件FPGA的Verilog都是采用switch-case结构,硬件的还好说,是并行的,但如果是 C语言 实现 状态机 则可能需要对每个case进行判断,状态少比如几个可能没什么效率之类的问题,但状态多几十个上百个呢,那么就需要进行 首先,我们包括 hsm /statemachine.h,它引入了整个 hsm 库。我们宣布一个名为First状态。状态是继承自 hsm ::State的结构或类。注意:我们更喜欢使用structs而不是类,因为默认情况下它们是公开派生的,所以不需要指定“public”关键字。主要来说,我们初始化一个StateMachine对象,告诉它First是它的初始状态。所有StateMachine都必须有一个初始状态才能启动。 每个父类 状态机 内部有若干个子 状态机 (可自由添加更多子类 状态机 ) 二、直接上代码 /**************************************************************************** 作者:小鱼儿飞丫飞 日期:2020-6-19 文件名:FSM 层次 状态机 头文件 ************************************************************* 为了方便我的游戏开发,写了这么一个通用的分层有限 状态机 。希望在其稳定以后,可以作为一个组件加入到我的游戏引擎当中。 目前使用了std::function来调用回调函数,在未来可能会用委托机制代替。 第一版仅仅是为了快速开发出来使用,在未来会对性能和易用性改进。 代码下载:http://download.csdn.net/detail/vvsxr/8060377... 有几种方法可以解决这个问题。这里有一个:编辑——添加了通用 层次 结构typedef unsigned op_code_type;typedef void (*dispatch_type)(op_code_type);typedef struct hierarchy_stack hierarchy_stack;struct hierarchy_stack {dispatch_type func;hie... 本文讲述 层次 状态机 实现 形式中的行为继承。从行为继承与类继承之间的OO类相似来看,一个成功的 层次 状态机 应该能够模拟下列属于C++对象模型。 ²        使用和维护 简单 ²        应允许转态机拓扑容易改变,不应要求转换连接的人工代码,所需要的修改限制在代码的一个地方。 今天心情不错,突然想明白了困扰自己几个月的 HSM 层次 状态机 )问题,“顿悟”的感觉真是舒畅。这也再次证明不够聪明的人(我),应该勤能补拙。废话少说,把自己的体会总结如下。 HSM 被称为 层次 状态机 ,用一个专业术语就是具有行为继承,类似OOP中的类继承。那怎么去理解这个行为继承呢,稍后再说。         首先来说说FSM, 状态机 ?如果我们把每个状态都认为是一个函数,并且函数返回 状态机 我们大家都知道,有一个专门的设计模式 状态机 模式,类图大概如下图:不过如果按照下面图来 实现 状态机 ,基本来说非常难用,没有实用性,只能作为教科书的产品。今天我们要 实现 的是一种通用 状态机 ,可以Send事件,每一个状态可以响应自己注册的事件,同时也可以通过自身或者事件来改变 状态机 的状态 代码地址:https://github.com/9435202/StateAPI go- hsm go- hsm 是一个 实现 分层 状态机 HSM )的 Golang 库。 分层 状态机 HSM )是一种表示 状态机 的方法。 Miro M. Samek 博士在《 》一书中介绍了它。 与传统的 状态机 实现 方法(例如嵌套 if-else/switch、状态表、OOP 中的状态设计模式)相比, HSM 提供了以下主要优势: 它支持嵌套状态和 hehavior 继承 它为状态提供进入和退出动作 它使用类 层次 结构来表示状态 层次 结构。 易于编写和理解。 上面提到的这本书详细介绍了 状态机 HSM 。 有关详细信息,请参阅。 每当需要编写具有高复杂性但需要绝对正确的代码时, 状态机 都是一种很有前途的方法。 HSM 是一种很好的表达 状态机 的模式。 HSM 是迄今为止我所知道的最强大的模式。 当我遇到一些 Golang 项目,比如时,我想到了 HSM 。 所以我将 HSM 移植到 Golang 并创建了