如何创建一个状态机的应用程序,是比较简单的,如果把你的应用程序改造成状态机是比较困难的,换个说法,如何把应用程序优雅的用状态机实现,这有点考验你对项目需求和状态机两方面的理解能力。这一篇我们只讲把一个简单的应用编程一个状态机应用程序。
第一步,就是枚举信号,也就是整个状态机应用里面用到的所有信号都枚举出来。如下:
注意下,第一个信号A_SIG 的默认值是Q_USER_SIG,也就是说他是第一个Q_USER_SIG信号,而状态机本身是有几个被默认信号的,Q_ENTRY_SIG/Q_EXIT_SIG/Q_INIT_SIG,这几个默认的信号已经在QEP处理器中被事先定义好了:
第二步,定义事件类型,QEP有默认的事件类型,叫QEvt,他只提供一个最简单的类型,或者说是事件处理器需要的类型,实际应用中你可能需要一个事件带有其它的参数,这时候你需要继承QEP的默认事件来创建你的事件类型。这两种情况给出官方定义的两种事件类型的例子如下:
第三步、派生状态机类型,这个词在C++中用来还是比较合适,针对C来讲,我们暂且称之为定义状态机类型。
第四步、声明状态处理函数。
第五步、实例化一个特定状态机对象、以及实例化一个通用状态机全局指针。
第六步、构造状态机、类似于C++中的构造函数。
第七步、定义状态处理函数。
到这里应该没有遗漏的了,关于状态机相关的内容编码就完毕了,下面就是要真正的让状态机跑起来,你需要在main函数中进行一些操作,让这个状态机真正的运行起来,针对事件驱动型系统来讲,状态机本身是被动的,他不会主动进行任何操作,他需要事件处理器进行分发事件,然后根据分发的事件触发状态处理或转换。
关于如何让状态机运行起来,我们需要在main函数中进行一下操作,还是拿这个例程为模板进行说明吧。
第一步、显式调用ctor函数,构造状态机。
第二步、显式调用init函数,初始化状态机。
第三步、采集输入信号、构造事件对象、调用事件处理器,将相应的事件发送给状态机。
以上步骤就完成了一个单一状态机的编码及应用。