From 5240b835782720e58e84cd044ce365d4bd314306 Mon Sep 17 00:00:00 2001 From: TrashGod <974980621@qq.com> Date: Fri, 28 Jun 2024 21:40:28 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=AE=E5=89=8D=E7=9C=8B=E8=B5=B7=E6=9D=A5?= =?UTF-8?q?=E6=B2=A1=E9=97=AE=E9=A2=98=E4=BA=86=EF=BC=8C=E6=98=8E=E5=A4=A9?= =?UTF-8?q?=E5=8E=BB=E6=9D=BF=E5=AD=90=E4=B8=8A=E6=B5=8B=E8=AF=95=E4=B8=80?= =?UTF-8?q?=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vscode/FSM_OOP/baseFSM/FSM.c | 54 ++++++++++++++++---------- vscode/FSM_OOP/baseFSM/FSM_private.h | 49 ++++++++++++++--------- vscode/FSM_OOP/baseFSM/FSM_protected.h | 8 ++-- vscode/FSM_OOP/baseFSM/FSM_public.h | 4 +- vscode/FSM_OOP/childtest/ParentFSM.c | 12 ++++-- vscode/FSM_OOP/childtest/childFSM.h | 2 - vscode/FSM_OOP/childtest/main.c | 3 +- vscode/FSM_OOP/childtest/parentFSM.h | 16 +++++--- vscode/FSM_OOP/template/templateFSM.h | 2 - 父子状态机测试.plecs | 28 ++++++------- 10 files changed, 102 insertions(+), 76 deletions(-) diff --git a/vscode/FSM_OOP/baseFSM/FSM.c b/vscode/FSM_OOP/baseFSM/FSM.c index 83fcfec..23b0096 100644 --- a/vscode/FSM_OOP/baseFSM/FSM.c +++ b/vscode/FSM_OOP/baseFSM/FSM.c @@ -27,15 +27,32 @@ * * @param pFSM 状态机变量的基类指针 */ -static inline void setNextState(FSM* pFSM){ - int curState = pFSM->privateVars->curState; - - pFSM->signals.lastTriggeredSignal = Idle_Signal; - pFSM->privateVars->nextState = pFSM->privateVars->fcns.selectNextState[curState](pFSM->data, &pFSM->signals); - pFSM->privateVars->index = pFSM->privateVars->curState * pFSM->privateVars->numState + pFSM->privateVars->nextState; +static inline void updateNextState(FSM* pFSM){ + int curState = getCurState(pFSM); + + int nextState = doSelectNextState(pFSM, curState); + setNextState(pFSM, nextState); + updateIndex(pFSM); } +/** + * @brief 递归退出整个状态机包括其子状态机,执行exit函数 + * + * @param pFSM 状态机变量的基类指针 + */ +static void exitFSM(FSM *pFSM) +{ + int curState = getCurState(pFSM); + if(hasChildFSM(pFSM, curState)){ + exitFSM(getChildFSM(pFSM, curState)); + } + doExit(pFSM); + setCurState(pFSM, Idle_State); +} + + + /** * @brief * @deprecated 去掉了所有和预装载器相关的内容 @@ -59,32 +76,27 @@ static inline void preload(FSM* pFSM){ */ void stepBaseFSM(FSM *pFSM) { - pFSM->pureVtbl.loadExternalData(pFSM->data); + // pFSM->pureVtbl.loadExternalData(pFSM->data); // preload(pFSM); - setNextState(pFSM); - pFSM->pureVtbl.resetSignals(&pFSM->signals, pFSM->data); + updateNextState(pFSM); + doResetSignals(pFSM); - FSMHandler *fcns = &pFSM->privateVars->fcns; - int curState = pFSM->privateVars->curState; - void *data = pFSM->data; - FSM **childFSMTable = pFSM->privateVars->childFSMTable; - int index = pFSM->privateVars->index; - int nextState = pFSM->privateVars->nextState; + int curState = getCurState(pFSM); + int index = getIndex(pFSM); + int nextState = getNextState(pFSM); if(nextState && curState != nextState){ // 状态切换 - // 退子状态机 + // 退出子状态机 if(hasChildFSM(pFSM, curState)){ FSM *cFSM = getChildFSM(pFSM, curState); exitFSM(cFSM); } - // 退状态机 - doExit(pFSM); - // 转移函数 - doTransition(pFSM, index); // 有特定的状态转移函数 + doExit(pFSM); + + doTransition(pFSM); // 有特定的状态转移函数 doGeneralTransition(pFSM); // 通用状态转移函数 - // 进状态机 doEnter(pFSM, nextState); // 进子状态机,必须从默认状态开始 diff --git a/vscode/FSM_OOP/baseFSM/FSM_private.h b/vscode/FSM_OOP/baseFSM/FSM_private.h index 3ef762f..b92d8d6 100644 --- a/vscode/FSM_OOP/baseFSM/FSM_private.h +++ b/vscode/FSM_OOP/baseFSM/FSM_private.h @@ -99,8 +99,8 @@ FSMPrivateVars* newFMSPrivateVars(int numState){ } - // 包括默认状态 - privateVars->fcns.selectNextState = calloc(numState+1, sizeof(SelectNextStateFcnPtr)); + + privateVars->fcns.selectNextState = calloc(numState+1, sizeof(SelectNextStateFcnPtr)); // 包括默认状态,所以要+1 privateVars->fcns.transitionTable = calloc(numState * numState, sizeof(TransitionFuncPtr)); for (int i = 0; i < numState * numState; i++) { @@ -110,7 +110,6 @@ FSMPrivateVars* newFMSPrivateVars(int numState){ privateVars->fcns.transitionGeneralAction = calloc(1, sizeof(StateFuncPtr)); privateVars->fcns.transitionGeneralAction = empty_func; - privateVars->fcns.childFSMStepTable = calloc(numState * numState, sizeof(ChildFSMStepFuncPtr)); return privateVars; } @@ -131,14 +130,24 @@ static inline int hasChildFSM(FSM *pFSM, int state){ static inline void setCurState(FSM *pFSM, int state){ pFSM->privateVars->curState = state; } - - - - static inline int getCurState(FSM *pFSM){ return pFSM->privateVars->curState; } +static inline int setNextState(FSM *pFSM, int state){ + return pFSM->privateVars->nextState = state; +} +static inline int getNextState(FSM *pFSM){ + return pFSM->privateVars->nextState; +} + +static inline int getIndex(FSM *pFSM){ + return pFSM->privateVars->index; +} +static inline void updateIndex(FSM *pFSM){ + pFSM->privateVars->index = pFSM->privateVars->curState * pFSM->privateVars->numState + pFSM->privateVars->nextState; +} + static inline void doExit(FSM *pFSM){ pFSM->privateVars->fcns.exitActionTable[getCurState(pFSM)](pFSM->data); } @@ -156,21 +165,25 @@ static inline void doGeneralTransition(FSM *pFSM){ pFSM->privateVars->fcns.transitionGeneralAction(pFSM->data); } -static inline void doTransition(FSM *pFSM, int index){ +static inline void doTransition(FSM *pFSM){ + int index = getIndex(pFSM); pFSM->privateVars->fcns.transitionTable[index](pFSM->data); } - -static void exitFSM(FSM *pFSM) -{ - doExit(pFSM); - - int curState = getCurState(pFSM); - if(hasChildFSM(pFSM, curState)){ - exitFSM(getChildFSM(pFSM, curState)); - } - setCurState(pFSM, 0); +static inline int doSelectNextState(FSM *pFSM, int state){ + return pFSM->privateVars->fcns.selectNextState[state](pFSM->data, &pFSM->signals); } + +static inline void doResetSignals(FSM *pFSM){ + pFSM->pureVtbl.resetSignals(&pFSM->signals, pFSM->data); +} + +static inline void clearLastTriggeredSignal(FSM *pFSM){ + pFSM->signals.lastTriggeredSignal = Idle_State; +} + + + #endif diff --git a/vscode/FSM_OOP/baseFSM/FSM_protected.h b/vscode/FSM_OOP/baseFSM/FSM_protected.h index 3350b23..a969cca 100644 --- a/vscode/FSM_OOP/baseFSM/FSM_protected.h +++ b/vscode/FSM_OOP/baseFSM/FSM_protected.h @@ -48,7 +48,7 @@ typedef struct FSM FSM; typedef struct FSMSignals FSMSignals; typedef struct FSMPrivateVars FSMPrivateVars; -typedef void (*Avoid_WARNING_State_Fcns)(void *data, FSM **childFSM); +typedef void (*Avoid_WARNING_State_Fcns)(void *data); typedef void (*Avoid_WARNING_General_Handlers)(void *data); typedef void (*Avoid_WARNING_Transition_Handler)(void *data); typedef void (*Avoid_WARNING_Overrider_Fcns)(FSM *pFSM); @@ -74,7 +74,6 @@ typedef struct FSMHandler{ void (**duringActionTable)(void *data); /**< 状态不变时运行的函数,和plecs对标 */ void (**exitActionTable)(void *data); /**< 状态退出时运行的函数,和plecs对标 */ - void (**childFSMStepTable)(FSM **cFSM); /**< @deprecated 子状态机暂时弃用 */ }FSMHandler; /** @@ -88,7 +87,7 @@ typedef struct FSMSignals Uint16 lastTriggeredSignal; /**< 上一次触发的外部信号,用于信号清除 */ }FSMSignals; #define Idle_Signal 0 /**< 清空上次触发信号,占用第一个信号位 */ - +#define Idle_State 0 /* -------------------------------------------------------------------------- */ /* 纯虚函数,子类必须重新实现,父类构造函数不会初始化 */ /* -------------------------------------------------------------------------- */ @@ -134,8 +133,7 @@ typedef struct FSM void stepBaseFSM(FSM *pFSM); void constructFSM(FSM* pFSM); FSM* newBaseFSM(int numState); -void resetFSM2Idle(FSM *pFSM); - +void registerChildFSM(FSM *parent, FSM *child, int state); /* -------------------------------------------------------------------------- */ /* 内联函数 */ diff --git a/vscode/FSM_OOP/baseFSM/FSM_public.h b/vscode/FSM_OOP/baseFSM/FSM_public.h index 81cea86..707f71c 100644 --- a/vscode/FSM_OOP/baseFSM/FSM_public.h +++ b/vscode/FSM_OOP/baseFSM/FSM_public.h @@ -31,7 +31,6 @@ typedef struct FSMPublicFcns #define GetData(pFSM) _getData((FSM*)pFSM) /**< 外界调用这个 */ #define SetSignal(pFSM, signal) _setSignal((FSM*)pFSM, signal) /**< 外界调用这个 */ - #define PreloaderGetReady(pFSM) _preloaderGetReady((FSM *)pFSM); /**< @deprecated */ #define GetPreloaderOverFlag(pFSM) _getPreloaderOverFlag((FSM *)pFSM) /**< @deprecated */ #define ClearPreloaderOverFlag(pFSM) _clearPreloaderOverFlag((FSM *)pFSM) /**< @deprecated */ @@ -52,7 +51,6 @@ void _preloaderGetReady(FSM *pFSM); int _getPreloaderOverFlag(FSM *pFSM); void _clearPreloaderOverFlag(FSM *pFSM); -/* ---------------------------------- 子状态机 ---------------------------------- */ -void registerChildFSM(FSM *parent, FSM *child, int state); + #endif diff --git a/vscode/FSM_OOP/childtest/ParentFSM.c b/vscode/FSM_OOP/childtest/ParentFSM.c index 2f73856..9e60e3c 100644 --- a/vscode/FSM_OOP/childtest/ParentFSM.c +++ b/vscode/FSM_OOP/childtest/ParentFSM.c @@ -8,7 +8,6 @@ - /* -------------------------------------------------------------------------- */ /* 纯虚函数,允许调用privateVars */ /* -------------------------------------------------------------------------- */ @@ -115,9 +114,14 @@ static void step(ParentFSM* pFSM){ } -// 绑定子状态机 -void bindChildFSM(FSM *pFSM, FSM *cFSM){ - registerChildFSM(pFSM, cFSM, B); +/** + * @brief 绑定子状态机,需要自己实现逻辑 + * + * @param pFSM 父状态机指针 + * @param B_FSM B状态对应的子状态机的指针,后续按照这种命名方式写 + */ +void bind_ParentFSM_ChildFSMs(ParentFSM *pFSM, FSM *B_FSM){ + registerChildFSM((FSM *)pFSM, B_FSM, B); } diff --git a/vscode/FSM_OOP/childtest/childFSM.h b/vscode/FSM_OOP/childtest/childFSM.h index 74b4eb4..b220cd5 100644 --- a/vscode/FSM_OOP/childtest/childFSM.h +++ b/vscode/FSM_OOP/childtest/childFSM.h @@ -42,8 +42,6 @@ typedef struct ChildFSMInnerData /* -------------------------------------------------------------------------- */ /* 下面的改个名字就行了 */ /* -------------------------------------------------------------------------- */ -#define ChildFSM_Input(pFSM) ((ChildFSMExternalData *)_preloadIn((FSM *)pFSM)) /**< @deprecated 暂时弃用 */ - typedef struct ChildFSMData { ChildFSMExternalData external; diff --git a/vscode/FSM_OOP/childtest/main.c b/vscode/FSM_OOP/childtest/main.c index 0d93dae..36f2615 100644 --- a/vscode/FSM_OOP/childtest/main.c +++ b/vscode/FSM_OOP/childtest/main.c @@ -15,7 +15,8 @@ int main(){ cFSM = createChildFSM(); pFSM = createParentFSM(); - registerChildFSM(pFSM, cFSM, 2); + bind_ParentFSM_ChildFSMs(pFSM, (FSM *)cFSM); + ((ParentFSMData *)GetData(cFSM))->external.x = 1; for (int k = 0; k < 15; k++) diff --git a/vscode/FSM_OOP/childtest/parentFSM.h b/vscode/FSM_OOP/childtest/parentFSM.h index 4f41fe4..ece41a0 100644 --- a/vscode/FSM_OOP/childtest/parentFSM.h +++ b/vscode/FSM_OOP/childtest/parentFSM.h @@ -1,10 +1,19 @@ #ifndef __PARENT_FSM_H_ #define __PARENT_FSM_H_ + + /* -------------------------------------------------------------------------- */ /* 提前做类型声明 */ /* -------------------------------------------------------------------------- */ +typedef struct FSM FSM; +typedef struct ParentFSM ParentFSM; +/* -------------------------------------------------------------------------- */ +/* 子状态机绑定,需要自己实现逻辑 */ +/* -------------------------------------------------------------------------- */ +void bind_ParentFSM_ChildFSMs(ParentFSM *pFSM, FSM *B_FSM); + /* -------------------------------------------------------------------------- */ /* 自定义数据和信号 */ /* -------------------------------------------------------------------------- */ @@ -41,12 +50,9 @@ typedef struct ParentFSMInnerData }ParentFSMInnerData; - - /* -------------------------------------------------------------------------- */ -/* 下面的改个名字就行了 */ +/* 这一块改个名字就行了 */ /* -------------------------------------------------------------------------- */ -#define ParentFSM_Input(pFSM) ((ParentFSMExternalData *)_preloadIn((FSM *)pFSM)) /**< @deprecated 暂时弃用 */ typedef struct ParentFSMData { @@ -54,10 +60,8 @@ typedef struct ParentFSMData ParentFSMInnerData internal; }ParentFSMData; -typedef struct ParentFSM ParentFSM; ParentFSM *createParentFSM(); - #endif diff --git a/vscode/FSM_OOP/template/templateFSM.h b/vscode/FSM_OOP/template/templateFSM.h index 74966c1..c244270 100644 --- a/vscode/FSM_OOP/template/templateFSM.h +++ b/vscode/FSM_OOP/template/templateFSM.h @@ -54,8 +54,6 @@ typedef struct TemplateFSMInnerData /* -------------------------------------------------------------------------- */ /* 下面的改个名字就行了 */ /* -------------------------------------------------------------------------- */ -#define TemplateFSM_Input(pFSM) ((TemplateFSMExternalData *)_preloadIn((FSM *)pFSM)) /**< @deprecated 暂时弃用 */ - typedef struct TemplateFSMData { TemplateFSMExternalData external; diff --git a/父子状态机测试.plecs b/父子状态机测试.plecs index 4643e69..d186e2b 100644 --- a/父子状态机测试.plecs +++ b/父子状态机测试.plecs @@ -47,7 +47,7 @@ Plecs { ScriptsDialogGeometry "" ScriptsDialogSplitterPos "0" Schematic { - Location [147, 417; 789, 840] + Location [306, 311; 948, 731] ZoomFactor 1.71498 SliderPosition [0, 0] ShowBrowser off @@ -139,7 +139,7 @@ Plecs { Show off } FSM { - Location [661, 192; 2579, 1112] + Location [190, 122; 1746, 914] ZoomFactor 0.76361 SliderPosition [0, 47] FsmState { @@ -161,8 +161,8 @@ Plecs { } FsmState { Name "B" - Position [1220, 400] - Frame [-530, -240; 530, 240] + Position [1210, 400] + Frame [-520, -240; 520, 240] Parameter { Name "EnterAction" Value "printf(\" enterB \");" @@ -177,7 +177,7 @@ Plecs { } FsmState { Name "D" - Position [-350, 20] + Position [-340, 20] Frame [-100, -90; 100, 90] Parameter { Name "EnterAction" @@ -194,15 +194,15 @@ Plecs { } FsmState { Name ".Junction" - Position [-200, -130] + Position [-190, -130] } FsmState { Name ".PointState" - Position [-200, -170] + Position [-190, -170] } FsmState { Name "E" - Position [230, 20] + Position [240, 20] Frame [-230, -90; 230, 90] Parameter { Name "EnterAction" @@ -571,7 +571,7 @@ Plecs { LabelPosition south Parameter { Variable "DialogGeometry" - Value "[782 587 655 313]" + Value "[947 556 655 313]" Show off } Parameter { @@ -683,17 +683,17 @@ Plecs { Direction up Flipped off LabelPosition south - Location [849, 525; 1199, 784] + Location [974, 426; 1324, 693] State "AAAA/wAAAAD9AAAAAgAAAAEAAAAAAAAAAPwCAAAAA/sAAAAQAFoAbwBvA" "G0AQQByAGUAYQAAAAAA/////wAAADQA////+wAAABQAUwBhAHYAZQBkAFYAaQBlAHcAcwAAAAAA//" "///wAAAGYA////+wAAAAwAVAByAGEAYwBlAHMAAAAAAP////8AAABmAP///wAAAAMAAAAAAAAAAPw" -"BAAAAAfsAAAAUAEQAYQB0AGEAVwBpAGQAZwBlAHQAAAAAAP////8AAABQAP///wAAAV4AAADoAAAA" +"BAAAAAfsAAAAUAEQAYQB0AGEAVwBpAGQAZwBlAHQAAAAAAP////8AAABQAP///wAAAV4AAADwAAAA" "BAAAAAQAAAAIAAAACPwAAAABAAAAAgAAAAEAAAAOAFQAbwBvAGwAQgBhAHIBAAAAAP////8AAAAAA" "AAAAA==" SavedViews "AAAAAgAAAAA=" HeaderState "AAAA/wAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAL/gMAAAAJAAAAA" -"QAAAGQAAAADAAAAZAAAAAIAAABkAAAABQAAAGQAAAAEAAAAZAAAAAcAAABkAAAABgAAAGQAAAAJAA" -"AAZAAAAAgAAABkAAAAiwAAAAsBAAABAAAAAAAAAAAAAAAAZP////8AAACBAAAAAAAAAAsAAABzAAA" +"gAAAGQAAAAJAAAAZAAAAAgAAABkAAAABQAAAGQAAAAEAAAAZAAAAAcAAABkAAAABgAAAGQAAAABAA" +"AAZAAAAAMAAABkAAAAiwAAAAsBAAABAAAAAAAAAAAAAAAAZP////8AAACBAAAAAAAAAAsAAABzAAA" "AAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAA" "AAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAA" "AAYAAAAAQAAAAAAAAPoAAAAABg=" @@ -781,4 +781,4 @@ Plecs { } } } -DemoSignature "GVuBD7S6RWz7S12avKXRuEMLBGx74onrKaOKhUN+KRs=" +DemoSignature "jw8KDReJrMPoo1lAaPtOZeufBUfPGFLDXzJKLXRaW0c="