用状态机原理进行软件设计 联系客服

发布时间 : 星期六 文章用状态机原理进行软件设计更新完毕开始阅读

QSTATE Calc_negated1(Calc *me, QEvent const *e); QSTATE Calc_operand1(Calc *me, QEvent const *e); QSTATE Calc_zero1(Calc *me, QEvent const *e); QSTATE Calc_int1(Calc *me, QEvent const *e); QSTATE Calc_frac1(Calc *me, QEvent const *e); QSTATE Calc_opEntered(Calc *me, QEvent const *e); QSTATE Calc_negated2(Calc *me, QEvent const *e); QSTATE Calc_operand2(Calc *me, QEvent const *e); QSTATE Calc_zero2(Calc *me, QEvent const *e); QSTATE Calc_int2(Calc *me, QEvent const *e); QSTATE Calc_frac2(Calc *me, QEvent const *e); void CalcClear_(Calc *me); void CalcInsert_(Calc *me, int keyId); void CalcNegate_(Calc *me); void CalcEval_(Calc *me); void CalcDispState(Calc *me, char const *s); END_CLASS calc.c

大体的思路跟QFSM类似,这里只举一个state的处理函数的例子。

QSTATE Calc_ready(Calc *me, QEvent const *e) { BOOLEAN is_handled = TRUE;

switch (e->sig) {

case Q_ENTRY_SIG:

CalcDispState(me, \ break;

case Q_INIT_SIG:

Q_INIT(Calc_begin); break; case IDC_0:

CalcClear_(me);

Q_TRAN_DYN(Calc_zero1); break; case IDC_1_9:

CalcClear_(me);

CalcInsert_(me, ((CalcEvt *)e)->keyId); Q_TRAN_DYN(Calc_int1); break;

case IDC_POINT: CalcClear_(me);

CalcInsert_(me, IDC_0);

CalcInsert_(me, ((CalcEvt *)e)->keyId); Q_TRAN_DYN(Calc_frac1);

break;

case IDC_OPER:

sscanf(me->display_, \ me->operator_ = ((CalcEvt *)e)->keyId; Q_TRAN_DYN(Calc_opEntered); break; default:

is_handled = FALSE; break; }

if (is_handled) {

return 0; } else {

return (QSTATE)Calc_calc; } }

分析:QHSM 是一套 HSM 的实现框架,它包括qhsm.h和qhsm.c文件等其他辅助文件。他的一些实现方法跟前面的 QFSM frame 类似,也是用函数指针代替状态。不过HSM 比 FSM 多了很多特性,以ready态的处理函数(Calc_ready)为例。描述一下QHSM的框架和 HSM 的执行情况:

2)SUPERCLASS QHsm中会记录Calc HSM instance的状态(函数指针)。当收到一个消息,QF框架会直接调用之。

3)状态的层次关系的体现:某个状态的处理函数中,如果这条消息需要这个状态处理,它的返回值就是0。如果本状态不处理,则返回其父状态的指针。比如 ready态会处理event IDC_0,它处理完毕就返回0,对于其他不处理的event则返回Calc_calc,也就是说其父状态就是Calc态。另外,QF自己定义了一个最顶层的状态叫QTop()。 4)QF自己定义了几个系统消息,包括:

Q_EMPTY_SIG = 0, //空消息,用于检测状态之间的父子关系的,外部不能响应这个消息。 Q_INIT_SIG = 1,//定义initial transition的消息,看代码,比如ready态的的初始状态是begin,当state transition到ready态以后,它就会自动迁移到begin态。 Q_ENTRY_SIG = 2, //Entry消息 Q_EXIT_SIG = 3 //Exit 消息

5)Transition:当调用Q_TRAN_DYN进行状态迁移的时候,QF会计算源状态和目标状态的公共父状态,会给源状态到公共父状态之间所有状态发送一个Q_EXIT_SIG 消息,然后给公共父状态到目标状态之间的所有状态发一个Q_ENTRY_SIG。

结论:前面用UML画的层次状态机用QHSM框架都能实现,而且把图翻译成代码也非常直观、方便。QHSM框架结构好,效率高,可重入。强烈推荐使用。 讲解完毕,别忘了我们的重点是:用状态机原理进行软件“设计”。

第9章 附录

附件是前面提到的CParser和Calc的实现。

SampleCode.rar