155 lines
6.3 KiB
C
155 lines
6.3 KiB
C
/**
|
||
* @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.h文件,这样方便在子类中添加函数。不然添加函数得再写个函数添加,
|
||
* 有点麻烦
|
||
*
|
||
*/
|
||
typedef struct FSMHandler{
|
||
int (**selectNextState)(void *data, FSMSignals* signals); /**< 每个状态配置的状态选择函数 */
|
||
|
||
void (**transitionTable)(void *data); /**< 状态转移函数表 */
|
||
void (*transitionGeneralAction)(void *data); /**< 通用状态转移函数,不论有没有独立的状态转移函数都会执行 */
|
||
|
||
void (**enterActionTable)(void *data, FSM **cFSM); /**< 进入状态时运行的函数,和plecs对标 */
|
||
void (**duringActionTable)(void *data, FSM **cFSM); /**< 状态不变时运行的函数,和plecs对标 */
|
||
void (**exitActionTable)(void *data, FSM **cFSM); /**< 状态退出时运行的函数,和plecs对标 */
|
||
|
||
void (**childFSMStepTable)(FSM **cFSM); /**< @deprecated 子状态机暂时弃用 */
|
||
}FSMHandler;
|
||
|
||
/**
|
||
* @brief 状态机用的信号,protected子类可以访问
|
||
* @details 外部只能通过SetSignal函数对信号进行设置,在状态机运行时会根据信号清除函数清除信号。信号
|
||
* 利用位进行存储,每个位代表一个信号,通过移位操作设置和清除信号。
|
||
*/
|
||
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
|
||
{
|
||
FSMPublicFcns publicFcns;
|
||
// 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
|