FSM/vscode/FSM_OOP/baseFSM/FSM.c

217 lines
7.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "FSM_private.h"
#include "FSM_protected.h"
#include "FSM_public.h"
/* -------------------------------------------------------------------------- */
/* private函数 */
/* -------------------------------------------------------------------------- */
static inline void setNextState(FSM* pFSM){
int curState = pFSM->privateVars.curState;
if(curState != 0){
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;
}
if(0 == pFSM->privateVars.numChild)
return;
for (int i = 0; i < pFSM->privateVars.numChild; i++)
{
FSM *cFSM = pFSM->privateVars.childFSM[i];
setNextState(cFSM);
}
}
static inline void preload(FSM* pFSM){
if(pFSM->privateVars.preloader.isReady){
memcpy(pFSM->data, pFSM->privateVars.preloader.shadowData, pFSM->privateVars.preloader.size);
pFSM->privateVars.preloader.isReady = 0;
}
}
/* -------------------------------------------------------------------------- */
/* protected */
/* -------------------------------------------------------------------------- */
void stepBaseFSM(FSM *pFSM)
{
pFSM->pureVtbl.loadExternalData(pFSM->data);
// preload(pFSM);
setNextState(pFSM);
pFSM->pureVtbl.resetSignals(&pFSM->signals, pFSM->data);
FSMHandler *fcns = &pFSM->privateVars.fcns;
int curState = pFSM->privateVars.curState;
void *data = pFSM->data;
FSM **childFSM = pFSM->privateVars.childFSM;
int index = pFSM->privateVars.index;
int nextState = pFSM->privateVars.nextState;
if(nextState && curState != nextState){ // 状态切换
if (fcns->transitionTable[index] != NULL) // 有特定的状态转移函数
{
if (fcns->exitActionTable[curState] != NULL)
fcns->exitActionTable[curState](data, childFSM);
(*fcns->transitionTable[index])(data);
if (fcns->enterActionTable[nextState] != NULL)
fcns->enterActionTable[nextState](data, childFSM);
}
if(fcns->transitionGeneralAction != NULL)
fcns->transitionGeneralAction(data); // 通用状态转移函数
pFSM->privateVars.curState = nextState;
}
else if(curState == 0){ // 处理刚运行进入的默认状态
nextState = pFSM->privateVars.defaultState;
if (fcns->enterActionTable[nextState] != NULL)
fcns->enterActionTable[nextState](data, childFSM);
pFSM->privateVars.curState = nextState;
}
else // 状态机没动
{
if (fcns->duringActionTable[curState] != NULL)
fcns->duringActionTable[curState](data, childFSM);
}
}
/* -------------------------------------------------------------------------- */
/* public 函数 */
/* -------------------------------------------------------------------------- */
void resetBaseFSM(FSM *pFSM)
{
if (pFSM->privateVars.fcns.exitActionTable[pFSM->privateVars.curState] != NULL)
pFSM->privateVars.fcns.exitActionTable[pFSM->privateVars.curState](pFSM->data, pFSM->privateVars.childFSM);
pFSM->privateVars.curState = 0;
}
void _stepFSM(FSM *pFSM){
pFSM->step(pFSM);
}
int getFSMCurState(FSM *pFSM){
return pFSM->privateVars.curState;
}
int getFSMNextState(FSM *pFSM){
return pFSM->privateVars.nextState;
}
void setChildNum(FSM *pFSM, int num){
pFSM->privateVars.numChild = num;
pFSM->privateVars.childFSM = (FSM **)calloc(num, sizeof(FSM *));
}
void registerChildFSM(FSM *parent, FSM *child, int index){
parent->privateVars.childFSM[index] = child;
}
const void *_getData(FSM* pFSM){
return (const void *)pFSM->data;
}
void _setSignal(FSM *pFSM, Uint16 signalFlag){
pFSM->signals.external |= (1 << signalFlag);
}
void *_preloadIn(FSM *pFSM){
return pFSM->privateVars.preloader.shadowData;
}
void _preloaderGetReady(FSM *pFSM){
if(pFSM->privateVars.preloader.isReady){
pFSM->privateVars.preloader.isOverflow = 1;
}
pFSM->privateVars.preloader.isReady = 1;
}
int _getPreloaderOverFlag(FSM *pFSM){
return pFSM->privateVars.preloader.isOverflow;
}
void _clearPreloaderOverFlag(FSM *pFSM){
pFSM->privateVars.preloader.isOverflow = 0;
}
/* -------------------------------------------------------------------------- */
/* 构造函数,分两段,先新建再赋值 */
/* -------------------------------------------------------------------------- */
FSM* newBaseFSM(int numState, int defaultState){
typedef void (*StateFuncPtr)(void *);
typedef void (*ChildFSMStepFuncPtr)(FSM **);
typedef int (*TransitionFuncPtr)(void *, int *);
typedef int (*SelectNextStateFcnPtr)(void *, FSMSignals *);
FSM *pFSM = calloc(1, sizeof(FSM));
pFSM->privateVars.numState = numState;
pFSM->privateVars.defaultState = defaultState;
pFSM->privateVars.curState = 0;
pFSM->privateVars.nextState = 0;
pFSM->privateVars.numChild = 0;
pFSM->privateVars.preloader.isReady = 0;
pFSM->privateVars.fcns.duringActionTable = calloc(numState, sizeof(StateFuncPtr));
pFSM->privateVars.fcns.enterActionTable = calloc(numState, sizeof(StateFuncPtr));
pFSM->privateVars.fcns.exitActionTable = calloc(numState, sizeof(StateFuncPtr));
pFSM->privateVars.fcns.selectNextState = calloc(numState, sizeof(SelectNextStateFcnPtr));
pFSM->privateVars.fcns.transitionTable = calloc(numState * numState, sizeof(TransitionFuncPtr));
pFSM->privateVars.fcns.transitionGeneralAction = calloc(1, sizeof(StateFuncPtr));
pFSM->privateVars.fcns.childFSMStepTable = calloc(numState * numState, sizeof(ChildFSMStepFuncPtr));
FSMPureVtbl pureVtbl = {
.setupHandler = NULL,
.initData = NULL,
.loadExternalData = NULL,
.initDataLoader = NULL,
.initSignals = NULL,
.resetSignals = NULL,
};
pFSM->pureVtbl = pureVtbl;
pFSM->step = stepBaseFSM;
pFSM->reset = resetBaseFSM;
return pFSM;
}
void constructFSM(FSM* pFSM){
assert(pFSM->pureVtbl.setupHandler);
assert(pFSM->pureVtbl.initData);
assert(pFSM->pureVtbl.initDataLoader);
pFSM->pureVtbl.setupHandler(&pFSM->privateVars.fcns);
pFSM->pureVtbl.initData(pFSM);
pFSM->pureVtbl.initDataLoader(pFSM);
/* ---------------------------------- 检查状态表 --------------------------------- */
for (int i = 1; i < pFSM->privateVars.numState; i++) // 跳过Idle状态Idle状态只能跳转到默认状态
{
if(!pFSM->privateVars.fcns.selectNextState[i]){
FSM_LOG("每个状态都要有一个状态选择函数!\n");
assert(0); // 强制退出
}
}
}