QEP之init()和dispatch()流程图
抽象状态机类QFsm或QHsm有一个函数指针,用于在继承的具体状态机类中指向具体的状态函数,其有两个对外的接口函数init()和dispatch(),其工作原理是理解状态机处理事件过程的关键。
具体状态机类继承自QFsm或QHsm,同时继承了这个函数指针,用于动态指向具体状态机类中的私有状态函数。
具体事件继承于根事件QEvent,并可以自己增加附加的属性。事件是外部与状态机唯一通信的实体,通过dispatch(),把事件送到状态机。状态机对外不可见,具体属性和具体状态函数都是私有的。

图1.QEP总体类结构
1.预备知识
(1)声明一个函数指针
具体状态机类继承自QFsm或QHsm,则具体状态机具有了一个指针state,state可以指向任何状态函数,并调用状态函数执行。dispatch()函数可以用空事件探测状态机的结构、可以执行进入和退出动作、可以执行具体的事件处理动作,也可以进行状态转移。
typedef uint8_t QState;
typedef QState (*QStateHandler)(void *me, QEvent const *e);/*函数指针*/
(2)声明一个状态机中的函数指针变量
typedef struct QFsmTag {
QStateHandler state; /*变量(函数指针),指向状态机当前状态(函数)*/
} QFsm;
typedef struct QFsmTag QHsm;
(3)状态函数处理后的返回结果
每个状态函数中,根据不同的事件处理,处理完后要返回上边的结果之一,供dispatch()了解状态函数对某事件是否忽略、是否处理完、是否转换、是否不能处理而要让父状态函数来处理。
QSUPP(super)中的参数决定了层次状态机的层次结构。
/* 忽略事件 */
#define Q_IGNORED() (Q_RET_IGNORED)
/* 已处理事件 */
#define Q_HANDLED() (Q_RET_HANDLED)
/* 状态转移 */
#define Q_TRAN(target_) \
(((QFsm *)me)->state = (QStateHandler)(target_), Q_RET_TRAN)
/* 到超状态 */
#define Q_SUPER(super_) \
(((QHsm *)me)->state = (QStateHandler)(super_), Q_RET_SUPER)
(4)触发动作
dispatch()用于主动去触发具体状态机,以探知状态机的结构、执行进入和退出动作。用QEPEMPTYSIG触发空动作,总是会执行到状态函数的最后一行QSUPPER(super_),通过触发后的返回结果,可以探知状态机的层次结构。
/* 以sig_信号触发状态机 */
#define QEP_TRIG_(state_, sig_) \
((*(state_))(me, &QEP_reservedEvt_[sig_]))
/* 触发退出动作,在层次状态机HSM */
#define QEP_EXIT_(state_) \
if (QEP_TRIG_(state_, Q_EXIT_SIG) == Q_RET_HANDLED) { \
...QS \
}
/* 触发进入动作,在层次状态机HSM */
#define QEP_ENTER_(state_) \
if (QEP_TRIG_(state_, Q_ENTRY_SIG) == Q_RET_HANDLED) { \
...QS \
}
/* 触发空动作,在层次状态机HSM (自加)*/
#define QEP_EMPTY_(state_) \
QEP_TRIG_(state_, QEP_EMPTY_SIG_)
2.Fsm状态机init()和dispatch()流程
(1)QFsm_init()流程

图2.QFsm_init()流程
(2)QFsm_dispatch()流程

图3.QFsm_dispatch()流程
3.Hsm状态机init()和dispatch()流程
从顶级状态的初始伪状态开始,到本初始伪状态转换的终状态(子状态),执行进入动作。在终状态(子状态)继续检查有没有子初始伪状态,如果有的话,继续进入,执行进入动作,直到最终状态。
(1)QHsm_init()流程

图4.QHsm_init()流程图与层次状态机
(2)QHsm_dispatch()流程

