尝鲜QM 4.0.0 -- 安装、注册、试用子机功能

参考1:http://www.ceeger.com/Manual/NestedStateMachines.html
参考2:http://www.uml-diagrams.org/state-machine-diagrams.html#submachine-state
参考3:http://www.state-machine.com/qm/index.html

已经一年多没有动静的QM,今天早上(2016-12-07)更新了QM 4.0.0,带来了宣传很久的子机图(Submachine Diagrams)和子机状态(Submachine States)功能。虽然只是一个甜点功能,但对于那些为状态图太大打印不到一张A4纸上,而苦恼的同学还是很有用的。


安装

很简单,然后一路点next在默认目录下安装就OK了。

注:刚发布的QM有个BUG,安装完毕后打开会报错:

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第1张图片

解决的办法就是,先安装QM 3.3.0,然后直接在同一个默认目录下覆盖安装QM 4.0.0。目前这个BUG已经被修复,请到官网下载最新版的安装包(版本号还是4.0.0)。

另外,QM 4.0.0对应的是QPC、QPN和QPCPP的5.8.0或者更新的版本,请提前下载并安装好。


注册

在QM 4.0.0中,默认只能生成QHsm风格状态机代码,生成QMsm风格的状态机代码的功能,需要在注册后才能使用。

打开QP的例子也可以看到,官方提供的.qm文件中默认使用的状态机策略换成了QActive/QHsm,如果强行修改活动对象的类型为QMActive,那么在生成代码的时候会产生这样的一个错误提示:

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第2张图片

幸好在5.8.0版的QP自带自带了一个可用到2017-01-31的评估许可(License )文件,比如在QPC_5.8.0里的就是QPC-EVAL-161130.qlc,它的文件格式类似于:

Bamboozle Technologies, Inc.
qpc
2016-12-24
eGizmo Shuffle 2nd Generation
#6031A51FBD8C7B9281C5E38C29E6EA9B18FA0F1C

第一行的是商业许可的名称(公司或者个人)

第二行的是QP框架的类型(qpc/qpn/qpcpp)

第三行的是准可的到期期限

第四行的是说明许可是用于单一产品还是产品线

第五行的是对许可的哈希加密,防止许可被篡改

购买过QP的用户在邮件里可以收到对应的许可文件;如果没有购买过,需要获取商用版许可的,请到http://www.state-machine.com/licensing/index.html#RequestForm中申请。

现在开始注册QM,首先QM的注册是写入到qm模型文件里的,对于每个新的.qm文件都要重新注册一遍,可将.qlc文件复制到C:\qm下,以方便注册。

打开qp中任意一个例子中的qm文件,点击工具条里的“View/Change License”图标,然后点击“Register Commercial QP License”按钮选择QPC-EVAL-161130.qlc。

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第3张图片

OK注册成功

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第4张图片

上图中的License File Relative to the Model复选框,指的是许可文件是否使用和qm模型文件的相对路径,因为我们统一放置qlc文件到C:\qm下了,并且暂时不需要拷贝到别的PC上执行,所以无需勾选。许可的注册是关联到单个qm模型文件里的,每次打开这个qm模型文件的时候,都会进行检查。

好的,顺利生成代码:

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第5张图片


试用子机功能

子机图和子机状态是QM 4.0.0的主打功能,为了实现这个功能QP的5.8.0版本对状态机的派生方式做了修改。

在5.8.0之前版本QP中,QMsm是QHsm的基类;而在5.8.0版中,则反过来通过QHsm派生出QMsm。

对于官方而言这样修改的好处是,可以通过QHsm提供基本的层次状态机,它派生出的QMsm则增加更高级的功能(比如这次增加的子机状态),从而顺势让QM增加注册功能,限制普通用户使用高级功能- -!

另外,5.8.0版的QPN在这次更新中阉割了QMsm,想要使用子机图设计状态图,就要改用全功能的QPC和QPCPP。

这次更新官方提供了一个子机的例子,位于(qp)\qpc\examples\win32\calc1_sub之下,我们可以用它来和原有的calc1例子作为对比。

为了方便大家熟悉QM新增的子机功能,我们选择将原有的calc1例子一步一步的加入子机功能,注意先做好备份。

  • 回顾例子Calc

打开(qp)\qpc\examples\win32\calc1\calc1.qm,在Model Explorer窗口中修改Calc类的超类为QMsm。打开Calc类的状态图:

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第6张图片

回顾下例子calc,这个例子出自psicc2的第2.4节,演示了如何设计一个计算器。其中,事件与键值对应的关系如下:

DIGIT_0_SIG:按键 ‘0’,输入数字
DIGIT_1_9_SIG:按键 ‘1’-‘9’,输入数字
POINT_SIG: 按键 ‘.’,输入小数点
OPER_SIG:按键 ‘+’ ‘-’ ‘*’ ‘/’,输入操作符
EQUALS_SIG:按键 ‘=’ ‘Enter’,得出结果
C_SIG:按键 ‘c’ ‘C’,撤销一个输入
CE_SIG:按键 ‘e’ ‘E’,撤销输入为空
OFF_SIG:按键 ‘ESC’,退出计数器

