/** * @file FSM_protected.h * @author 天神 (dalaoshi@stu.xjtu.edu.cn) * @brief 状态机框架的protected函数和变量,在继承的子类中可使用,在外界不可使用 * @version 2.1 * @date 2024-05-07 * * @copyright 天神创意无限公司 2024 * */ #ifndef __FSM_PROTECTED_H_ #define __FSM_PROTECTED_H_ #include "FSM_public.h" // #define DSP28377 #ifdef DSP28377 #define NDEBUG #else #define FSM_LOG_ON #endif #ifdef FSM_LOG_ON #define FSM_LOG(...) printf(__VA_ARGS__) #else #define FSM_LOG(...) ((void)0) #endif #define during during #define enter enter #define exit exit #define selectNextStateFcn(curstate) curstate##_##selectNextState #define transitionHandler(curstate, nextstate) curstate##2##nextstate##Handler #define actionFcn(action, curstate) curstate##_##action##Action #define index(curstate, nextstate) (curstate*Count_State + nextstate) #define addSelectNextStateFcn(curstate) fcns->selectNextState[curstate] = (Avoid_WARNING_SelectNextState)selectNextStateFcn(curstate) #define addStateActionFcn(type, state) fcns->type##ActionTable[state] = (Avoid_WARNING_State_Fcns)actionFcn(type, state) #define addTransitionHandler(curstate, nextstate) fcns->transitionTable[index(curstate, nextstate)] = (Avoid_WARNING_Transition_Handler)transitionHandler(curstate, nextstate) typedef struct FSMHandler FSMHandler; typedef struct FSM FSM; typedef struct FSMSignals FSMSignals; typedef struct FSMPrivateVars FSMPrivateVars; typedef void (*Avoid_WARNING_State_Fcns)(void *data, FSM **childFSM); typedef void (*Avoid_WARNING_General_Handlers)(void *data); typedef void (*Avoid_WARNING_Transition_Handler)(void *data); typedef void (*Avoid_WARNING_Overrider_Fcns)(FSM *pFSM); typedef void (*Avoid_WARNING_ResetSignals_Fcns)(FSMSignals* signals, void *); typedef void (*Avoid_WARNING_loadData_Fcns)(void*); typedef int (*Avoid_WARNING_SelectNextState)(void *data, FSMSignals* signals); typedef void (*Avoid_WARNING_void_fcns)(FSMHandler *fcns); /** * @brief 状态处理函数集合,全部需要子类重新填充内容 * @details 这个结构体暴露给FSM.protect文件,方便在子类中添加函数。不然添加函数得再写个函数添加, * 有点麻烦 * */ typedef struct FSMHandler{ int (**selectNextState)(void *data, FSMSignals* signals); /**< 每个状态配置的状态选择函数 */ void (**transitionTable)(void *data); void (*transitionGeneralAction)(void *data); void (**enterActionTable)(void *data, FSM **cFSM); void (**duringActionTable)(void *data, FSM **cFSM); void (**exitActionTable)(void *data, FSM **cFSM); void (**childFSMStepTable)(FSM **cFSM); }FSMHandler; /** * @brief 状态机用的信号,protected子类可以访问 * */ typedef struct FSMSignals { Uint16 all; /**< 外部信号 */ Uint16 lastTriggeredSignal; /**< 上一次触发的外部信号 */ }FSMSignals; #define Idle_Signal 0 /**< 啥意思? */ /* -------------------------------------------------------------------------- */ /* 纯虚函数,子类必须重新实现,父类构造函数不会初始化 */ /* -------------------------------------------------------------------------- */ /** * @brief 纯虚函数,子类必须重新实现,父类构造函数不会初始化 * */ typedef struct FSMPureVtbl { // 状态机控制 void (*setupHandler)(FSMHandler *fcns); /**< 设置所有的FSMHandler,必须重新实现 */ void (*initData)(FSM *pFSM); /**< 初始化状态机用数据,包括内部数据和外部数据 */ void (*loadExternalData)(void *extData); /**< @deprecated 暂时没用,后续可能考虑外部数据是否允许随时修改 */ void (*initDataLoader)(FSM *pFSM); /**< @deprecated 和预装载器相关 */ void (*initSignals)(FSM *pFSM); /**< 初始化状态机信号 */ void (*resetSignals)(FSMSignals *signals, void *data); /**< 根据条件重置状态机信号 */ }FSMPureVtbl; /* -------------------------------------------------------------------------- */ /* 基类定义,纯虚类 */ /* -------------------------------------------------------------------------- */ typedef struct FSM { // public functions void (*step)(FSM *pFSM); // 子类重新实现可以添加一些打印信息 void (*reset)(FSM *pFSM); // 子类重新实现可以添加一些打印信息 // protected FSMPureVtbl pureVtbl; void *data; FSMSignals signals; // private FSMPrivateVars* privateVars; /**< 细节被隐藏,无法在子类中访问 */ } FSM; /* -------------------------------------------------------------------------- */ /* protected函数,子类能用外界用不了 */ /* -------------------------------------------------------------------------- */ void stepBaseFSM(FSM *pFSM); void constructFSM(FSM* pFSM); FSM* newBaseFSM(int numState, int defaultState); void resetBaseFSM(FSM *pFSM); /* -------------------------------------------------------------------------- */ /* 内联函数 */ /* -------------------------------------------------------------------------- */ static inline void clearSignal(FSMSignals *signals, Uint16 signalFlag){ signals->all &= ~(1 << signalFlag); } static inline Uint16 getSignal(FSMSignals *signals, Uint16 signalFlag){ return (signals->all >> signalFlag) & 1; } static inline void clearAllSignals(FSMSignals *signals){ signals->all = 0; } #endif