抽象状态机类QFsm或QHsm有一个函数指针,用于在继承的具体状态机类中指向具体的状态函数,其有两个接口函数init()和dispatch(),其工作原理是理解状态机处理事件过程的关键。具体状态机类继承自QFsm或QHsm,同时继承了这个函数指针,用于动态指向具体状态机类中的私有 ...
抽象状态机类QFsm或QHsm有一个函数指针,用于在继承的具体状态机类中指向具体的状态函数,其有两个接口函数init()和dispatch(),其工作原理是理解状态机处理事件过程的关键。
具体状态机类继承自QFsm或QHsm,同时继承了这个函数指针,用于动态指向具体状态机类中的私有状态函数。
具体事件继承于根事件QEvent,并可以自己增加附加的属性。

图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()流程
原标题:QEP之init()和dispatch()流程图
关键词:
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。