添加预装载模块,delay函数小改一下
This commit is contained in:
parent
fff5e8d1d4
commit
5eaac008c5
|
@ -1,6 +1,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "FSM_private.h"
|
#include "FSM_private.h"
|
||||||
#include "FSM_protected.h"
|
#include "FSM_protected.h"
|
||||||
|
@ -14,45 +15,73 @@ void resetBaseFSM(FSM *pFSM)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (pFSM->privateVars.fcns.exitActionTable[pFSM->privateVars.curState] != NULL)
|
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;
|
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)
|
void stepBaseFSM(FSM *pFSM)
|
||||||
{
|
{
|
||||||
|
preload(pFSM);
|
||||||
|
setEvent(pFSM);
|
||||||
|
|
||||||
int index = pFSM->privateVars.curState * pFSM->privateVars.numEvent + pFSM->privateVars.curEvent;
|
int index = pFSM->privateVars.curState * pFSM->privateVars.numEvent + pFSM->privateVars.curEvent;
|
||||||
int curState = pFSM->privateVars.curState;
|
int curState = pFSM->privateVars.curState;
|
||||||
|
FSM **childFSM = pFSM->privateVars.childFSM;
|
||||||
int nextState;
|
int nextState;
|
||||||
void *data = pFSM->data;
|
void *data = pFSM->data;
|
||||||
FSMHandler *fcns = &pFSM->privateVars.fcns;
|
FSMHandler *fcns = &pFSM->privateVars.fcns;
|
||||||
|
|
||||||
if(fcns->delayActionTable[curState] != NULL ){
|
if(fcns->isDelayActionActivated[curState] && fcns->delayActionTable[curState] != NULL ){
|
||||||
fcns->delayActionTable[curState](data);
|
fcns->delayActionTable[curState](data, NULL);
|
||||||
|
fcns->isDelayActionActivated[curState] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fcns->transitionTable[index] != NULL)
|
if (fcns->transitionTable[index] != NULL)
|
||||||
{
|
{
|
||||||
|
fcns->isDelayActionActivated[curState] = 1;
|
||||||
if (fcns->exitActionTable[curState] != NULL)
|
if (fcns->exitActionTable[curState] != NULL)
|
||||||
fcns->exitActionTable[curState](data);
|
fcns->exitActionTable[curState](data, childFSM);
|
||||||
|
|
||||||
nextState = (*fcns->transitionTable[index])(data, curState);
|
nextState = (*fcns->transitionTable[index])(data, curState);
|
||||||
|
|
||||||
if (fcns->enterActionTable[nextState] != NULL)
|
if (fcns->enterActionTable[nextState] != NULL)
|
||||||
fcns->enterActionTable[nextState](data);
|
fcns->enterActionTable[nextState](data, childFSM);
|
||||||
|
|
||||||
pFSM->privateVars.curState = nextState;
|
pFSM->privateVars.curState = nextState;
|
||||||
}
|
}
|
||||||
else if(curState == 0){
|
else if(curState == 0){
|
||||||
nextState = pFSM->privateVars.defaultState;
|
nextState = pFSM->privateVars.defaultState;
|
||||||
if (fcns->enterActionTable[nextState] != NULL)
|
if (fcns->enterActionTable[nextState] != NULL)
|
||||||
fcns->enterActionTable[nextState](data);
|
fcns->enterActionTable[nextState](data, childFSM);
|
||||||
pFSM->privateVars.curState = nextState;
|
pFSM->privateVars.curState = nextState;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (fcns->duringActionTable[curState] != NULL)
|
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.defaultState = defaultState;
|
||||||
pFSM->privateVars.numChild = 0;
|
pFSM->privateVars.numChild = 0;
|
||||||
|
|
||||||
|
pFSM->privateVars.preloader.isReady = 0;
|
||||||
|
|
||||||
pFSM->privateVars.fcns.duringActionTable = calloc(numState, sizeof(StateFuncPtr));
|
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.delayActionTable = calloc(numState, sizeof(StateFuncPtr));
|
||||||
pFSM->privateVars.fcns.enterActionTable = calloc(numState, sizeof(StateFuncPtr));
|
pFSM->privateVars.fcns.enterActionTable = calloc(numState, sizeof(StateFuncPtr));
|
||||||
pFSM->privateVars.fcns.exitActionTable = calloc(numState, sizeof(StateFuncPtr));
|
pFSM->privateVars.fcns.exitActionTable = calloc(numState, sizeof(StateFuncPtr));
|
||||||
|
@ -110,20 +142,7 @@ int getFSMCurEvent(FSM *pFSM){
|
||||||
return pFSM->privateVars.curEvent;
|
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){
|
void setChildNum(FSM *pFSM, int num){
|
||||||
|
@ -135,10 +154,19 @@ void registerChildFSM(FSM *parent, FSM *child, int index){
|
||||||
parent->privateVars.childFSM[index] = child;
|
parent->privateVars.childFSM[index] = child;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *getData(FSM* pFSM){
|
const void *getData(FSM* pFSM){
|
||||||
return pFSM->data;
|
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){
|
FSMVtbl *vptrFSM(FSM* pFSM){
|
||||||
return &pFSM->vtbl;
|
return &pFSM->vtbl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#define index(state, event) (state*Count_Event + event)
|
#define index(state, event) (state*Count_Event + event)
|
||||||
|
|
||||||
typedef struct _FSMHandler FSMHandler;
|
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 int (*Avoid_WARNING_Transition_Handler)(void *data, int curState);
|
||||||
typedef void (*Avoid_WARNING_Overrider_Fcns)(FSM *pFsm);
|
typedef void (*Avoid_WARNING_Overrider_Fcns)(FSM *pFsm);
|
||||||
typedef int (*Avoid_WARNING_SelectEvent)(void *data);
|
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)
|
#define addTransitionHandler(state, event) fcns->transitionTable[index(state, event)] = (Avoid_WARNING_Transition_Handler)transitionHandler(event)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _FSM FSM;
|
typedef struct _FSM FSM;
|
||||||
typedef struct _FSMHandler{
|
typedef struct _FSMHandler{
|
||||||
int (**transitionTable)(void *data, int currentState);
|
int (**transitionTable)(void *data, int currentState);
|
||||||
|
|
||||||
void (**enterActionTable)(void *data);
|
void (**enterActionTable)(void *data, FSM **cFSM);
|
||||||
void (**delayActionTable)(void *data);
|
void (**duringActionTable)(void *data, FSM **cFSM);
|
||||||
void (**duringActionTable)(void *data);
|
void (**exitActionTable)(void *data, FSM **cFSM);
|
||||||
void (**exitActionTable)(void *data);
|
|
||||||
|
int *isDelayActionActivated;
|
||||||
|
void (**delayActionTable)(void *data, FSM **childFSM);
|
||||||
|
|
||||||
void (**childFSMStepTable)(FSM **cFSM);
|
void (**childFSMStepTable)(FSM **cFSM);
|
||||||
}FSMHandler;
|
}FSMHandler;
|
||||||
|
|
||||||
|
typedef struct _FSMDataLoader
|
||||||
|
{
|
||||||
|
void *in;
|
||||||
|
int isReady;
|
||||||
|
size_t preloadSize;
|
||||||
|
}FSMDataLoader;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _FSMPrivateVars
|
typedef struct _FSMPrivateVars
|
||||||
{
|
{
|
||||||
int curState;
|
int curState;
|
||||||
int curEvent;
|
|
||||||
int defaultState; // Idle状态不能停留,必须指定一个初始状态
|
int defaultState; // Idle状态不能停留,必须指定一个初始状态
|
||||||
|
|
||||||
|
int curEvent;
|
||||||
int numEvent;
|
int numEvent;
|
||||||
int numChild;
|
|
||||||
FSM **childFSM;
|
FSMDataLoader preloader;
|
||||||
|
|
||||||
FSMHandler fcns;
|
FSMHandler fcns;
|
||||||
|
|
||||||
|
int numChild;
|
||||||
|
FSM **childFSM;
|
||||||
}FMSPrivateVars;
|
}FMSPrivateVars;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 类似于纯虚类, vptr中的函数必须继承后重新实现
|
// 类似于纯虚类, vptr中的函数必须继承后重新实现
|
||||||
typedef struct _FSM
|
typedef struct _FSM
|
||||||
{
|
{
|
||||||
|
@ -73,9 +88,7 @@ typedef struct _FSM
|
||||||
FMSPrivateVars privateVars;
|
FMSPrivateVars privateVars;
|
||||||
|
|
||||||
// protected
|
// protected
|
||||||
|
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
} FSM;
|
} FSM;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
typedef struct _FSM FSM;
|
typedef struct _FSM FSM;
|
||||||
typedef FSM * FSM_Ptr;
|
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)
|
#define Step(FSM) vptrFSM((FSM_Ptr)FSM)->step((FSM_Ptr)FSM)
|
||||||
|
|
||||||
typedef struct _FSMHandler FSMHandler;
|
typedef struct _FSMHandler FSMHandler;
|
||||||
|
@ -24,11 +24,14 @@ typedef struct _FSMVtbl {
|
||||||
|
|
||||||
int getFSMCurState(FSM *pFSM);
|
int getFSMCurState(FSM *pFSM);
|
||||||
int getFSMCurEvent(FSM *pFSM);
|
int getFSMCurEvent(FSM *pFSM);
|
||||||
void setEvent(FSM* pFSM);
|
// void setEvent(FSM* pFSM);
|
||||||
void setChildNum(FSM *pFSM, int num);
|
void setChildNum(FSM *pFSM, int num);
|
||||||
void registerChildFSM(FSM *parent, FSM *child, int index);
|
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);
|
FSMVtbl *vptrFSM(FSM* pFSM);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,9 @@ static void initData(KeyFSM *pFSM){ // 必须重新实现
|
||||||
data->in = Up;
|
data->in = Up;
|
||||||
data->out = Idle;
|
data->out = Idle;
|
||||||
|
|
||||||
|
pFSM->base.privateVars.preloader.in = malloc(sizeof(KeyIn));
|
||||||
|
pFSM->base.privateVars.preloader.preloadSize = sizeof(KeyIn);
|
||||||
|
|
||||||
pFSM->base.data = data;
|
pFSM->base.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,10 @@ const static char *keyStr[] =
|
||||||
|
|
||||||
typedef struct _keyFSMData
|
typedef struct _keyFSMData
|
||||||
{
|
{
|
||||||
int countDelay;
|
|
||||||
int countMultiDown;
|
|
||||||
KeyIn in;
|
KeyIn in;
|
||||||
KeyOutSignal out;
|
KeyOutSignal out;
|
||||||
|
int countDelay;
|
||||||
|
int countMultiDown;
|
||||||
}KeyFSMData;
|
}KeyFSMData;
|
||||||
|
|
||||||
typedef struct _KeyFSM KeyFSM;
|
typedef struct _KeyFSM KeyFSM;
|
||||||
|
|
|
@ -193,6 +193,7 @@ static State transitionHandler(DelayCount3)(KeyFSMData* data, State curState){
|
||||||
{
|
{
|
||||||
case DownDebouncing:
|
case DownDebouncing:
|
||||||
data->out = Down;
|
data->out = Down;
|
||||||
|
|
||||||
FSM_LOG("按键按下");
|
FSM_LOG("按键按下");
|
||||||
return Downing;
|
return Downing;
|
||||||
|
|
||||||
|
|
8
main.c
8
main.c
|
@ -33,10 +33,12 @@ int main(){
|
||||||
for (int i = 0; i < NUM; i++)
|
for (int i = 0; i < NUM; i++)
|
||||||
{
|
{
|
||||||
printf("第%d次: ",i+1);
|
printf("第%d次: ",i+1);
|
||||||
KeyFSMData* data = getData((FSM_Ptr)keyFSM);
|
const KeyFSMData* data = getData((FSM_Ptr)keyFSM);
|
||||||
data->in = testin[i];
|
|
||||||
|
KeyIn *in = preloadIn((FSM_Ptr)keyFSM);
|
||||||
|
*in = testin[i];
|
||||||
|
preloaderReady((FSM_Ptr)keyFSM);
|
||||||
|
|
||||||
SetEvent(keyFSM);
|
|
||||||
Step(keyFSM);
|
Step(keyFSM);
|
||||||
|
|
||||||
if(data->out){
|
if(data->out){
|
||||||
|
|
Loading…
Reference in New Issue