图5.QHsm_dispatch()流程图
关键词:状态机;抽象状态机类;具体状态机类,状态函数;初始伪状态;父状态;超状态;源状态;终状态;最终状态。
参考:
【1】Miro Samek《UML状态图的实用C/C++设计---嵌入式系统的事件驱动型编程技术》第二版
QEP之init()和dispatch()流程图的更多相关文章
- libevent源码深度剖析
原文地址: http://blog.csdn.net/sparkliang/article/details/4957667 第一章 1,前言 Libevent是一个轻量级的开源高性能网络库,使用者众多 ...
- redux源码解读
react在做大型项目的时候,前端的数据一般会越来越复杂,状态的变化难以跟踪.无法预测,而redux可以很好的结合react使用,保证数据的单向流动,可以很好的管理整个项目的状态,但是具体来说,下面是 ...
- Redux百行代码千行文档
接触Redux不过短短半年,从开始看官方文档的一头雾水,到渐渐已经理解了Redux到底是在做什么,但是绝大数场景下Redux都是配合React一同使用的,因而会引入了React-Redux库,但是正是 ...
- libevent 源码分析
1,前言 Libevent是一个轻量级的开源高性能网络库,使用者众多,研究者更甚,相关文章也不少.写这一系列文章的用意在于,一则分享心得:二则对libevent代码和设计思想做系统的.更深层次的分析, ...
- Redux原理(一):Store实现分析
写在前面 写React也有段时间了,一直也是用Redux管理数据流,最近正好有时间分析下源码,一方面希望对Redux有一些理论上的认识:另一方面也学习下框架编程的思维方式. Redux如何管理stat ...
- 【原创】Redux 卍解
Redux 卍解 Redux - Flux设计模式的又一种实现形式. 说起Flux,笔者之前,曾写过一篇<ReFlux细说>的文章,重点对比讲述了Flux的另外两种实现形式:『Facebo ...
- Android 启动过程简析
首先我们先来看android构架图: android系统是构建在linux系统上面的. 所以android设备启动经历3个过程. Boot Loader,Linux Kernel & Andr ...
- Redux1
Redux 写在前面 写React也有段时间了,一直也是用Redux管理数据流,最近正好有时间分析下源码,一方面希望对Redux有一些理论上的认识:另一方面也学习下框架编程的思维方式. Redux如何 ...
- react-redux源码解析
有理解不对的地方,欢迎大家指正!!! react为什么需要redux辅助???react是view层的单向数据流框架,数据需要一层一层往子组件传递(子组件并不会自动继承).子组件需要操作父组件的数据时 ...
随机推荐
- RuntimeBroker ClipboardBroker EoP
datetime: 2017.04.28 漏洞简介 随着沙箱技术的普及,现在主流的操作系统及软件都开始支持沙箱,以此来缓解层出不穷的远程代码执行漏洞对系统造成的危害.AppContainer是自Win ...
- centos 6 YUM安装 lnmp
准备篇: 1.配置防火墙,开启80端口.3306端口 vi /etc/sysconfig/iptables -A INPUT -m state --state NEW -m t ...
- AutoHotkey调用VBA实现批量精确筛选数据透视表某字段内容。
如上图,想在数据透视表中只显示红色区域的内容,手动勾选就比较繁琐. 实现思路: 先复制红色的内容. 鼠标停留在数据透视表[型号]列的任意数据上(通过该单元格可以获取数据透视表和字段) 由于数据透视表的 ...
- easyui学习笔记12—tab标签页的添加和删除
这一篇我们来看看标签页的添加和删除动作.我在想看这些例子还不如看文档,文档的内容更加全面,但是文档全部是理论没有实际的操作,看起来很枯燥,文档只能是遇到问题的时候查.easyui的文档写的还是很详细的 ...
- 记录linux查询命令的一个网站
http://man.linuxde.net/ 另外下面是对常用命令的总结 https://www.cnblogs.com/soyxiaobi/p/9717483.html
- 【[SHOI2014]概率充电器】
这是一道概率+树形\(dp\) 首先我们看到这里每一个的贡献都是1,所以我们要求的期望就是概率 求得其实就是这个 \[\sum_{i=1}^nP_i\] \(P_i\)为节点\(i\)通电的概率 显然 ...
- DataGrid添加滚动条
DataGrid中是没有滚动条的,要添加滚动条需要借助<div>层 <div style="overflow:auto;width:95%;height:95%" ...
- IDEA定位开发文件在左边工程中的文件路径
IDEA新公司入职使用第七天,基本快捷键和BUG调试已经搞透了!从最开始的配置到现在的适应确实是一个不小的进步,前几天每天加班太忙没有时间更新博客,明天就是五一假期,现在将刚掌握的一点IDEA技术写出 ...
- MacType 文字之美 – 让 Windows 字体更漂亮
苹果的Mac系统总能让人眼前一亮,除了其精美的软件界面设计外,最重要是其文字显示效果(渲染方式)比 Windows 更加清晰锐利,阅读起来更加舒服.于是就有高手开发了一款叫 GDI++ 的字体渲染引擎 ...
- HDU 2102 A计划(两层地图加时间限制加传送门的bfs)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2102 A计划 Time Limit: 3000/1000 MS (Java/Others) Me ...