QP官网网址:http://www.state-machine.com

本书下载地址:

笔记有点乱,没办法,书里也是断断续续的介绍。

UML:

UML状态图:状态用节点表示,转换用弧线连接在节点间。状态节点用圆角方框表示。状态名用粗体,写在状态框顶部的名字格里。在名字下面有一个可选的内部转换格,用一条水平线分开。内部转换格包含进入动作内部转换格包含进入动作(在保留符号entry后的动作)退出动作(在保留符号 exit 后的动作)和其他内部转换(比如在图中里被 TIME_TICK触发的那些动作)。状态转换用从源状态边界指向目的状态边界的箭头表示。最低要求,一个转换必须用触发事件来做标签。触发可以有可选的多个事件参数,一个监护条件和一个动作列表。

最终状态在 UML 符号里是牛眼 (bull’s eye) 符号,通常的用法是指示状态机对象的析构(destruction)。

图1 状态图示例

状态嵌套的威力在于它被设计于用来排除可能会发生的重复。高层的active 状态被称为超状态 (superstate) ,它的抽象定义是,状态机不能直接在这个状态里,只能在它里面嵌套的某一个状态里,这个状态被称为活动子状态。 UML 和状态嵌套有关的语法说明,任何事件先被当前正在活动的子状态 (substate) 处理,如果这个子状态不能处理这个事件,状态机尝试在较高一层超状态的上下文处理这个事件。当然, UML 里的状态嵌套不限于仅一层,而且,这个处理事件的简单规则可以递归的应用于任何多层的嵌套。

图2 QP状态机主框架

上图展示了QEP事件处理器,QF实时框架,QS,QK,Qvanilla。

QF简介:

QF框架两种事件派送机制:

1. 简单的直接发送。比较简单的机制,通过函数 QActive_postFIFO() 和 QAcive_postLIFO() 直接进行事件发布,一个事件的产生者直接把这个事件发布到作为这个事件消费者的主动对象的事件队列。

2. 灵活的发行 - 订阅事件传递机制,通过函数 QF_publish()和 QActive_subscribe() 支持。事件的产生者把事件发行给框架,框架然后把它传递给所有订阅了这些事件的主动对象。

QF处理全部的线程安全的事件交换和排队细节。

QF里的主动对象是封装后的状态机,QF事件队列只拥有指向对象的指针。

QF框架可以管理3个不同大小块的事件池(大中小)。小事件池必须在中等事件池前初始化。

在 QF 里,系统的任何部分,而不仅局限于主动对象,都能够产生事件。例如,中断服务程序(ISR) 或设备驱动程序也能产生事件。另一方面,只有主动对象能消费事件,因为只有主动对象才拥有事件队列。

QF 的事件管理的最重要的特征是,框架只传递指向事件的指针,而不是事件本身。 QF 从不复制事件(零复制策略)。

时间事件由应用程序分配,但是由 QF 框架管理。 QF 提供函数去启动 (arming)一个时间事情,例如一次性超时的 QTimeEvt-postIn() ,和周期性时间事件的 QTimeEvt_postEvery() 。启动一个时间事件实际上通知 QF 框架。

在 QP 里,事件被表示为使用框架提供的 QEvent结构的实例。具体来说, QEvent结构包含成员 sig ,它表示事件的信号。通过继承过程来添加事件参数。如下文“ C 语言里的单一继承”所描叙。

继承是基于已有结构派生新的结构,从而重用和组织代码的一种能力。你可以非常简单的在 C 里实现单继承,只要字面上把基础结构作为派生结构的第一个成员即可。例如,图 3( a )显示了通过把QEvent实例作为 ScoreEvt 的第一个成员嵌入,从而从基础结构 QEvent派生出结构 ScoreEvt 。为了使这个用法更加突出,我总是把基本结构成员命名为 super。

图3

你总是可以安全的传递一个指向 ScoreEvt 的指针,给任何需要一个指向 QEvent的指针的函数。(严格来讲,在 C 里你应该显式的转换这个指针。在 OOP里,这种转换被称为向上类型转换 (upcasting) ,而且它总是安全的。)结果,所有为 QEvent结构设计的函数自动的适用于 ScoreEvt 结构和其他从 QEvent派生的结构。图 3(c) 的 UML 类图,说明了 ScoreEvt 结构和 QEvent结构的继承关系。

