📄 statemachine.c
字号:
/*****************************************************************************Filename : StateMachine.C* Programmer : Haven**Date : 2007.9.25**DESCRIPTION: 事件分发函数*****************************************************************************/#define FK_SM_GLOBALS#include "..\includes\includes.H"#define MAX_NEST_DEPTH 5/*****************************************************************************void FsmDispatch(FSM *me) 有限状态机事件分发*****************************************************************************/void FsmDispatch(FSM *me) { STAT_PTR st = me->StatFunPtr; (*st)(me); if (me->EventSig == (EVENT_SIG)0) { me->EventSig = (EVENT_SIG)EXIT_SIG; (*st)(me); //源状态执行退出动作 me->EventSig = (EVENT_SIG)ENTRY_SIG; (*me->StatFunPtr)(me); //目标状态执行进入动作 }}#if HFSM_ENSTAT_PTR HfsmTop(HFSM *me) { (void)me; return (STAT_PTR)0; }/******************************************************************void HfsmInit(HFSM *me) 初始状态转换,每一线程在初始化时都需要调用一次本函数。*******************************************************************/void HfsmInit(HFSM *me) { HFSM_STAT_PTR st; //源状态 HFSM_STAT_PTR tt; //目标状态 HFSM_STAT_PTR path[MAX_NEST_DEPTH]; //状态层次路径 INT8S ip; st = &HfsmTop; //这个状态机必须在HsmCtor()中被初始化 //REQUIRE(me->StatFunPtr != (HFSM_STAT_PTR)0); //(void)(*me->StatFunPtr)(me); // 在初始伪状态启动转换 //不用初始伪状态设计中省略。 do { // 穿入目标层次... tt = me->StatFunPtr; ip = (INT8S)0; path[0] = tt; SIG(me) = (EVENT_SIG)EMPTY_SIG; tt = (HFSM_STAT_PTR)(*tt)(me); // 找出t的超状态 //用于初始转换跨层次的转换,中间层次要找出来,因为每一层都要有进入动作 while (tt != st) { ++ip; path[ip] = tt; SIG(me) = (EVENT_SIG)EMPTY_SIG; tt = (HFSM_STAT_PTR)(*tt)(me); // 找出t的超状态 } //ASSERT(ip < (INT8S)MAX_NEST_DEPTH); // 进入路径不能溢出 //因为ip是由底层向顶层的查找方式,所以进入动作,是ip--是从顶层到底层 //的一层一层执行进入动作。 do { SIG(me) = (EVENT_SIG)ENTRY_SIG; (void)(*path[ip])(me); //执行进入动作 --ip; } while (ip >= (INT8S)0); st = me->StatFunPtr; SIG(me) = (EVENT_SIG)INIT_SIG; } while ((*st)(me) == (STAT_PTR)0); // 初始转换句柄,为0是还有初始转换}/****************************************************************************层次状态机事件分发****************************************************************************/void HfsmDispatch(HFSM *me) { HFSM_STAT_PTR path[MAX_NEST_DEPTH]; HFSM_STAT_PTR st; HFSM_STAT_PTR tt; HFSM_STAT_PTR src; // 转换的源状态 INT8S ip; // 转换进行路径索引 INT8S iq; tt = me->StatFunPtr; path[1] = tt; // 存储当前状态 do { // 处理事件层次... st = tt; //源等于下一条返回状态 tt = (HFSM_STAT_PTR)((*st)(me)); // 调用状态处理程序 } while (tt != (HFSM_STAT_PTR)0); //如果!=0说明这一层不处理这个信号,返回 //上层状态(它的超状态)处理 if (me->EventSig == (EVENT_SIG)0) { // 如果是转换请求 src = st; // 转换的源状态 ip = (INT8S)(-1); // 转换进行路径索引 path[0] = me->StatFunPtr; // 存储新的状态 me->StatFunPtr = path[1]; // 恢复当前状态 // 退出当前状态,到转换源 src... //源状态执行退出动作,直到转换源 for (st = path[1]; st != src; ) { SIG(me) = (EVENT_SIG)EXIT_SIG; tt = (HFSM_STAT_PTR)(*st)(me); // 找到的超状态 if (tt != (HFSM_STAT_PTR)0) { // 退出动作没有处理程序 st = tt; // tt 指向超状态 }else{ // 退出动作处理了 SIG(me) = (EVENT_SIG)EMPTY_SIG; st = (HFSM_STAT_PTR)(*st)(me); // 找到ss的超状态 } } tt = path[0]; // 转换的目标 if (src == tt) { // (1) 检测 source==target (自转换) SIG(me) = (EVENT_SIG)EXIT_SIG; (void)(*src)(me); // 退出源状态 ip = (INT8S)0; // 进入目标 }else{ SIG(me) = (EVENT_SIG)EMPTY_SIG; tt = (HFSM_STAT_PTR)(*tt)(me); // 找目标的超状态 if (src == tt) { // (2) 检测 source==target->super ip = (INT8S)0; // 进入目标 }else { SIG(me) = (EVENT_SIG)EMPTY_SIG; st = (HFSM_STAT_PTR)(*src)(me); // 找 src的超状态 if (st == tt) { // (3) 检测 source->super==target->super SIG(me) = (EVENT_SIG)EXIT_SIG; (void)(*src)(me); // 退出源 ip = (INT8S)0; // 进入目标 }else { if (st == path[0]) { // (4) 检测 source->super==target SIG(me) = (EVENT_SIG)EXIT_SIG; (void)(*src)(me); // 退出源 }else { // (5) 检测 rest of source==target->super->super.. // 延着路存储进入路径*/ iq = (INT8S)0; // 表明 that LCA not found ip = (INT8S)1; // 进入目标和它的超状态 path[1] = tt; // 存储目标的超状态 SIG(me) = (EVENT_SIG)EMPTY_SIG; tt = (HFSM_STAT_PTR)(*tt)(me); // 找 tt的超状态 while (tt != (HFSM_STAT_PTR)0) { path[++ip] = tt; // 存储进入路径 if (tt == src) { // 是源吗? iq = (INT8S)1; // 表明 that LCA found //ASSERT(ip < (INT8S)MAX_NEST_DEPTH);// 进入路径必须不能溢出 --ip; // 不能进入源 tt = (HFSM_STAT_PTR)0; // 终止循环 }else { // tt不是源, keep going up SIG(me) = (EVENT_SIG)EMPTY_SIG; tt = (HFSM_STAT_PTR)(*tt)(me); // t的超状态 } } if (iq == (INT8S)0) { // the LCA not found yet? //ASSERT(ip < (INT8S)MAX_NEST_DEPTH);// 进入路径必须不能溢出 SIG(me) = (EVENT_SIG)EXIT_SIG; (void)(*src)(me); // 退出源 // (6) 检测 the rest of source->super == target->super->super... iq = ip; do { if (st == path[iq]) { // is this the LCA? tt = st; // 表明 that LCA is found ip = (INT8S)(iq - 1); // do not enter LCA iq = (INT8S)(-1); // 终止循环 } else { --iq; // try lower superstate of target } } while (iq >= (INT8S)0); if (tt == (HFSM_STAT_PTR)0) { // LCA not found yet? // (7) 检测 每一个 source->super->... // 对每一个 target->super... do { SIG(me) = (EVENT_SIG)EXIT_SIG; tt = (HFSM_STAT_PTR)(*st)(me); // 退出 st if (tt != (HFSM_STAT_PTR)0) { // 如果没有处理? st = tt; // tt 指向 ss的源 } else { // 退出动作执行了 SIG(me) = (EVENT_SIG)EMPTY_SIG; st = (HFSM_STAT_PTR)(*st)(me); //ss的超状态 } iq = ip; do { if (st == path[iq]) {// is this LCA? // do not enter LCA ip = (INT8S)(iq - 1); iq = (INT8S)(-1);//终止内部 st = (HFSM_STAT_PTR)0; //终止外部 } else { --iq; } } while (iq >= (INT8S)0); } while (st != (HFSM_STAT_PTR)0); } } } } } } // 执行进入动作 for (; ip >= (INT8S)0; --ip) { SIG(me) = (EVENT_SIG)ENTRY_SIG; (void)(*path[ip])(me); // 进入 path[ip] } st = path[0]; // 粘贴目标到寄存器 me->StatFunPtr = st; // 更新当前状态 // 穿过目标层次... SIG(me) = (EVENT_SIG)INIT_SIG; while ((*st)(me) == (STAT_PTR)0) { tt = me->StatFunPtr; path[0] = tt; ip = (INT8S)0; SIG(me) = (EVENT_SIG)EMPTY_SIG; tt = (HFSM_STAT_PTR)(*tt)(me); // 找 tt的超状态 while (tt != st) { ++ip; path[ip] = tt; SIG(me) = (EVENT_SIG)EMPTY_SIG; tt = (HFSM_STAT_PTR)(*tt)(me); // 找 tt的超状态 } //ASSERT(ip < (INT8S)MAX_NEST_DEPTH);// 进入路径必须不能溢出 do { // 执行进入动作 SIG(me) = (EVENT_SIG)ENTRY_SIG; (void)(*path[ip])(me); // 进入 path[ip] --ip; } while (ip >= (INT8S)0); st = me->StatFunPtr; SIG(me) = (EVENT_SIG)INIT_SIG; } }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -