FSM/vscode/FSM_OOP/template/templateFSM.c

168 lines
5.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.

/**
* @file templateFSM.c
* @author 天神 (dalaoshi@stu.xjtu.edu.cn)
* @brief 重新实现几个必须实现的函数,并赋值到父类指针里
* @version 2.1
* @date 2024-05-07
*
* @copyright 天神创意无限公司 2024
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "FSM_protected.h"
#include "templateFSM.h"
#include "templateFSM_private.h"
const char * curState2ASCII(TemplateFSM *pFSM){
return stateStr[getFSMCurState((FSM *)pFSM)];
}
/* -------------------------------------------------------------------------- */
/* 纯虚函数允许调用privateVars */
/* -------------------------------------------------------------------------- */
/**
* @brief
* @deprecated 暂时没用后续考虑data是否需要加锁再说
* @param data 主要是外部数据
*/
static void loadExternalData(TemplateFSMData *data){ // 必须重新实现
data->external.arrindex = arrindex;
data->external.x = x;
}
/**
* @brief 根据条件重置信号
* @details 清除被响应信号和所有小于被响应信号优先级的信号具体可以参考notion
* @param signals 状态机接收到的信号
* @param data 状态机数据
*/
static void resetSignals(FSMSignals *signals, TemplateFSMData *data){ // 必须重新实现
switch (signals->lastTriggeredSignal)
{
case Signal_A:
clearSignal(signals, Signal_A);
break;
default:
break;
}
}
/**
* @brief 给所有内部、外部数据分配堆空间
*
* @param pFSM
*/
static void initData(TemplateFSM *pFSM){ // 必须重新实现
TemplateFSMData *data = (TemplateFSMData *)malloc(sizeof(TemplateFSMData));
TemplateFSMData tempData = {
.external = {
.arrindex = 0,
.x = 0,
},
.internal = {
.inner1 = 0,
.y1 = 0,
},
};
*data = tempData;
pFSM->base.data = data;
}
/**
* @brief
* @deprecated 弃用
* @param pFSM
*/
static void initDataLoader(TemplateFSM *pFSM){ // 必须重新实现
// pFSM->base.privateVars->preloader.shadowData = malloc(sizeof(TemplateFSMExternalData));
// pFSM->base.privateVars->preloader.size = sizeof(TemplateFSMExternalData);
}
/**
* @brief 设置状态选择函数、状态内函数和状态转移函数
*
* @param fcns 状态机函数表
*/
static void setupHandler(FSMHandler* fcns){ // 必须重新实现
/* ------------------------------- 添加下一个状态选择函数 ------------------------------ */
addSelectNextStateFcn(Idle);
addSelectNextStateFcn(D);
addSelectNextStateFcn(E);
/* ----------------------- 添加状态中事件action during exit ----------------------- */
addStateActionFcn(during, E);
addStateActionFcn(during, D);
addStateActionFcn(enter, E);
addStateActionFcn(enter, D);
addStateActionFcn(exit, E);
addStateActionFcn(exit, D);
/* --------------------------- 添加转移函数和转移函数对应的Delay -------------------------- */
addTransitionHandler(Idle, D);
addTransitionHandler(Idle, E);
addTransitionHandler(D, E);
addTransitionHandler(E, D);
fcns->transitionGeneralAction = (Avoid_WARNING_General_Handlers)transitionGeneralAction;
}
/* -------------------------------------------------------------------------- */
/* 其他重新实现的函数,父类已有实现,实现多态 */
/* -------------------------------------------------------------------------- */
/**
* @brief 重新实现基类的step函数添加一些打印信息
*
* @param pFSM 子类状态机指针
*/
static void step(TemplateFSM* pFSM){
printFSM(pFSM);
stepBaseFSM(BASE_FSM(pFSM));
FSM_LOG("下次状态:%s", stateStr[getFSMNextState((FSM *)pFSM)]);
}
/* -------------------------------------------------------------------------- */
/* 子类构造函数 */
/* -------------------------------------------------------------------------- */
/**
* @brief Create a Template FSM object
* @details 子类状态机细节对外隐藏,外部只能访问基类的公有函数来操作子类变量
* @return TemplateFSM*
*/
TemplateFSM *createTemplateFSM(){
TemplateFSM *pFSM;
pFSM = (TemplateFSM *)newBaseFSM(Count_State);
// 重新实现的函数
pFSM->base.publicFcns.step = (Avoid_WARNING_Overrider_Fcns)step;
pFSM->base.publicFcns.curState2ASCII = (Avoid_WARNING_2ASCII_Fcns)curState2ASCII;
pFSM->base.pureVtbl.initData = (Avoid_WARNING_Overrider_Fcns)initData;
pFSM->base.pureVtbl.initDataLoader = (Avoid_WARNING_Overrider_Fcns)initDataLoader;
pFSM->base.pureVtbl.setupHandler = (Avoid_WARNING_void_fcns)setupHandler;
pFSM->base.pureVtbl.resetSignals = (Avoid_WARNING_ResetSignals_Fcns)resetSignals;
pFSM->base.pureVtbl.loadExternalData = (Avoid_WARNING_loadData_Fcns)loadExternalData;
// 调用父类构造函数
constructFSM((FSM *)pFSM);
FSM_LOG("ok\n");
return pFSM;
}