QP 非常广泛的使用单继承,不仅用来派生带有变量的事件,也用来派生状态机和主动对象。当然,QP 的 C++ 版本使用固有的 C++ 类派生而不是“结构的派生”。

在 C 和 C++ 里,一个函数指针 QHsm_top() 可以写成 QHsm_top 或 &QHsm_top 。尽管QHsm_top 表达更加简洁,我更喜欢使用表达式 &QHsm_top ,以表明这里我确实需要一个函数指针 &QHsm_top。

事件在大多数应用构件间是共享的。

应用程序的信号不是从 0 开始,而是有常数为 Q_USER_SIG 的偏移。这是因为 QP 保留了最低的几个信号给内部使用,并提供常数 Q_USER_SIG 作为偏移值,用户信号从它开始枚举。

全局指针代表在应用程序里的主动对象,并被用来直接发送事件给主动对象。因为这些指针可以在编译时间被初始化,我喜欢把它们声明为 const,这样它们能被放在 ROM 里。这些主动对象指针是“不透明的” (opaque) ,因为它们不能访问整个主动对象,只能访问从QActive 结构继承的那部分。

top 状态是 UML 的概念,表明在一个层次式状态机里的状态层次的终极根 (ultimate root)。

当实现状态处理函数时你需要注意在这些函数由 QEP 事件处理器而不是你的代码管理。 QEP将根据不同的原因调用某个状态处理函数:层次事件处理,执行入口和出口动作,触发初始转换,或仅仅引出某给定状态处理函数的超状态。因此,你不能假设某个状态处理函数仅仅用来处理在那些在 case 语句后的信号。你必须避免任何在 switch 语句之外的代码,特别是那些有副作用的代码。

传统的解决办法是完全针对手头的问题,而状态机方案是通用性的。

图4

Quickstart程序和“飞行和射击”实例相比有更多的循环式控制流程,因为传统的解决办法是完全针对手头的问题,而状态机方案是通用性的。 Quickstart应用程序的结构和传统的顺序式程序非常相似,它尽量从头到尾保持控制。它不时的停住,忙等待某个事件,代码基本上没有准备好去处理任何它在等待的事件以外的其他的事件。这些都是由于设计的不灵活性导致。增加新的事件是困难的,因为需要更改的代码的整个结构被设计为只接收很特定的事件,而且需要被剧烈的改变从而容纳新的事件。同样,当忙等待屏幕更新事件时(等效为“飞行和射击”游戏里的 TIME_TICK事件),程序不会对任何其他的事件产生反应。任务级响应难以被确定,通常它和事件的类型有关。通过硬编码确定的等待时序适合现有的事件但是也许不会适合新的事件。

相反,“飞行和射击”游戏有更加简单的控制流程,纯粹的由事件驱动并且完全通用(见图1.11(b) )。每个主动对象的上下文表示为一个状态机的当前状态,而不是某处的代码。这样,根据当前上下文在代码某处进行“事件循环”变得没必要了。相反,状态机把上下文当做一个很小的数据成员的方法是很有效率的。在处理完每个事件后,状态机能返回为被设计成能处理全部事件的公共事件循环。如果必要的话,状态机自然的挑选每一个事件并移动到下一个状态。很容易在这种设计里增加新的事件,因为状态机在任何时候可以响应任何事件。一个事件驱动的基于状态机的应用程序,和传统的程序相比,更加灵活,更有弹性。

当编码基本上不成问题时,大部分编程工作就花在设计应用程序上了。

一个事件驱动程序运行时,不停的查看可能的事件,当一个事件被探测到,就分派这个事件到合适的状态机构件(见图 1.11(b) )。为了让这个方法可以工作,必须连续频繁的查看事件。这意味者状态机必须很快的运行,这样程序能返回来查看事件。为了符合这个要求,状态机不能进入到需要忙等待一段较长或不确定时间的状态。这种状态最普遍的例子就是在一个状态处理函数内的 while 循环,退出循环的条件,比如按键输入,不受程序的控制。这类一个无限循环的程序结构,被称为“阻塞“代码 ,你可以在 Quickstart应用程序里看到这些例子(见图 1.11(a) )。为了让事件驱动型编程模式能工作,你必须只编写“非阻塞”代码。

