2024-05-07 16:45:57 +08:00
|
|
|
|
/**
|
|
|
|
|
* @file FSM.c
|
|
|
|
|
* @author 天神 (dalaoshi@stu.xjtu.edu.cn)
|
|
|
|
|
* @brief
|
|
|
|
|
* @version 2.1
|
|
|
|
|
* @date 2024-05-07
|
|
|
|
|
*
|
|
|
|
|
* @copyright 天神创意无限公司 2024
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2024-01-23 20:05:30 +08:00
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <assert.h>
|
2024-01-30 15:11:15 +08:00
|
|
|
|
#include <string.h>
|
2024-01-23 20:05:30 +08:00
|
|
|
|
|
|
|
|
|
#include "FSM_private.h"
|
|
|
|
|
#include "FSM_protected.h"
|
|
|
|
|
#include "FSM_public.h"
|
|
|
|
|
|
2024-05-07 15:52:18 +08:00
|
|
|
|
|
2024-04-23 19:35:16 +08:00
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
/* private函数 */
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
2024-05-07 15:46:51 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief 设置下一个状态,里面的子状态机暂时没用到
|
|
|
|
|
*
|
|
|
|
|
* @param pFSM 状态机变量的基类指针
|
|
|
|
|
*/
|
2024-06-28 21:40:28 +08:00
|
|
|
|
static inline void updateNextState(FSM* pFSM){
|
|
|
|
|
int curState = getCurState(pFSM);
|
2024-04-23 15:11:06 +08:00
|
|
|
|
|
2024-06-28 21:40:28 +08:00
|
|
|
|
|
|
|
|
|
int nextState = doSelectNextState(pFSM, curState);
|
|
|
|
|
setNextState(pFSM, nextState);
|
|
|
|
|
updateIndex(pFSM);
|
|
|
|
|
}
|
2024-01-30 15:11:15 +08:00
|
|
|
|
|
2024-06-28 21:40:28 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief 递归退出整个状态机包括其子状态机,执行exit函数
|
|
|
|
|
*
|
|
|
|
|
* @param pFSM 状态机变量的基类指针
|
|
|
|
|
*/
|
|
|
|
|
static void exitFSM(FSM *pFSM)
|
|
|
|
|
{
|
|
|
|
|
int curState = getCurState(pFSM);
|
|
|
|
|
if(hasChildFSM(pFSM, curState)){
|
|
|
|
|
exitFSM(getChildFSM(pFSM, curState));
|
|
|
|
|
}
|
|
|
|
|
doExit(pFSM);
|
2024-06-28 22:13:30 +08:00
|
|
|
|
setCurState(pFSM, FSM_Idle);
|
2024-01-30 15:11:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 21:40:28 +08:00
|
|
|
|
|
|
|
|
|
|
2024-05-07 15:46:51 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief
|
|
|
|
|
* @deprecated 去掉了所有和预装载器相关的内容
|
|
|
|
|
* @param pFSM
|
|
|
|
|
*/
|
2024-01-30 15:11:15 +08:00
|
|
|
|
static inline void preload(FSM* pFSM){
|
2024-05-07 15:46:51 +08:00
|
|
|
|
if(pFSM->privateVars->preloader.isReady){
|
|
|
|
|
memcpy(pFSM->data, pFSM->privateVars->preloader.shadowData, pFSM->privateVars->preloader.size);
|
|
|
|
|
pFSM->privateVars->preloader.isReady = 0;
|
2024-01-30 15:11:15 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-23 22:09:53 +08:00
|
|
|
|
|
2024-04-23 19:35:16 +08:00
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
/* protected */
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
2024-05-07 15:46:51 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 运行状态机,状态机框架的核心函数
|
|
|
|
|
* @details 共分为三部首先判断是否有状态机切换,
|
|
|
|
|
* @param pFSM 状态机基类指针
|
|
|
|
|
*/
|
2024-01-23 20:05:30 +08:00
|
|
|
|
void stepBaseFSM(FSM *pFSM)
|
|
|
|
|
{
|
2024-06-28 22:13:30 +08:00
|
|
|
|
pFSM->pureVtbl.loadExternalData(pFSM->data);
|
2024-04-24 13:18:59 +08:00
|
|
|
|
// preload(pFSM);
|
2024-06-28 21:40:28 +08:00
|
|
|
|
updateNextState(pFSM);
|
|
|
|
|
doResetSignals(pFSM);
|
2024-04-23 17:37:25 +08:00
|
|
|
|
|
2024-06-28 21:40:28 +08:00
|
|
|
|
int curState = getCurState(pFSM);
|
|
|
|
|
int index = getIndex(pFSM);
|
|
|
|
|
int nextState = getNextState(pFSM);
|
2024-05-07 15:46:51 +08:00
|
|
|
|
|
2024-04-23 14:32:23 +08:00
|
|
|
|
if(nextState && curState != nextState){ // 状态切换
|
2024-06-28 21:40:28 +08:00
|
|
|
|
// 退出子状态机
|
2024-06-28 19:45:02 +08:00
|
|
|
|
if(hasChildFSM(pFSM, curState)){
|
|
|
|
|
FSM *cFSM = getChildFSM(pFSM, curState);
|
|
|
|
|
exitFSM(cFSM);
|
2024-06-26 20:21:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 21:40:28 +08:00
|
|
|
|
doExit(pFSM);
|
|
|
|
|
|
|
|
|
|
doTransition(pFSM); // 有特定的状态转移函数
|
2024-06-28 19:45:02 +08:00
|
|
|
|
doGeneralTransition(pFSM); // 通用状态转移函数
|
2024-06-26 20:21:14 +08:00
|
|
|
|
|
2024-06-28 19:45:02 +08:00
|
|
|
|
doEnter(pFSM, nextState);
|
2024-06-26 20:21:14 +08:00
|
|
|
|
|
|
|
|
|
// 进子状态机,必须从默认状态开始
|
2024-06-28 19:45:02 +08:00
|
|
|
|
if(hasChildFSM(pFSM, nextState)){
|
|
|
|
|
FSM *cFSM = getChildFSM(pFSM, nextState);
|
2024-06-28 19:13:27 +08:00
|
|
|
|
Step(cFSM);
|
2024-06-26 20:21:14 +08:00
|
|
|
|
}
|
2024-06-28 19:45:02 +08:00
|
|
|
|
setCurState(pFSM, nextState);
|
2024-01-23 20:05:30 +08:00
|
|
|
|
}
|
2024-04-20 20:05:10 +08:00
|
|
|
|
else // 状态机没动
|
2024-01-23 20:05:30 +08:00
|
|
|
|
{
|
2024-06-28 19:45:02 +08:00
|
|
|
|
if(!hasChildFSM(pFSM, curState)){
|
|
|
|
|
doDuring(pFSM);
|
2024-06-26 20:21:14 +08:00
|
|
|
|
}
|
|
|
|
|
else{
|
2024-06-28 19:45:02 +08:00
|
|
|
|
FSM *cFSM = getChildFSM(pFSM, curState);
|
|
|
|
|
Step(cFSM);
|
2024-06-26 20:21:14 +08:00
|
|
|
|
}
|
2024-01-23 20:05:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-23 19:35:16 +08:00
|
|
|
|
|
2024-06-22 20:49:23 +08:00
|
|
|
|
|
|
|
|
|
|
2024-04-23 19:35:16 +08:00
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
/* public 函数 */
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
void _stepFSM(FSM *pFSM){
|
2024-05-07 15:52:18 +08:00
|
|
|
|
pFSM->publicFcns.step(pFSM);
|
2024-04-23 19:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int getFSMCurState(FSM *pFSM){
|
2024-05-07 15:46:51 +08:00
|
|
|
|
return pFSM->privateVars->curState;
|
2024-04-23 19:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
int getFSMNextState(FSM *pFSM){
|
2024-05-07 15:46:51 +08:00
|
|
|
|
return pFSM->privateVars->nextState;
|
2024-04-23 19:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-06-22 20:49:23 +08:00
|
|
|
|
|
2024-06-26 20:21:14 +08:00
|
|
|
|
void registerChildFSM(FSM *parent, FSM *child, int state){
|
|
|
|
|
parent->privateVars->childFSMTable[state] = child;
|
2024-04-23 19:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 19:45:02 +08:00
|
|
|
|
|
|
|
|
|
|
2024-04-23 19:35:16 +08:00
|
|
|
|
const void *_getData(FSM* pFSM){
|
|
|
|
|
return (const void *)pFSM->data;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-23 22:09:53 +08:00
|
|
|
|
void _setSignal(FSM *pFSM, Uint16 signalFlag){
|
2024-05-07 15:46:51 +08:00
|
|
|
|
pFSM->signals.all |= (1 << signalFlag);
|
2024-04-23 19:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-07 15:46:51 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief
|
|
|
|
|
* @deprecated 弃用
|
|
|
|
|
* @param pFSM
|
|
|
|
|
* @return void*
|
|
|
|
|
*/
|
2024-04-23 19:35:16 +08:00
|
|
|
|
void *_preloadIn(FSM *pFSM){
|
2024-05-07 15:46:51 +08:00
|
|
|
|
return pFSM->privateVars->preloader.shadowData;
|
2024-04-23 19:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-07 15:46:51 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief
|
|
|
|
|
* @deprecated 弃用
|
|
|
|
|
* @param pFSM
|
|
|
|
|
*/
|
2024-04-23 19:35:16 +08:00
|
|
|
|
void _preloaderGetReady(FSM *pFSM){
|
2024-05-07 15:46:51 +08:00
|
|
|
|
if(pFSM->privateVars->preloader.isReady){
|
|
|
|
|
pFSM->privateVars->preloader.isOverflow = 1;
|
2024-04-23 19:35:16 +08:00
|
|
|
|
}
|
2024-05-07 15:46:51 +08:00
|
|
|
|
pFSM->privateVars->preloader.isReady = 1;
|
2024-04-23 19:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-07 15:46:51 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief
|
|
|
|
|
* @deprecated 弃用
|
|
|
|
|
* @param pFSM
|
|
|
|
|
* @return int
|
|
|
|
|
*/
|
2024-04-23 19:35:16 +08:00
|
|
|
|
int _getPreloaderOverFlag(FSM *pFSM){
|
2024-05-07 15:46:51 +08:00
|
|
|
|
return pFSM->privateVars->preloader.isOverflow;
|
2024-04-23 19:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-07 15:46:51 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief
|
|
|
|
|
* @deprecated 弃用
|
|
|
|
|
* @param pFSM
|
|
|
|
|
*/
|
2024-04-23 19:35:16 +08:00
|
|
|
|
void _clearPreloaderOverFlag(FSM *pFSM){
|
2024-05-07 15:46:51 +08:00
|
|
|
|
pFSM->privateVars->preloader.isOverflow = 0;
|
2024-04-23 19:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
/* 构造函数,分两段,先新建再赋值 */
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
2024-06-28 17:43:17 +08:00
|
|
|
|
FSM* newBaseFSM(int numState){
|
2024-04-20 21:16:26 +08:00
|
|
|
|
typedef void (*StateFuncPtr)(void *);
|
|
|
|
|
typedef void (*ChildFSMStepFuncPtr)(FSM **);
|
|
|
|
|
typedef int (*TransitionFuncPtr)(void *, int *);
|
2024-04-23 22:09:53 +08:00
|
|
|
|
typedef int (*SelectNextStateFcnPtr)(void *, FSMSignals *);
|
2024-01-23 20:05:30 +08:00
|
|
|
|
|
|
|
|
|
FSM *pFSM = calloc(1, sizeof(FSM));
|
2024-06-28 17:43:17 +08:00
|
|
|
|
pFSM->privateVars = newFMSPrivateVars(numState);
|
2024-05-07 15:52:18 +08:00
|
|
|
|
|
2024-04-23 19:35:16 +08:00
|
|
|
|
FSMPureVtbl pureVtbl = {
|
2024-01-23 20:05:30 +08:00
|
|
|
|
.setupHandler = NULL,
|
|
|
|
|
.initData = NULL,
|
2024-04-24 13:18:59 +08:00
|
|
|
|
.loadExternalData = NULL,
|
2024-01-30 20:35:05 +08:00
|
|
|
|
.initDataLoader = NULL,
|
2024-04-19 15:58:28 +08:00
|
|
|
|
.initSignals = NULL,
|
2024-04-23 21:18:30 +08:00
|
|
|
|
.resetSignals = NULL,
|
2024-01-23 20:05:30 +08:00
|
|
|
|
};
|
2024-04-23 19:35:16 +08:00
|
|
|
|
pFSM->pureVtbl = pureVtbl;
|
|
|
|
|
|
2024-05-07 16:12:07 +08:00
|
|
|
|
pFSM->publicFcns.step = stepBaseFSM;
|
2024-01-23 20:05:30 +08:00
|
|
|
|
|
|
|
|
|
return pFSM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void constructFSM(FSM* pFSM){
|
2024-04-23 19:35:16 +08:00
|
|
|
|
assert(pFSM->pureVtbl.setupHandler);
|
|
|
|
|
assert(pFSM->pureVtbl.initData);
|
|
|
|
|
assert(pFSM->pureVtbl.initDataLoader);
|
2024-01-23 20:05:30 +08:00
|
|
|
|
|
2024-06-22 20:49:23 +08:00
|
|
|
|
|
|
|
|
|
|
2024-05-07 15:46:51 +08:00
|
|
|
|
pFSM->pureVtbl.setupHandler(&pFSM->privateVars->fcns);
|
2024-04-23 19:35:16 +08:00
|
|
|
|
pFSM->pureVtbl.initData(pFSM);
|
|
|
|
|
pFSM->pureVtbl.initDataLoader(pFSM);
|
2024-04-23 14:03:00 +08:00
|
|
|
|
|
|
|
|
|
/* ---------------------------------- 检查状态表 --------------------------------- */
|
2024-05-07 15:46:51 +08:00
|
|
|
|
for (int i = 1; i < pFSM->privateVars->numState; i++) // 跳过Idle状态,Idle状态只能跳转到默认状态
|
2024-04-23 14:03:00 +08:00
|
|
|
|
{
|
2024-05-07 15:46:51 +08:00
|
|
|
|
if(!pFSM->privateVars->fcns.selectNextState[i]){
|
2024-04-23 14:03:00 +08:00
|
|
|
|
FSM_LOG("每个状态都要有一个状态选择函数!\n");
|
|
|
|
|
assert(0); // 强制退出
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-01-23 20:05:30 +08:00
|
|
|
|
}
|
|
|
|
|
|