2024-05-07 15:46:51 +08:00
|
|
|
|
/**
|
|
|
|
|
* @file FSM_private.h
|
|
|
|
|
* @author 天神 (dalaoshi@stu.xjtu.edu.cn)
|
|
|
|
|
* @brief 状态机框架的私有变量,只能在状态机框架内使用。
|
2024-05-07 16:45:57 +08:00
|
|
|
|
* @details 基类私有变量对子类和外界隐藏实现,通过指针进行访问。
|
2024-05-07 15:46:51 +08:00
|
|
|
|
* @version 2.1
|
|
|
|
|
* @date 2024-05-07
|
|
|
|
|
*
|
|
|
|
|
* @copyright 天神创意无限公司 2024
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2024-01-23 20:05:30 +08:00
|
|
|
|
#ifndef __FSM_PRIVATE_H_
|
|
|
|
|
#define __FSM_PRIVATE_H_
|
|
|
|
|
|
2024-05-07 15:46:51 +08:00
|
|
|
|
#include <string.h>
|
|
|
|
|
#include "FSM_protected.h"
|
|
|
|
|
|
|
|
|
|
typedef struct FSMHandler FSMHandler;
|
|
|
|
|
typedef struct FSM FSM;
|
|
|
|
|
typedef struct FSMSignals FSMSignals;
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
/* private数据类型 */
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
/**
|
|
|
|
|
* @brief
|
|
|
|
|
* @deprecated 预装载器弃用
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
typedef struct FSMDataLoader
|
|
|
|
|
{
|
|
|
|
|
void *shadowData;
|
|
|
|
|
int isReady;
|
|
|
|
|
int isOverflow;
|
|
|
|
|
size_t size;
|
|
|
|
|
}FSMDataLoader;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 基类状态机的私有变量和函数,子类不可直接访问
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
typedef struct FSMPrivateVars
|
|
|
|
|
{
|
2024-05-07 16:45:57 +08:00
|
|
|
|
int numState; /**< 状态数量 */
|
2024-05-07 15:46:51 +08:00
|
|
|
|
int defaultState; /**< Idle状态不能停留,必须指定一个初始状态 */
|
|
|
|
|
|
2024-05-07 16:45:57 +08:00
|
|
|
|
int curState; /**< 当前状态 */
|
2024-05-07 15:46:51 +08:00
|
|
|
|
int nextState; /**< nextState为Idle代表状态机不发生变化 */
|
|
|
|
|
int index; /**< 状态转移函数表对应的标号 */
|
|
|
|
|
|
2024-05-07 16:45:57 +08:00
|
|
|
|
FSMHandler fcns; /**< 状态函数表 */
|
2024-05-07 15:46:51 +08:00
|
|
|
|
|
2024-06-26 20:21:14 +08:00
|
|
|
|
// FSM *childFSM; /**< 限定只能有一个子状态机 */
|
|
|
|
|
FSM **childFSMTable; /**< 每个状态都可配置一个子状态机 */
|
2024-05-07 15:46:51 +08:00
|
|
|
|
|
|
|
|
|
FSMDataLoader preloader; /**< @deprecated 弃用 */
|
|
|
|
|
|
|
|
|
|
}FSMPrivateVars;
|
|
|
|
|
|
2024-06-28 19:45:02 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief 纯纯空函数
|
|
|
|
|
*/
|
2024-06-22 20:49:23 +08:00
|
|
|
|
static void empty_func(){
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-07 16:45:57 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 仅在FSM.c中调用,新建私有变量并分配空间
|
|
|
|
|
*
|
|
|
|
|
* @param numState
|
|
|
|
|
* @return FSMPrivateVars*
|
|
|
|
|
*/
|
2024-06-28 17:43:17 +08:00
|
|
|
|
FSMPrivateVars* newFMSPrivateVars(int numState){
|
2024-05-07 15:46:51 +08:00
|
|
|
|
typedef void (*StateFuncPtr)(void *);
|
|
|
|
|
typedef void (*ChildFSMStepFuncPtr)(FSM **);
|
|
|
|
|
typedef int (*TransitionFuncPtr)(void *, int *);
|
|
|
|
|
typedef int (*SelectNextStateFcnPtr)(void *, FSMSignals *);
|
|
|
|
|
|
|
|
|
|
FSMPrivateVars *privateVars = calloc(1, sizeof(FSMPrivateVars));
|
|
|
|
|
privateVars->numState = numState;
|
|
|
|
|
privateVars->curState = 0;
|
|
|
|
|
privateVars->nextState = 0;
|
2024-06-26 20:21:14 +08:00
|
|
|
|
privateVars->childFSMTable = calloc(numState, sizeof(FSM));
|
2024-05-07 15:46:51 +08:00
|
|
|
|
|
|
|
|
|
privateVars->preloader.isReady = 0;
|
|
|
|
|
|
|
|
|
|
privateVars->fcns.duringActionTable = calloc(numState, sizeof(StateFuncPtr));
|
|
|
|
|
privateVars->fcns.enterActionTable = calloc(numState, sizeof(StateFuncPtr));
|
|
|
|
|
privateVars->fcns.exitActionTable = calloc(numState, sizeof(StateFuncPtr));
|
2024-06-22 20:49:23 +08:00
|
|
|
|
|
|
|
|
|
for (int i = 0; i < numState; i++)
|
|
|
|
|
{
|
|
|
|
|
privateVars->fcns.duringActionTable[i] = empty_func;
|
|
|
|
|
privateVars->fcns.enterActionTable[i] = empty_func;
|
|
|
|
|
privateVars->fcns.exitActionTable[i] = empty_func;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-07 15:46:51 +08:00
|
|
|
|
|
2024-06-28 21:40:28 +08:00
|
|
|
|
|
2024-06-28 22:13:30 +08:00
|
|
|
|
privateVars->fcns.selectNextState = calloc(numState, sizeof(SelectNextStateFcnPtr)); // 包括默认状态,所以要+1
|
2024-05-07 15:46:51 +08:00
|
|
|
|
privateVars->fcns.transitionTable = calloc(numState * numState, sizeof(TransitionFuncPtr));
|
2024-06-22 20:49:23 +08:00
|
|
|
|
for (int i = 0; i < numState * numState; i++)
|
|
|
|
|
{
|
|
|
|
|
privateVars->fcns.transitionTable[i] = empty_func;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-07 15:46:51 +08:00
|
|
|
|
privateVars->fcns.transitionGeneralAction = calloc(1, sizeof(StateFuncPtr));
|
2024-06-22 20:49:23 +08:00
|
|
|
|
privateVars->fcns.transitionGeneralAction = empty_func;
|
2024-01-23 20:05:30 +08:00
|
|
|
|
|
2024-05-07 15:46:51 +08:00
|
|
|
|
|
|
|
|
|
return privateVars;
|
|
|
|
|
}
|
2024-01-23 20:05:30 +08:00
|
|
|
|
|
2024-06-22 20:49:23 +08:00
|
|
|
|
|
2024-06-28 19:45:02 +08:00
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
/* 以下开始是FSM私有函数 */
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
static inline FSM * getChildFSM(FSM *pFSM, int state){
|
|
|
|
|
return pFSM->privateVars->childFSMTable[state];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int hasChildFSM(FSM *pFSM, int state){
|
2024-06-26 20:21:14 +08:00
|
|
|
|
return (pFSM->privateVars->childFSMTable[state] != NULL);
|
2024-06-22 20:49:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 19:45:02 +08:00
|
|
|
|
static inline void setCurState(FSM *pFSM, int state){
|
|
|
|
|
pFSM->privateVars->curState = state;
|
|
|
|
|
}
|
|
|
|
|
static inline int getCurState(FSM *pFSM){
|
|
|
|
|
return pFSM->privateVars->curState;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 21:40:28 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 19:45:02 +08:00
|
|
|
|
static inline void doExit(FSM *pFSM){
|
|
|
|
|
pFSM->privateVars->fcns.exitActionTable[getCurState(pFSM)](pFSM->data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void doEnter(FSM *pFSM, int state){
|
|
|
|
|
pFSM->privateVars->fcns.enterActionTable[state](pFSM->data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void doDuring(FSM *pFSM){
|
|
|
|
|
pFSM->privateVars->fcns.duringActionTable[getCurState(pFSM)](pFSM->data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static inline void doGeneralTransition(FSM *pFSM){
|
|
|
|
|
pFSM->privateVars->fcns.transitionGeneralAction(pFSM->data);
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 21:40:28 +08:00
|
|
|
|
static inline void doTransition(FSM *pFSM){
|
|
|
|
|
int index = getIndex(pFSM);
|
2024-06-28 19:45:02 +08:00
|
|
|
|
pFSM->privateVars->fcns.transitionTable[index](pFSM->data);
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 21:40:28 +08:00
|
|
|
|
static inline int doSelectNextState(FSM *pFSM, int state){
|
|
|
|
|
return pFSM->privateVars->fcns.selectNextState[state](pFSM->data, &pFSM->signals);
|
|
|
|
|
}
|
2024-06-28 19:45:02 +08:00
|
|
|
|
|
|
|
|
|
|
2024-06-28 21:40:28 +08:00
|
|
|
|
|
|
|
|
|
static inline void doResetSignals(FSM *pFSM){
|
|
|
|
|
pFSM->pureVtbl.resetSignals(&pFSM->signals, pFSM->data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void clearLastTriggeredSignal(FSM *pFSM){
|
2024-06-28 22:13:30 +08:00
|
|
|
|
pFSM->signals.lastTriggeredSignal = FSM_Idle;
|
2024-06-28 19:45:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-22 20:49:23 +08:00
|
|
|
|
|
2024-06-28 21:40:28 +08:00
|
|
|
|
|
2024-06-22 20:49:23 +08:00
|
|
|
|
#endif
|