为方便理解,上面的状态图可以简化为:

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第7张图片

可以看出这个计算器的操作流程是,首先在operand1状态输入第一个被操作数,然后接收到’+’ ‘-’ ‘*’ ‘/’之后跳转到opEntered状态等待输入下一个被操作数。之后在operand2状态里输入完第二个被操作数后,得出结果。

  • 分析1

在原有的Calc状态图中,operand1和operand2状态都含有较多的嵌套状态,并且内部的转换也较多,影响到了状态图的阅读。为了让状态图变得清晰,可以将operand1和operand2变为子机状态。

QM有两种添加子机图的方式,一种是直接添加子机图一般用于新编写的子机;一种是将状态图中的状态转换成子机图。下面先介绍第一种方式。

  • 添加子机图:方法1

以operand1为例,在Model Explorer窗口中的Calc类的SM属性下,右键添加子机:

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第8张图片

将这个子机图的名字改成operand1,在Model Explorer窗口双击operand1子机的图标,会打开operand1子机图。

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第9张图片

可以看到右侧工具条多了两个图标,上面的叫入口节点段(Entry-Point Segment,后面统一称为Entry-Point),下面的是出口节点(eXit-Point)。

在operand1子机中添加zero1、int1、frac1、negated1状态,并添加entry和exit动作。
拉动子机图的边框,调整子机图的大小:

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第10张图片

  • 添加子机图:方法2

在原有的Calc状态图中,选中operand2状态并点击右键,选择“Add Sub-Machine from State”

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第11张图片

很顺利的生成了operand2子机

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第12张图片

删除operand2子机tran到外部的三个事件:OPER_SIG,EQUALS_SIG,CE_SIG。

  • 分析2

Calc状态图中的operand1状态下嵌套的,zero1、int1、frac1、negated1状态,都有一个外部的tran指向它们,所以子机需要设置4个Entry-Point。

同时,operand1状态通过在碰到3种事件的时候会tran到别的状态,因此还要给子机添加3个eXit-Point。

观察到,operand1和operand2子机实现的功能其实是一样的,对于功能类似的子机其实只要保留一个就好了。子机和子机状态的关系可类比于,类和对象,一个子机可以实例化出多个子机状态。本文保留的是operand1子机,将它改名为operand,并将它内部的几个状态改名为zero、int、frac、negated。

  • 增加Entry-Point和eXit-Point

给operand1子机增加Entry-Point和eXit-Point:

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第13张图片

值得注意的是eXit-Point需要连接到自转换上(如上图中的CE事件)。

子机状态作为一个状态,可以像普通状态那样,拥有entry、exit action和initial transition,并处理事件(如上图中的CE_SIG事件),并通过这个事件直接tran到别的状态上,而无需通过eXit-Point。所以本次示范中,就没给OPER_SIG和EQUALS_SIG事件设置eXit-Point。

  • 添加子机状态

打开Calc状态图,在右侧工具条中,可以看到相对过去的QM在工具条下方增加了两个图标,
上面的叫子机状态(Submachine States),下面的是出口节点段(eXit-Point Segment,后面统一称为eXit-Point)。

点击子机状态图标,在Calc状态图放置一个子机状态,然后修改它的类型为operand,并命名为operand1:

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第14张图片

将原有指向operand1状态内部嵌套zero1、int1、frac1、negated1状态上事件tran线连接到operand1 子机状态的4个Entry-Point上。

点击工具条上的eXit-Point图标,从operand1 子机状态的ce eXit-Point连接到ready状态里嵌套的begin状态上。并将operand1状态原有的CE事件的action拷贝到ce eXit-Point的action中。

然后,将operand1状态上的OPER_SIG和EQUALS_SIG事件也连接到operand1 子机状态上。

最后在Calc状态图中选中operand1状态,然后在Model Explorer窗口中的高亮的operand1标签下的几个标签统统删掉(因为operand1 子机状态在这里被放置到了operand1状态内部,QM会误认为它是被operand1状态内嵌的,注意别删错了)。

对于operand2状态也用以上的方法处理,状态图被简化成了:
尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第15张图片

  • 编译运行

注:在make工程之前先要保证:安装了MinGW,并且将make.exe的目录和QPC的目录,设置到环境变量中。本文不做展开,具体请百度。

make后,执行dbg/calac1.exe后,并测试44+58*61-2=?

尝鲜QM 4.0.0 -- 安装、注册、试用子机功能_第16张图片

结果变成了44 + 58*61- 2 = 46

原版的calac1也是这样的结果,有兴趣的可以修改下。

你可能感兴趣的:(状态机)