From 5eaac008c5fe3eefebf9ff64a667bcf115a9ab6b Mon Sep 17 00:00:00 2001 From: godcreator <974980621@qq.com> Date: Tue, 30 Jan 2024 15:11:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A2=84=E8=A3=85=E8=BD=BD?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=EF=BC=8Cdelay=E5=87=BD=E6=95=B0=E5=B0=8F?= =?UTF-8?q?=E6=94=B9=E4=B8=80=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FSM_OOP/baseFSM/FSM.c | 72 +++++++++++++++++++++++---------- FSM_OOP/baseFSM/FSM_protected.h | 33 ++++++++++----- FSM_OOP/baseFSM/FSM_public.h | 9 +++-- FSM_OOP/usr/keyFSM.c | 3 ++ FSM_OOP/usr/keyFSM.h | 4 +- FSM_OOP/usr/keyFSM_private.h | 1 + main.c | 8 ++-- 7 files changed, 90 insertions(+), 40 deletions(-) diff --git a/FSM_OOP/baseFSM/FSM.c b/FSM_OOP/baseFSM/FSM.c index 4489006..d2d4911 100644 --- a/FSM_OOP/baseFSM/FSM.c +++ b/FSM_OOP/baseFSM/FSM.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "FSM_private.h" #include "FSM_protected.h" @@ -14,45 +15,73 @@ void resetBaseFSM(FSM *pFSM) { if (pFSM->privateVars.fcns.exitActionTable[pFSM->privateVars.curState] != NULL) - pFSM->privateVars.fcns.exitActionTable[pFSM->privateVars.curState](pFSM->data); + pFSM->privateVars.fcns.exitActionTable[pFSM->privateVars.curState](pFSM->data, pFSM->privateVars.childFSM); pFSM->privateVars.curState = 0; } + +static inline void setEvent(FSM* pFSM){ + assert(pFSM->vtbl.selectEvent); + pFSM->privateVars.curEvent = pFSM->vtbl.selectEvent(pFSM->data); + + if(0 == pFSM->privateVars.numChild){ + return; + } + + for (int i = 0; i < pFSM->privateVars.numChild; i++) + { + FSM *cFSM = pFSM->privateVars.childFSM[i]; + setEvent(cFSM); + } +} + +static inline void preload(FSM* pFSM){ + if(pFSM->privateVars.preloader.isReady){ + memcpy(pFSM->data, pFSM->privateVars.preloader.in, pFSM->privateVars.preloader.preloadSize); + pFSM->privateVars.preloader.isReady = 0; + } +} void stepBaseFSM(FSM *pFSM) { + preload(pFSM); + setEvent(pFSM); + int index = pFSM->privateVars.curState * pFSM->privateVars.numEvent + pFSM->privateVars.curEvent; int curState = pFSM->privateVars.curState; + FSM **childFSM = pFSM->privateVars.childFSM; int nextState; void *data = pFSM->data; FSMHandler *fcns = &pFSM->privateVars.fcns; - if(fcns->delayActionTable[curState] != NULL ){ - fcns->delayActionTable[curState](data); + if(fcns->isDelayActionActivated[curState] && fcns->delayActionTable[curState] != NULL ){ + fcns->delayActionTable[curState](data, NULL); + fcns->isDelayActionActivated[curState] = 0; } if (fcns->transitionTable[index] != NULL) { + fcns->isDelayActionActivated[curState] = 1; if (fcns->exitActionTable[curState] != NULL) - fcns->exitActionTable[curState](data); + fcns->exitActionTable[curState](data, childFSM); nextState = (*fcns->transitionTable[index])(data, curState); if (fcns->enterActionTable[nextState] != NULL) - fcns->enterActionTable[nextState](data); + fcns->enterActionTable[nextState](data, childFSM); pFSM->privateVars.curState = nextState; } else if(curState == 0){ nextState = pFSM->privateVars.defaultState; if (fcns->enterActionTable[nextState] != NULL) - fcns->enterActionTable[nextState](data); + fcns->enterActionTable[nextState](data, childFSM); pFSM->privateVars.curState = nextState; } else { if (fcns->duringActionTable[curState] != NULL) - fcns->duringActionTable[curState](data); + fcns->duringActionTable[curState](data, childFSM); } } @@ -68,7 +97,10 @@ FSM* newBaseFSM(int numState, int numEvent, int defaultState){ pFSM->privateVars.defaultState = defaultState; pFSM->privateVars.numChild = 0; + pFSM->privateVars.preloader.isReady = 0; + pFSM->privateVars.fcns.duringActionTable = calloc(numState, sizeof(StateFuncPtr)); + pFSM->privateVars.fcns.isDelayActionActivated = calloc(numState, sizeof(int)); pFSM->privateVars.fcns.delayActionTable = calloc(numState, sizeof(StateFuncPtr)); pFSM->privateVars.fcns.enterActionTable = calloc(numState, sizeof(StateFuncPtr)); pFSM->privateVars.fcns.exitActionTable = calloc(numState, sizeof(StateFuncPtr)); @@ -110,20 +142,7 @@ int getFSMCurEvent(FSM *pFSM){ return pFSM->privateVars.curEvent; } -void setEvent(FSM* pFSM){ - assert(pFSM->vtbl.selectEvent); - pFSM->privateVars.curEvent = pFSM->vtbl.selectEvent(pFSM->data); - if(0 == pFSM->privateVars.numChild){ - return; - } - - for (int i = 0; i < pFSM->privateVars.numChild; i++) - { - FSM *cFSM = pFSM->privateVars.childFSM[i]; - setEvent(cFSM); - } -} void setChildNum(FSM *pFSM, int num){ @@ -135,10 +154,19 @@ void registerChildFSM(FSM *parent, FSM *child, int index){ parent->privateVars.childFSM[index] = child; } -void *getData(FSM* pFSM){ - return pFSM->data; +const void *getData(FSM* pFSM){ + return (const void *)pFSM->data; } +void *preloadIn(FSM *pFSM){ + return pFSM->privateVars.preloader.in; +} + +void preloaderReady(FSM *pFSM){ + pFSM->privateVars.preloader.isReady = 1; +} + + FSMVtbl *vptrFSM(FSM* pFSM){ return &pFSM->vtbl; } diff --git a/FSM_OOP/baseFSM/FSM_protected.h b/FSM_OOP/baseFSM/FSM_protected.h index 9a0c155..d10005d 100644 --- a/FSM_OOP/baseFSM/FSM_protected.h +++ b/FSM_OOP/baseFSM/FSM_protected.h @@ -26,7 +26,7 @@ #define index(state, event) (state*Count_Event + event) typedef struct _FSMHandler FSMHandler; -typedef void (*Avoid_WARNING_State_Fcns)(void *data); +typedef void (*Avoid_WARNING_State_Fcns)(void *data, FSM **childFSM); typedef int (*Avoid_WARNING_Transition_Handler)(void *data, int curState); typedef void (*Avoid_WARNING_Overrider_Fcns)(FSM *pFsm); typedef int (*Avoid_WARNING_SelectEvent)(void *data); @@ -37,32 +37,47 @@ typedef void (*Avoid_WARNING_void_fcns)(FSMHandler *fcns); #define addTransitionHandler(state, event) fcns->transitionTable[index(state, event)] = (Avoid_WARNING_Transition_Handler)transitionHandler(event) + typedef struct _FSM FSM; typedef struct _FSMHandler{ int (**transitionTable)(void *data, int currentState); - void (**enterActionTable)(void *data); - void (**delayActionTable)(void *data); - void (**duringActionTable)(void *data); - void (**exitActionTable)(void *data); + void (**enterActionTable)(void *data, FSM **cFSM); + void (**duringActionTable)(void *data, FSM **cFSM); + void (**exitActionTable)(void *data, FSM **cFSM); + + int *isDelayActionActivated; + void (**delayActionTable)(void *data, FSM **childFSM); void (**childFSMStepTable)(FSM **cFSM); }FSMHandler; +typedef struct _FSMDataLoader +{ + void *in; + int isReady; + size_t preloadSize; +}FSMDataLoader; + typedef struct _FSMPrivateVars { int curState; - int curEvent; int defaultState; // Idle状态不能停留,必须指定一个初始状态 + + int curEvent; int numEvent; - int numChild; - FSM **childFSM; + + FSMDataLoader preloader; FSMHandler fcns; + + int numChild; + FSM **childFSM; }FMSPrivateVars; + // 类似于纯虚类, vptr中的函数必须继承后重新实现 typedef struct _FSM { @@ -73,9 +88,7 @@ typedef struct _FSM FMSPrivateVars privateVars; // protected - void *data; - } FSM; diff --git a/FSM_OOP/baseFSM/FSM_public.h b/FSM_OOP/baseFSM/FSM_public.h index 7829675..021e7a8 100644 --- a/FSM_OOP/baseFSM/FSM_public.h +++ b/FSM_OOP/baseFSM/FSM_public.h @@ -7,7 +7,7 @@ typedef struct _FSM FSM; typedef FSM * FSM_Ptr; -#define SetEvent(FSM) setEvent((FSM_Ptr)FSM) +// #define SetEvent(FSM) setEvent((FSM_Ptr)FSM) #define Step(FSM) vptrFSM((FSM_Ptr)FSM)->step((FSM_Ptr)FSM) typedef struct _FSMHandler FSMHandler; @@ -24,11 +24,14 @@ typedef struct _FSMVtbl { int getFSMCurState(FSM *pFSM); int getFSMCurEvent(FSM *pFSM); -void setEvent(FSM* pFSM); +// void setEvent(FSM* pFSM); void setChildNum(FSM *pFSM, int num); void registerChildFSM(FSM *parent, FSM *child, int index); -void *getData(FSM* pFSM); +const void *getData(FSM* pFSM); +void *preloadIn(FSM *pFSM); +void preloaderReady(FSM *pFSM); + FSMVtbl *vptrFSM(FSM* pFSM); diff --git a/FSM_OOP/usr/keyFSM.c b/FSM_OOP/usr/keyFSM.c index 6f15762..d04f724 100644 --- a/FSM_OOP/usr/keyFSM.c +++ b/FSM_OOP/usr/keyFSM.c @@ -41,6 +41,9 @@ static void initData(KeyFSM *pFSM){ // 必须重新实现 data->in = Up; data->out = Idle; + pFSM->base.privateVars.preloader.in = malloc(sizeof(KeyIn)); + pFSM->base.privateVars.preloader.preloadSize = sizeof(KeyIn); + pFSM->base.data = data; } diff --git a/FSM_OOP/usr/keyFSM.h b/FSM_OOP/usr/keyFSM.h index 022df66..e0baf42 100644 --- a/FSM_OOP/usr/keyFSM.h +++ b/FSM_OOP/usr/keyFSM.h @@ -29,10 +29,10 @@ const static char *keyStr[] = typedef struct _keyFSMData { - int countDelay; - int countMultiDown; KeyIn in; KeyOutSignal out; + int countDelay; + int countMultiDown; }KeyFSMData; typedef struct _KeyFSM KeyFSM; diff --git a/FSM_OOP/usr/keyFSM_private.h b/FSM_OOP/usr/keyFSM_private.h index a3d6bf3..3deb8ff 100644 --- a/FSM_OOP/usr/keyFSM_private.h +++ b/FSM_OOP/usr/keyFSM_private.h @@ -193,6 +193,7 @@ static State transitionHandler(DelayCount3)(KeyFSMData* data, State curState){ { case DownDebouncing: data->out = Down; + FSM_LOG("按键按下"); return Downing; diff --git a/main.c b/main.c index 5052178..dd3c598 100644 --- a/main.c +++ b/main.c @@ -33,10 +33,12 @@ int main(){ for (int i = 0; i < NUM; i++) { printf("第%d次: ",i+1); - KeyFSMData* data = getData((FSM_Ptr)keyFSM); - data->in = testin[i]; + const KeyFSMData* data = getData((FSM_Ptr)keyFSM); + + KeyIn *in = preloadIn((FSM_Ptr)keyFSM); + *in = testin[i]; + preloaderReady((FSM_Ptr)keyFSM); - SetEvent(keyFSM); Step(keyFSM); if(data->out){