UML状态图的实用C/C++设计(QP状态机)-笔记一相关推荐

  1. 时序扩展的UML状态图的测试用例生成研究

    一.基本信息 标题:时序扩展的UML状态图的测试用例生成研究 时间:2014 出版源:西南大学 领域分类:时序扩展:UML状态图:测试用例:需求规格说明:模型 二.研究背景 问题定义:时序扩展的UML ...

  2. 【转】超详细的UML状态图符号,初学者也能轻松看懂状态图

    UML状态图,用于显示状态机,即描述一个对象所处的可能状态以及状态之间的转移.用状态图建模可以帮助开发人员分析复杂对象的各种状态的转换,以及对象何时执行怎样的动作.那状态图又是怎样表示这些信息的呢?要 ...

  3. UML状态图和活动图

    转载于https://www.cnblogs.com/jingwhale/p/4230235.html UML状态图和活动图 UML状态图和活动图 统一建模语言UML(Unified Modeling ...

  4. 10个实用的UX设计作品推销小窍门

    以下内容由Mockplus(摹客)团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具. 众所周知,产品用户体验很重要,即使是Google也知道这一点.但是,当真正涉及到UX 设计销 ...

  5. UML状态图 2021.07.18

    概述 UML状态图主要用于描述对象具有的各种状态.状态之间的转换过程以及触发状态转换的各种事件和条件. UML 状态图的目的: UML 状态图可以捕获对象.子系统和系统的生命周期,可以告知一个对象可以 ...

  6. 软件工程结对项目--实用计算器的设计和制作

    一.题目简介 题目:软件工程结对项目--实用计算器的设计和制作 简介:计算器是人们生活中经常使用的一种工具,已经可以说是人们日常生活中必不可少的工具了.本次实验我们设计并实现了一款基于Android系 ...

  7. Spring StateMachine(2) UML状态图支持

    还是刚才的以二级审批请假流程为例. 绘制流程 首先创建 Papyrus 项目,选择 StateMachine 模板,绘制流程图如下: 然后创建 6 个 signal event 和与之绑定的 sign ...

  8. 菜鸟实战UML——状态图

    状态图 状态图(Statechart Diagram):是描述一个实体基于事件反应的动态行为,显示了该实体如何根据当前所处的状态对不同的事件做出反应.通常我们创建一个UML状态图是为了以下的研究目的: ...

  9. 超强干货,11个灰常实用的AI设计小技巧!

    11个超级实用的AI设计小技巧!涉及到很多的实用操作,纯干货经验总结,灰常值得收藏,赶快转走学起来吧! ​编辑:千锋UI设计

最新文章

  1. OneFlow 概念清单
  2. js 函数调用顺序研究
  3. Python之流程控制
  4. 去掉softmax后Transformer会更好吗?复旦华为诺亚提出SOFT
  5. python适配器模式角色_Python设计模式之适配器模式原理与用法详解
  6. vsftp的被动模式
  7. NETINT刘迅思:底层软件开发向上层应用靠拢
  8. 深入delphi编程(转)
  9. mysql数据库应用_MySQL数据库应用 从入门到精通 学习笔记
  10. 前端有关vue的面试题
  11. SQL必知必会-视图
  12. MTK 驱动(73)--- Kernel Backtrace 无法显示出具体的地址.
  13. java socket - 传递对象
  14. 01我为什么学Unity3d
  15. Java单链表中的元素互换位置_Java如何在链表的第一个和最后一个位置添加一个元素?...
  16. 数据库sql操作实验报告
  17. python win32api sendmessage_win32api win32gui win32con 窗口句柄 发送消息 常用方法
  18. 计算机导论论文含图,计算机导论(论文).doc
  19. 计算机保研厦大面试,保研其实不难:他们保研人大、厦大、山大,有这些经验,值得收藏!...
  20. 计算机专业术语,收藏用

热门文章

  1. SV学习笔记—结构体及枚举类型及字符串
  2. 电脑一打开计算机硬盘就嗡嗡,电脑主机嗡嗡响 怎么解决?
  3. java中的@param参数_dao层方法中的@Param说明
  4. 两个房间 每间房间三盏灯
  5. 翻译小窍门-高智商的游戏 看谁能过
  6. 【系统之家】---开机进不了系统、PE、光盘 等也启动不了怎么办?
  7. Ionic3开发环境搭建-VS Code
  8. maven profile filter 线上线下分开打包配置
  9. Hive 学习(五) Hive之HSQL基础
  10. 第十三届Revit二次开发实战训练课程22年3月21在武汉举办