bug不少,还需要修复
This commit is contained in:
parent
04c8c07b8f
commit
d6791ef8d4
|
@ -7,7 +7,7 @@ aux_source_directory(${PROJECT_SOURCE_DIR}/FSM_OOP/baseFSM SRC_FSM_OOP)
|
||||||
|
|
||||||
|
|
||||||
# set(keytest 789)
|
# set(keytest 789)
|
||||||
# set(child_parent 789)
|
set(child_parent 789)
|
||||||
if(DEFINED keytest)
|
if(DEFINED keytest)
|
||||||
include_directories(${PROJECT_SOURCE_DIR}/FSM_OOP/keytest)
|
include_directories(${PROJECT_SOURCE_DIR}/FSM_OOP/keytest)
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/FSM_OOP/keytest SRC_FSM_USR)
|
aux_source_directory(${PROJECT_SOURCE_DIR}/FSM_OOP/keytest SRC_FSM_USR)
|
||||||
|
|
|
@ -69,26 +69,60 @@ void stepBaseFSM(FSM *pFSM)
|
||||||
FSMHandler *fcns = &pFSM->privateVars->fcns;
|
FSMHandler *fcns = &pFSM->privateVars->fcns;
|
||||||
int curState = pFSM->privateVars->curState;
|
int curState = pFSM->privateVars->curState;
|
||||||
void *data = pFSM->data;
|
void *data = pFSM->data;
|
||||||
FSM **childFSM = pFSM->privateVars->childFSM;
|
FSM **childFSMTable = pFSM->privateVars->childFSMTable;
|
||||||
int index = pFSM->privateVars->index;
|
int index = pFSM->privateVars->index;
|
||||||
int nextState = pFSM->privateVars->nextState;
|
int nextState = pFSM->privateVars->nextState;
|
||||||
|
|
||||||
if(nextState && curState != nextState){ // 状态切换
|
if(nextState && curState != nextState){ // 状态切换
|
||||||
fcns->exitActionTable[curState](data, childFSM);
|
// 退子状态机
|
||||||
|
if(childFSMTable[curState] != NULL){
|
||||||
|
FSM *cFSM = childFSMTable[curState];
|
||||||
|
int cFSMCurState = cFSM->privateVars->curState;
|
||||||
|
cFSM->privateVars->fcns.exitActionTable[cFSMCurState](cFSM->data);
|
||||||
|
resetBaseFSM(cFSM);
|
||||||
|
}
|
||||||
|
// 退父状态机
|
||||||
|
fcns->exitActionTable[curState](data);
|
||||||
|
|
||||||
|
// 转移函数
|
||||||
fcns->transitionTable[index](data); // 有特定的状态转移函数
|
fcns->transitionTable[index](data); // 有特定的状态转移函数
|
||||||
fcns->transitionGeneralAction(data); // 通用状态转移函数
|
fcns->transitionGeneralAction(data); // 通用状态转移函数
|
||||||
fcns->enterActionTable[nextState](data, childFSM);
|
|
||||||
|
// 进父状态机
|
||||||
|
fcns->enterActionTable[nextState](data);
|
||||||
|
|
||||||
|
// 进子状态机,必须从默认状态开始
|
||||||
|
if(childFSMTable[nextState] != NULL){
|
||||||
|
FSM *cFSM = childFSMTable[nextState];
|
||||||
|
int cFSMNextState = cFSM->privateVars->defaultState;
|
||||||
|
cFSM->privateVars->fcns.enterActionTable[cFSMNextState](cFSM->data);
|
||||||
|
cFSM->privateVars->curState = cFSMNextState;
|
||||||
|
}
|
||||||
|
|
||||||
pFSM->privateVars->curState = nextState;
|
pFSM->privateVars->curState = nextState;
|
||||||
}
|
}
|
||||||
else if(curState == 0){ // 处理刚运行进入的默认状态
|
else if(curState == 0){ // 处理刚运行进入的默认状态
|
||||||
nextState = pFSM->privateVars->defaultState;
|
nextState = pFSM->privateVars->defaultState;
|
||||||
fcns->enterActionTable[nextState](data, childFSM);
|
// 进父状态机
|
||||||
|
fcns->enterActionTable[nextState](data);
|
||||||
|
// 进子状态机
|
||||||
|
if(childFSMTable[nextState] != NULL){
|
||||||
|
FSM *cFSM = childFSMTable[nextState];
|
||||||
|
int cFSMNextState = cFSM->privateVars->defaultState;
|
||||||
|
cFSM->privateVars->fcns.enterActionTable[cFSMNextState](cFSM->data);
|
||||||
|
cFSM->privateVars->curState = cFSMNextState;
|
||||||
|
}
|
||||||
|
|
||||||
pFSM->privateVars->curState = nextState;
|
pFSM->privateVars->curState = nextState;
|
||||||
}
|
}
|
||||||
else // 状态机没动
|
else // 状态机没动
|
||||||
{
|
{
|
||||||
fcns->duringActionTable[curState](data, childFSM);
|
if(childFSMTable[curState] == NULL){
|
||||||
|
fcns->duringActionTable[curState](data);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Step(childFSMTable[curState]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,8 +134,6 @@ void stepBaseFSM(FSM *pFSM)
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
void resetBaseFSM(FSM *pFSM)
|
void resetBaseFSM(FSM *pFSM)
|
||||||
{
|
{
|
||||||
if (pFSM->privateVars->fcns.exitActionTable[pFSM->privateVars->curState] != NULL)
|
|
||||||
pFSM->privateVars->fcns.exitActionTable[pFSM->privateVars->curState](pFSM->data, pFSM->privateVars->childFSM);
|
|
||||||
|
|
||||||
pFSM->privateVars->curState = 0;
|
pFSM->privateVars->curState = 0;
|
||||||
}
|
}
|
||||||
|
@ -120,9 +152,8 @@ int getFSMNextState(FSM *pFSM){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void registerChildFSM(FSM *parent, FSM *child){
|
void registerChildFSM(FSM *parent, FSM *child, int state){
|
||||||
// parent->privateVars->childFSM[index] = child;
|
parent->privateVars->childFSMTable[state] = child;
|
||||||
// parent->privateVars->hasChild++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,8 @@ typedef struct FSMPrivateVars
|
||||||
|
|
||||||
FSMHandler fcns; /**< 状态函数表 */
|
FSMHandler fcns; /**< 状态函数表 */
|
||||||
|
|
||||||
FSM *childFSM; /**< 限定只能有一个子状态机 */
|
// FSM *childFSM; /**< 限定只能有一个子状态机 */
|
||||||
|
FSM **childFSMTable; /**< 每个状态都可配置一个子状态机 */
|
||||||
|
|
||||||
FSMDataLoader preloader; /**< @deprecated 弃用 */
|
FSMDataLoader preloader; /**< @deprecated 弃用 */
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ FSMPrivateVars* newFMSPrivateVars(int numState, int defaultState){
|
||||||
privateVars->defaultState = defaultState;
|
privateVars->defaultState = defaultState;
|
||||||
privateVars->curState = 0;
|
privateVars->curState = 0;
|
||||||
privateVars->nextState = 0;
|
privateVars->nextState = 0;
|
||||||
privateVars->childFSM = NULL;
|
privateVars->childFSMTable = calloc(numState, sizeof(FSM));
|
||||||
|
|
||||||
privateVars->preloader.isReady = 0;
|
privateVars->preloader.isReady = 0;
|
||||||
|
|
||||||
|
@ -114,8 +115,8 @@ FSMPrivateVars* newFMSPrivateVars(int numState, int defaultState){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int hasChildFSM(FSM *pFSM){
|
static int hasChildFSM(FSM *pFSM, int state){
|
||||||
return (pFSM->privateVars->childFSM != NULL);
|
return (pFSM->privateVars->childFSMTable[state] != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,9 +70,9 @@ typedef struct FSMHandler{
|
||||||
void (**transitionTable)(void *data); /**< 状态转移函数表 */
|
void (**transitionTable)(void *data); /**< 状态转移函数表 */
|
||||||
void (*transitionGeneralAction)(void *data); /**< 通用状态转移函数,不论有没有独立的状态转移函数都会执行。常用来清空内部变量 */
|
void (*transitionGeneralAction)(void *data); /**< 通用状态转移函数,不论有没有独立的状态转移函数都会执行。常用来清空内部变量 */
|
||||||
|
|
||||||
void (**enterActionTable)(void *data, FSM **cFSM); /**< 进入状态时运行的函数,和plecs对标 */
|
void (**enterActionTable)(void *data); /**< 进入状态时运行的函数,和plecs对标 */
|
||||||
void (**duringActionTable)(void *data, FSM **cFSM); /**< 状态不变时运行的函数,和plecs对标 */
|
void (**duringActionTable)(void *data); /**< 状态不变时运行的函数,和plecs对标 */
|
||||||
void (**exitActionTable)(void *data, FSM **cFSM); /**< 状态退出时运行的函数,和plecs对标 */
|
void (**exitActionTable)(void *data); /**< 状态退出时运行的函数,和plecs对标 */
|
||||||
|
|
||||||
void (**childFSMStepTable)(FSM **cFSM); /**< @deprecated 子状态机暂时弃用 */
|
void (**childFSMStepTable)(FSM **cFSM); /**< @deprecated 子状态机暂时弃用 */
|
||||||
}FSMHandler;
|
}FSMHandler;
|
||||||
|
|
|
@ -53,6 +53,6 @@ int _getPreloaderOverFlag(FSM *pFSM);
|
||||||
void _clearPreloaderOverFlag(FSM *pFSM);
|
void _clearPreloaderOverFlag(FSM *pFSM);
|
||||||
|
|
||||||
/* ---------------------------------- 子状态机 ---------------------------------- */
|
/* ---------------------------------- 子状态机 ---------------------------------- */
|
||||||
void registerChildFSM(FSM *parent, FSM *child);
|
void registerChildFSM(FSM *parent, FSM *child, int state);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,123 +1,83 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "parentFSM.h"
|
|
||||||
#include "FSM_protected.h"
|
#include "FSM_protected.h"
|
||||||
|
#include "parentFSM.h"
|
||||||
#define DEFAULT_STATE Idle
|
#include "parentFSM_private.h"
|
||||||
|
|
||||||
typedef struct _ParentFSM
|
|
||||||
{
|
|
||||||
FSM base;
|
|
||||||
}ParentFSM;
|
|
||||||
|
|
||||||
typedef enum _State{
|
|
||||||
Idle,
|
|
||||||
A,
|
|
||||||
B,
|
|
||||||
C,
|
|
||||||
|
|
||||||
Count_State,
|
|
||||||
}State;
|
|
||||||
|
|
||||||
typedef enum _Event{
|
|
||||||
Idle_Event,
|
|
||||||
Start,
|
|
||||||
A2B,
|
|
||||||
B2A,
|
|
||||||
B2C,
|
|
||||||
C2A,
|
|
||||||
|
|
||||||
Count_Event,
|
|
||||||
}Event;
|
|
||||||
|
|
||||||
const static char *stateStr[] = {
|
|
||||||
"Idle",
|
|
||||||
"A",
|
|
||||||
"B",
|
|
||||||
"C",
|
|
||||||
};
|
|
||||||
|
|
||||||
const static char *eventStr[] = {
|
|
||||||
"Idle",
|
|
||||||
"Start",
|
|
||||||
"A2B",
|
|
||||||
"B2A",
|
|
||||||
"B2C",
|
|
||||||
"C2A",
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
State StartHandler(){
|
|
||||||
FSM_LOG(" start ");
|
|
||||||
return A;
|
|
||||||
}
|
|
||||||
|
|
||||||
State A2BHandler(){
|
|
||||||
FSM_LOG(" A2B ");
|
|
||||||
return B;
|
|
||||||
}
|
|
||||||
|
|
||||||
State B2AHandler(){
|
/* -------------------------------------------------------------------------- */
|
||||||
FSM_LOG(" B2A ");
|
/* 纯虚函数,允许调用privateVars */
|
||||||
return A;
|
/* -------------------------------------------------------------------------- */
|
||||||
}
|
|
||||||
|
|
||||||
State B2CHandler(){
|
/**
|
||||||
FSM_LOG(" B2C ");
|
* @brief
|
||||||
return C;
|
* @deprecated 暂时没用,后续考虑data是否需要加锁再说
|
||||||
}
|
* @param data 主要是外部数据
|
||||||
|
*/
|
||||||
State C2AHandler(){
|
static void loadExternalData(ParentFSMData *data){ // 必须重新实现
|
||||||
FSM_LOG(" C2A ");
|
|
||||||
return A;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void A_enterAction(){
|
/**
|
||||||
FSM_LOG(" enterA ");
|
* @brief 根据条件重置信号
|
||||||
}
|
* @details 清除被响应信号和所有小于被响应信号优先级的信号,具体可以参考notion
|
||||||
void A_duringAction(){
|
* @param signals 状态机接收到的信号
|
||||||
FSM_LOG(" duringA ");
|
* @param data 状态机数据
|
||||||
}
|
*/
|
||||||
void A_exitAction(){
|
static void resetSignals(FSMSignals *signals, ParentFSMData *data){ // 必须重新实现
|
||||||
FSM_LOG(" exitA ");
|
clearAllSignals(signals);
|
||||||
}
|
}
|
||||||
|
|
||||||
void B_enterAction(void *data, FSM **childFSM){
|
/**
|
||||||
FSM_LOG(" enterB ");
|
* @brief 给所有内部、外部数据分配堆空间
|
||||||
|
*
|
||||||
FSM *cFSM = childFSM[0];
|
* @param pFSM
|
||||||
cFSM->pureVtbl.step(cFSM);
|
*/
|
||||||
}
|
static void initData(ParentFSM *pFSM){ // 必须重新实现
|
||||||
void B_duringAction(void *data, FSM **childFSM){
|
ParentFSMData *data = (ParentFSMData *)malloc(sizeof(ParentFSMData));
|
||||||
FSM_LOG(" duringB ");
|
|
||||||
|
|
||||||
FSM *cFSM = childFSM[0];
|
ParentFSMData tempData = {
|
||||||
cFSM->pureVtbl.step(cFSM);
|
.external = {
|
||||||
}
|
.arrindex = 0,
|
||||||
void B_exitAction(void *data, FSM **childFSM){
|
.x = 0,
|
||||||
FSM *cFSM = childFSM[0];
|
},
|
||||||
cFSM->pureVtbl.reset(cFSM);
|
.internal = {
|
||||||
|
.inner1 = 0,
|
||||||
|
.y1 = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
*data = tempData;
|
||||||
|
|
||||||
FSM_LOG(" exitB ");
|
pFSM->base.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @deprecated 弃用
|
||||||
|
* @param pFSM
|
||||||
|
*/
|
||||||
|
static void initDataLoader(ParentFSM *pFSM){ // 必须重新实现
|
||||||
|
// pFSM->base.privateVars->preloader.shadowData = malloc(sizeof(ParentFSMExternalData));
|
||||||
|
// pFSM->base.privateVars->preloader.size = sizeof(ParentFSMExternalData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void C_enterAction(){
|
/**
|
||||||
FSM_LOG(" enterC ");
|
* @brief 设置状态选择函数、状态内函数和状态转移函数
|
||||||
}
|
*
|
||||||
void C_duringAction(){
|
* @param fcns 状态机函数表
|
||||||
FSM_LOG(" duringC ");
|
*/
|
||||||
}
|
static void setupHandler(FSMHandler* fcns){ // 必须重新实现
|
||||||
void C_exitAction(){
|
/* ------------------------------- 添加下一个状态选择函数 ------------------------------ */
|
||||||
FSM_LOG(" exitC ");
|
addSelectNextStateFcn(A);
|
||||||
}
|
addSelectNextStateFcn(B);
|
||||||
|
addSelectNextStateFcn(C);
|
||||||
|
|
||||||
|
|
||||||
static void setupHandler(FSMHandler* fcns){
|
|
||||||
|
|
||||||
|
/* ----------------------- 添加状态中事件,action during exit ----------------------- */
|
||||||
addStateActionFcn(during, A);
|
addStateActionFcn(during, A);
|
||||||
addStateActionFcn(during, B);
|
addStateActionFcn(during, B);
|
||||||
addStateActionFcn(during, C);
|
addStateActionFcn(during, C);
|
||||||
|
@ -128,85 +88,63 @@ static void setupHandler(FSMHandler* fcns){
|
||||||
addStateActionFcn(exit, B);
|
addStateActionFcn(exit, B);
|
||||||
addStateActionFcn(exit, C);
|
addStateActionFcn(exit, C);
|
||||||
|
|
||||||
addTransitionHandler(Idle, Start);
|
/* --------------------------- 添加转移函数和转移函数对应的Delay -------------------------- */
|
||||||
addTransitionHandler(A, A2B);
|
addTransitionHandler(Idle, A);
|
||||||
addTransitionHandler(B, B2A);
|
addTransitionHandler(A, B);
|
||||||
addTransitionHandler(B, B2C);
|
addTransitionHandler(B, A);
|
||||||
addTransitionHandler(C, C2A);
|
addTransitionHandler(B, C);
|
||||||
}
|
addTransitionHandler(C, A);
|
||||||
|
|
||||||
|
fcns->transitionGeneralAction = (Avoid_WARNING_General_Handlers)transitionGeneralAction;
|
||||||
|
|
||||||
/*
|
|
||||||
用户自定义事件选择逻辑—————————————————begin
|
|
||||||
*/
|
|
||||||
Event peventArr[20] = {
|
|
||||||
Idle_Event,
|
|
||||||
Start,
|
|
||||||
A2B,
|
|
||||||
Idle_Event,
|
|
||||||
Idle_Event,
|
|
||||||
Idle_Event,
|
|
||||||
Idle_Event,
|
|
||||||
Idle_Event,
|
|
||||||
B2C,
|
|
||||||
C2A,
|
|
||||||
A2B,
|
|
||||||
B2A,
|
|
||||||
};
|
|
||||||
|
|
||||||
static Event selectEvent(ParentFSMData *data){
|
|
||||||
return peventArr[data->arrindex];
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
用户自定义事件选择逻辑————————end
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void printFSM(ParentFSM* pFSM){
|
|
||||||
FSM_LOG("\tParentFSM: ");
|
|
||||||
|
|
||||||
FSM_LOG("当前状态:%s, 当前事件:%s, 动作:", stateStr[pFSM->base.privateVars.curState], eventStr[pFSM->base.privateVars.curEvent]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 其他重新实现的函数,父类已有实现,实现多态 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* @brief 重新实现基类的step函数,添加一些打印信息
|
||||||
|
*
|
||||||
|
* @param pFSM 子类状态机指针
|
||||||
|
*/
|
||||||
static void step(ParentFSM* pFSM){
|
static void step(ParentFSM* pFSM){
|
||||||
printFSM(pFSM);
|
printFSM(pFSM);
|
||||||
_stepFSM(BASE_FSM(pFSM));
|
stepBaseFSM(BASE_FSM(pFSM));
|
||||||
}
|
FSM_LOG("下次状态:%s", stateStr[getFSMNextState((FSM *)pFSM)]);
|
||||||
|
|
||||||
static void reset(ParentFSM* pFSM){
|
|
||||||
resetBaseFSM(BASE_FSM(pFSM));
|
|
||||||
FSM_LOG(" ParentFSM-reset");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void initData(ParentFSM *pFSM){
|
|
||||||
ParentFSMData *data = (ParentFSMData *)malloc(sizeof(ParentFSMData));
|
|
||||||
data->arrindex = 0;
|
|
||||||
|
|
||||||
pFSM->base.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void initDataLoader(ParentFSM *pFSM){ // 必须重新实现
|
|
||||||
pFSM->base.privateVars.preloader.in = malloc(sizeof(ParentFSMData));
|
|
||||||
pFSM->base.privateVars.preloader.preloadSize = sizeof(ParentFSMData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 绑定子状态机
|
||||||
|
void bindChildFSM(FSM *pFSM, FSM *cFSM){
|
||||||
|
registerChildFSM(pFSM, cFSM, B);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 子类构造函数 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a Parent FSM object
|
||||||
|
* @details 子类状态机细节对外隐藏,外部只能访问基类的公有函数来操作子类变量
|
||||||
|
* @return ParentFSM*
|
||||||
|
*/
|
||||||
ParentFSM *createParentFSM(){
|
ParentFSM *createParentFSM(){
|
||||||
|
|
||||||
ParentFSM *pFSM;
|
ParentFSM *pFSM;
|
||||||
pFSM = (ParentFSM *)newBaseFSM(Count_State, Count_Event, DEFAULT_STATE);
|
pFSM = (ParentFSM *)newBaseFSM(Count_State, DEFAULT_STATE);
|
||||||
|
|
||||||
|
// 重新实现的函数
|
||||||
|
pFSM->base.publicFcns.step = (Avoid_WARNING_Overrider_Fcns)step;
|
||||||
|
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");
|
||||||
|
|
||||||
pFSM->base.pureVtbl.step = step;
|
|
||||||
pFSM->base.pureVtbl.selectNextState = selectEvent;
|
|
||||||
pFSM->base.pureVtbl.initData = initData;
|
|
||||||
pFSM->base.pureVtbl.setupHandler = setupHandler;
|
|
||||||
pFSM->base.pureVtbl.initDataLoader = initDataLoader;
|
|
||||||
|
|
||||||
constructFSM((FSM *)pFSM);
|
|
||||||
return pFSM;
|
return pFSM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
#ifdef __PARENTFSM_PRIVATE_FSM_H_
|
||||||
|
#error This file can only be included once!!!
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define __PARENTFSM_PRIVATE_FSM_H_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "FSM_protected.h"
|
||||||
|
#include "parentFSM.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 继承基类 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
typedef struct ParentFSM
|
||||||
|
{
|
||||||
|
FSM base;
|
||||||
|
}ParentFSM;
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 状态定义 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 状态机内状态定义,Idle和Count_State必须占据开头和结尾两个位置
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum _State
|
||||||
|
{
|
||||||
|
Idle, /**< 必须在开头,并且枚举值=0 */
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
C,
|
||||||
|
|
||||||
|
Count_State, /**< 必须在结尾,用来统计状态数量 */
|
||||||
|
} State;
|
||||||
|
#define DEFAULT_STATE A /**< 默认状态,Idle状态会先跳转到默认状态 */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 下一个状态选择函数 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
static State selectNextStateFcn(A)(ParentFSM *data, FSMSignals *signals){
|
||||||
|
if(getSignal(signals, Signal_toB)){
|
||||||
|
signals->lastTriggeredSignal = Signal_toB;
|
||||||
|
return B;
|
||||||
|
}
|
||||||
|
return Idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static State selectNextStateFcn(B)(ParentFSM *data, FSMSignals *signals){
|
||||||
|
if(getSignal(signals, Signal_toA)){
|
||||||
|
signals->lastTriggeredSignal = Signal_toA;
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
else if(getSignal(signals, Signal_toC)){
|
||||||
|
signals->lastTriggeredSignal = Signal_toC;
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
return Idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static State selectNextStateFcn(C)(ParentFSM *data, FSMSignals *signals){
|
||||||
|
if(getSignal(signals, Signal_toA)){
|
||||||
|
signals->lastTriggeredSignal = Signal_toA;
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
return Idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 对应的 action, exit, during 函数 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
static void actionFcn(enter, A)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" enterA ");
|
||||||
|
}
|
||||||
|
static void actionFcn(during, A)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" duringA ");
|
||||||
|
}
|
||||||
|
static void actionFcn(exit, A)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" exitA ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void actionFcn(enter, B)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" enterB ");
|
||||||
|
}
|
||||||
|
static void actionFcn(during, B)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" duringB ");
|
||||||
|
}
|
||||||
|
static void actionFcn(exit, B)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" exitB ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void actionFcn(enter, C)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" enterC ");
|
||||||
|
}
|
||||||
|
static void actionFcn(during, C)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" duringC ");
|
||||||
|
}
|
||||||
|
static void actionFcn(exit, C)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" exitC");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 转移函数 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
static void transitionGeneralAction(FSM pFSM){
|
||||||
|
// FSM_LOG("general");
|
||||||
|
}
|
||||||
|
|
||||||
|
// static void transitionGeneralAction(TemplateFSMData *data){
|
||||||
|
// FSM_LOG("general");
|
||||||
|
// }
|
||||||
|
|
||||||
|
static void transitionHandler(Idle, A)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" Idle2A ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void transitionHandler(A, B)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" A2B ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void transitionHandler(B, A)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" B2A ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void transitionHandler(B, C)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" B2C ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void transitionHandler(C, A)()
|
||||||
|
{
|
||||||
|
FSM_LOG(" C2A ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 打印调试 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
const static char *stateStr[] = {
|
||||||
|
"Idle",
|
||||||
|
"A",
|
||||||
|
"B",
|
||||||
|
"C",
|
||||||
|
};
|
||||||
|
|
||||||
|
static void printFSM(ParentFSM* pFSM){
|
||||||
|
FSM_LOG(" \tParent: ");
|
||||||
|
FSM_LOG("当前状态:%s, 动作:", stateStr[getFSMCurState((FSM *)pFSM)]);
|
||||||
|
}
|
|
@ -1,82 +1,142 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "FSM_protected.h"
|
#include "FSM_protected.h"
|
||||||
#include "childFSM.h"
|
#include "childFSM.h"
|
||||||
#include "childFSM_private.h"
|
#include "childFSM_private.h"
|
||||||
|
|
||||||
/*
|
|
||||||
重载函数,有些是纯虚的必须重新实现,有些可以不重新实现直接用父类的
|
|
||||||
*/
|
|
||||||
Event ceventArr[20] = {
|
|
||||||
Idle_Event,
|
|
||||||
Idle_Event,
|
|
||||||
Idle2D,
|
|
||||||
Idle_Event,
|
|
||||||
Idle_Event,
|
|
||||||
D2E,
|
|
||||||
E2D,
|
|
||||||
D2E,
|
|
||||||
Idle_Event,
|
|
||||||
Idle_Event,
|
|
||||||
Idle_Event,
|
|
||||||
Idle_Event,
|
|
||||||
};
|
|
||||||
|
|
||||||
static Event selectEvent(ChildFSMData *data){ // 必须重新实现
|
|
||||||
return ceventArr[data->arrindex];
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 纯虚函数,允许调用privateVars */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @deprecated 暂时没用,后续考虑data是否需要加锁再说
|
||||||
|
* @param data 主要是外部数据
|
||||||
|
*/
|
||||||
|
static void loadExternalData(ChildFSMData *data){ // 必须重新实现
|
||||||
}
|
}
|
||||||
|
|
||||||
static void step(ChildFSM* pFSM){
|
|
||||||
printFSM(pFSM);
|
/**
|
||||||
_stepFSM(BASE_FSM(pFSM));
|
* @brief 根据条件重置信号
|
||||||
|
* @details 清除被响应信号和所有小于被响应信号优先级的信号,具体可以参考notion
|
||||||
|
* @param signals 状态机接收到的信号
|
||||||
|
* @param data 状态机数据
|
||||||
|
*/
|
||||||
|
static void resetSignals(FSMSignals *signals, ChildFSMData *data){ // 必须重新实现
|
||||||
|
clearAllSignals(signals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 给所有内部、外部数据分配堆空间
|
||||||
|
*
|
||||||
|
* @param pFSM
|
||||||
|
*/
|
||||||
static void initData(ChildFSM *pFSM){ // 必须重新实现
|
static void initData(ChildFSM *pFSM){ // 必须重新实现
|
||||||
ChildFSMData *data = (ChildFSMData *)malloc(sizeof(ChildFSMData));
|
ChildFSMData *data = (ChildFSMData *)malloc(sizeof(ChildFSMData));
|
||||||
data->arrindex = 0;
|
|
||||||
|
|
||||||
pFSM->base.privateVars.preloader.in = malloc(sizeof(ChildFSMData));
|
ChildFSMData tempData = {
|
||||||
pFSM->base.privateVars.preloader.preloadSize = sizeof(ChildFSMData);
|
.external = {
|
||||||
|
.arrindex = 0,
|
||||||
|
.x = 0,
|
||||||
|
},
|
||||||
|
.internal = {
|
||||||
|
.inner1 = 0,
|
||||||
|
.y1 = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
*data = tempData;
|
||||||
|
|
||||||
pFSM->base.data = data;
|
pFSM->base.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @deprecated 弃用
|
||||||
|
* @param pFSM
|
||||||
|
*/
|
||||||
static void initDataLoader(ChildFSM *pFSM){ // 必须重新实现
|
static void initDataLoader(ChildFSM *pFSM){ // 必须重新实现
|
||||||
pFSM->base.privateVars.preloader.in = malloc(sizeof(ChildFSMData));
|
// pFSM->base.privateVars->preloader.shadowData = malloc(sizeof(ChildFSMExternalData));
|
||||||
pFSM->base.privateVars.preloader.preloadSize = sizeof(ChildFSMData);
|
// pFSM->base.privateVars->preloader.size = sizeof(ChildFSMExternalData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置状态选择函数、状态内函数和状态转移函数
|
||||||
|
*
|
||||||
|
* @param fcns 状态机函数表
|
||||||
|
*/
|
||||||
static void setupHandler(FSMHandler* fcns){ // 必须重新实现
|
static void setupHandler(FSMHandler* fcns){ // 必须重新实现
|
||||||
addStateActionFcn(during, E);
|
/* ------------------------------- 添加下一个状态选择函数 ------------------------------ */
|
||||||
|
addSelectNextStateFcn(D);
|
||||||
|
addSelectNextStateFcn(E);
|
||||||
|
|
||||||
|
/* ----------------------- 添加状态中事件,action during exit ----------------------- */
|
||||||
addStateActionFcn(during, D);
|
addStateActionFcn(during, D);
|
||||||
|
addStateActionFcn(during, E);
|
||||||
addStateActionFcn(enter, D);
|
addStateActionFcn(enter, D);
|
||||||
addStateActionFcn(exit, D);
|
|
||||||
addStateActionFcn(enter, E);
|
addStateActionFcn(enter, E);
|
||||||
|
addStateActionFcn(exit, D);
|
||||||
addStateActionFcn(exit, E);
|
addStateActionFcn(exit, E);
|
||||||
|
|
||||||
addTransitionHandler(Idle, Idle2D);
|
/* --------------------------- 添加转移函数和转移函数对应的Delay -------------------------- */
|
||||||
addTransitionHandler(Idle, Idle2E);
|
addTransitionHandler(Idle, D);
|
||||||
addTransitionHandler(D, D2E);
|
addTransitionHandler(Idle, E);
|
||||||
addTransitionHandler(E, E2D);
|
addTransitionHandler(D, E);
|
||||||
|
addTransitionHandler(E, D);
|
||||||
|
|
||||||
|
fcns->transitionGeneralAction = (Avoid_WARNING_General_Handlers)transitionGeneralAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
唯一外界调用的函数
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 其他重新实现的函数,父类已有实现,实现多态 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* @brief 重新实现基类的step函数,添加一些打印信息
|
||||||
|
*
|
||||||
|
* @param pFSM 子类状态机指针
|
||||||
*/
|
*/
|
||||||
|
static void step(ChildFSM* pFSM){
|
||||||
|
printFSM(pFSM);
|
||||||
|
stepBaseFSM(BASE_FSM(pFSM));
|
||||||
|
FSM_LOG("下次状态:%s", stateStr[getFSMNextState((FSM *)pFSM)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 子类构造函数 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a Child FSM object
|
||||||
|
* @details 子类状态机细节对外隐藏,外部只能访问基类的公有函数来操作子类变量
|
||||||
|
* @return ChildFSM*
|
||||||
|
*/
|
||||||
ChildFSM *createChildFSM(){
|
ChildFSM *createChildFSM(){
|
||||||
|
|
||||||
ChildFSM *pFSM;
|
ChildFSM *pFSM;
|
||||||
pFSM = (ChildFSM *)newBaseFSM(Count_State, Count_Event, DEFAULT_STATE);
|
pFSM = (ChildFSM *)newBaseFSM(Count_State, DEFAULT_STATE);
|
||||||
|
|
||||||
pFSM->base.pureVtbl.step = step;
|
// 重新实现的函数
|
||||||
pFSM->base.pureVtbl.selectNextState = selectEvent;
|
pFSM->base.publicFcns.step = (Avoid_WARNING_Overrider_Fcns)step;
|
||||||
pFSM->base.pureVtbl.initData = initData;
|
pFSM->base.pureVtbl.initData = (Avoid_WARNING_Overrider_Fcns)initData;
|
||||||
pFSM->base.pureVtbl.setupHandler = setupHandler;
|
pFSM->base.pureVtbl.initDataLoader = (Avoid_WARNING_Overrider_Fcns)initDataLoader;
|
||||||
pFSM->base.pureVtbl.initDataLoader = 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);
|
// 调用父类构造函数
|
||||||
|
constructFSM((FSM *)pFSM);
|
||||||
|
|
||||||
|
FSM_LOG("ok\n");
|
||||||
|
|
||||||
return pFSM;
|
return pFSM;
|
||||||
}
|
}
|
|
@ -1,17 +1,59 @@
|
||||||
#ifndef __CHILD_FSM_H_
|
#ifndef __CHILD_FSM_H_
|
||||||
#define __CHILD_FSM_H_
|
#define __CHILD_FSM_H_
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 提前做类型声明 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define ChildFSM_Input(pFSM) ((ChildFSMData *)_preloadIn((FSM *)pFSM))
|
|
||||||
|
|
||||||
typedef struct _childFSMData
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 自定义数据和信号 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* @brief 自定义外部信号,目前最多15个
|
||||||
|
* @details 因为是Unint16存储的信号位
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
enum ChildFSMSignals{
|
||||||
|
Signal_toD = 1, /**< 必须从1开始,0预留给Idle信号了*/
|
||||||
|
Signal_toE,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 自定义外部数据
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct ChildFSMExternalData
|
||||||
{
|
{
|
||||||
int arrindex;
|
int arrindex;
|
||||||
|
int x;
|
||||||
|
}ChildFSMExternalData;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 自定义内部数据
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct ChildFSMInnerData
|
||||||
|
{
|
||||||
|
int y1;
|
||||||
|
int inner1;
|
||||||
|
}ChildFSMInnerData;
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 下面的改个名字就行了 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
#define ChildFSM_Input(pFSM) ((ChildFSMExternalData *)_preloadIn((FSM *)pFSM)) /**< @deprecated 暂时弃用 */
|
||||||
|
|
||||||
|
typedef struct ChildFSMData
|
||||||
|
{
|
||||||
|
ChildFSMExternalData external;
|
||||||
|
ChildFSMInnerData internal;
|
||||||
}ChildFSMData;
|
}ChildFSMData;
|
||||||
|
|
||||||
typedef struct _ChildFSM ChildFSM;
|
typedef struct ChildFSM ChildFSM;
|
||||||
|
|
||||||
ChildFSM *createChildFSM();
|
ChildFSM *createChildFSM();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,121 +1,133 @@
|
||||||
#ifndef __CHILD_PRIVATE_FSM_H_
|
#ifdef __CHILDFSM_PRIVATE_FSM_H_
|
||||||
#define __CHILD_PRIVATE_FSM_H_
|
#error This file can only be included once!!!
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define __CHILDFSM_PRIVATE_FSM_H_
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "FSM_protected.h"
|
#include "FSM_protected.h"
|
||||||
#include "childFSM.h"
|
#include "childFSM.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* -------------------------------------------------------------------------- */
|
||||||
继承基类
|
/* 继承基类 */
|
||||||
*/
|
/* -------------------------------------------------------------------------- */
|
||||||
typedef struct _ChildFSM
|
typedef struct ChildFSM
|
||||||
{
|
{
|
||||||
// 继承父类
|
|
||||||
FSM base;
|
FSM base;
|
||||||
}ChildFSM;
|
}ChildFSM;
|
||||||
|
|
||||||
/*
|
/* -------------------------------------------------------------------------- */
|
||||||
状态和对应的 action, exit, during 函数
|
/* 状态定义 */
|
||||||
*/
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 状态机内状态定义,Idle和Count_State必须占据开头和结尾两个位置
|
||||||
|
*
|
||||||
|
*/
|
||||||
typedef enum _State
|
typedef enum _State
|
||||||
{
|
{
|
||||||
Idle,
|
Idle, /**< 必须在开头,并且枚举值=0 */
|
||||||
D,
|
D,
|
||||||
E,
|
E,
|
||||||
|
|
||||||
Count_State,
|
Count_State, /**< 必须在结尾,用来统计状态数量 */
|
||||||
} State;
|
} State;
|
||||||
#define DEFAULT_STATE E
|
#define DEFAULT_STATE D /**< 默认状态,Idle状态会先跳转到默认状态 */
|
||||||
|
|
||||||
void actionFcn(enter, D)()
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 下一个状态选择函数 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
static State selectNextStateFcn(D)(ChildFSM *data, FSMSignals *signals){
|
||||||
|
if(getSignal(signals, Signal_toE)){
|
||||||
|
signals->lastTriggeredSignal = Signal_toE;
|
||||||
|
return E;
|
||||||
|
}
|
||||||
|
return Idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static State selectNextStateFcn(E)(ChildFSM *data, FSMSignals *signals){
|
||||||
|
if(getSignal(signals, Signal_toD)){
|
||||||
|
signals->lastTriggeredSignal = Signal_toD;
|
||||||
|
return D;
|
||||||
|
}
|
||||||
|
return Idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 对应的 action, exit, during 函数 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
static void actionFcn(enter, D)()
|
||||||
{
|
{
|
||||||
FSM_LOG(" enterD ");
|
FSM_LOG(" enterD ");
|
||||||
}
|
}
|
||||||
void actionFcn(during, D)()
|
static void actionFcn(during, D)()
|
||||||
{
|
{
|
||||||
FSM_LOG(" duringD ");
|
FSM_LOG(" duringD ");
|
||||||
}
|
}
|
||||||
void actionFcn(exit, D)()
|
static void actionFcn(exit, D)()
|
||||||
{
|
{
|
||||||
FSM_LOG(" exitD ");
|
FSM_LOG(" exitD ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void actionFcn(enter, E)()
|
static void actionFcn(enter, E)()
|
||||||
{
|
{
|
||||||
FSM_LOG(" enterE ");
|
FSM_LOG(" enterE ");
|
||||||
}
|
}
|
||||||
void actionFcn(during, E)()
|
static void actionFcn(during, E)()
|
||||||
{
|
{
|
||||||
FSM_LOG(" duringE ");
|
FSM_LOG(" duringE ");
|
||||||
}
|
}
|
||||||
void actionFcn(exit, E)()
|
static void actionFcn(exit, E)()
|
||||||
{
|
{
|
||||||
FSM_LOG(" exitE ");
|
FSM_LOG(" exitE ");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
事件和对应的转移函数
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef enum _Event{
|
/* -------------------------------------------------------------------------- */
|
||||||
Idle_Event,
|
/* 转移函数 */
|
||||||
Idle2D,
|
/* -------------------------------------------------------------------------- */
|
||||||
Idle2E,
|
static void transitionGeneralAction(FSM pFSM){
|
||||||
D2E,
|
// FSM_LOG("general");
|
||||||
E2D,
|
}
|
||||||
|
|
||||||
Count_Event,
|
// static void transitionGeneralAction(TemplateFSMData *data){
|
||||||
}Event;
|
// FSM_LOG("general");
|
||||||
|
// }
|
||||||
|
|
||||||
|
static void transitionHandler(Idle, D)()
|
||||||
State transitionHandler(Idle2D)()
|
|
||||||
{
|
{
|
||||||
FSM_LOG(" Idle2D ");
|
FSM_LOG(" Idle2D ");
|
||||||
return D;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
State transitionHandler(Idle2E)()
|
static void transitionHandler(Idle, E)()
|
||||||
{
|
{
|
||||||
FSM_LOG(" Idle2E ");
|
FSM_LOG(" Idle2E ");
|
||||||
return E;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
State transitionHandler(D2E)()
|
static void transitionHandler(D, E)()
|
||||||
{
|
{
|
||||||
FSM_LOG(" D2E ");
|
FSM_LOG(" D2E ");
|
||||||
return E;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
State transitionHandler(E2D)()
|
static void transitionHandler(E, D)()
|
||||||
{
|
{
|
||||||
FSM_LOG(" E2D ");
|
FSM_LOG(" E2D ");
|
||||||
return D;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 打印调试 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
/*
|
|
||||||
用户自定义事件选择逻辑—————————————————begin
|
|
||||||
*/
|
|
||||||
const static char *stateStr[] = {
|
const static char *stateStr[] = {
|
||||||
"Idle",
|
"Idle",
|
||||||
"D",
|
"D",
|
||||||
"E",
|
"E",
|
||||||
};
|
|
||||||
const static char *eventStr[] = {
|
|
||||||
"Idle",
|
|
||||||
"Idle2D",
|
|
||||||
"Idle2E",
|
|
||||||
"D2E",
|
|
||||||
"E2D",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void printFSM(ChildFSM* pFSM){
|
static void printFSM(ChildFSM* pFSM){
|
||||||
FSM_LOG(" \t\tChildFSM: ");
|
FSM_LOG(" \tChild: ");
|
||||||
FSM_LOG("当前状态:%s, 当前事件:%s, 动作:", stateStr[getFSMCurState((FSM *)pFSM)], eventStr[getFSMCurEvent((FSM *)pFSM)]);
|
FSM_LOG("当前状态:%s, 动作:", stateStr[getFSMCurState((FSM *)pFSM)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -7,27 +7,25 @@
|
||||||
ChildFSM *cFSM;
|
ChildFSM *cFSM;
|
||||||
ParentFSM *pFSM;
|
ParentFSM *pFSM;
|
||||||
|
|
||||||
|
enum ParentFSMSignals i[20] = {0, Signal_toA, Signal_toB,0,0,0,0,0, Signal_toC, Signal_toA, Signal_toB, Signal_toA};
|
||||||
|
enum ChildFSMSignals j[20] = {0,0,Signal_toD,0,0,Signal_toE, Signal_toD, Signal_toE,0,0,0,0};
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
|
|
||||||
cFSM = createChildFSM();
|
cFSM = createChildFSM();
|
||||||
pFSM = createParentFSM();
|
pFSM = createParentFSM();
|
||||||
|
|
||||||
setChildNum((pFSM), 1);
|
registerChildFSM(pFSM, cFSM, 2);
|
||||||
registerChildFSM((pFSM), (cFSM), 0);
|
|
||||||
|
|
||||||
for (int i = 0; i < 15; i++)
|
for (int k = 0; k < 15; k++)
|
||||||
{
|
{
|
||||||
ParentFSM_Input(pFSM)->arrindex = i;
|
printf("第%d次: ",k+1);
|
||||||
PreloaderGetReady(pFSM);
|
SetSignal(pFSM, i[k]);
|
||||||
|
SetSignal(cFSM, j[k]);
|
||||||
|
|
||||||
ChildFSM_Input(cFSM)->arrindex = i;
|
Step(pFSM);
|
||||||
PreloaderGetReady(cFSM);
|
|
||||||
|
|
||||||
ChildFSMData* data = _getData((FSM *)(cFSM));
|
|
||||||
printf(" %d ", data->arrindex);
|
|
||||||
|
|
||||||
|
|
||||||
_vptrFSM((FSM *)pFSM)->step((FSM *)pFSM);
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,63 @@
|
||||||
#ifndef __PARENT_FSM_H_
|
#ifndef __PARENT_FSM_H_
|
||||||
#define __PARENT_FSM_H_
|
#define __PARENT_FSM_H_
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 提前做类型声明 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define ParentFSM_Input(pFSM) ((ParentFSMData *)_preloadIn((FSM *)pFSM))
|
|
||||||
|
|
||||||
typedef struct _parentFSMData
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 自定义数据和信号 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* @brief 自定义外部信号,目前最多15个
|
||||||
|
* @details 因为是Unint16存储的信号位
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
enum ParentFSMSignals{
|
||||||
|
Signal_toA = 1, /**< 必须从1开始,0预留给Idle信号了*/
|
||||||
|
Signal_toB,
|
||||||
|
Signal_toC,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 自定义外部数据
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct ParentFSMExternalData
|
||||||
{
|
{
|
||||||
int arrindex;
|
int arrindex;
|
||||||
}ParentFSMData;
|
int x;
|
||||||
typedef struct _ParentFSM ParentFSM;
|
}ParentFSMExternalData;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 自定义内部数据
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct ParentFSMInnerData
|
||||||
|
{
|
||||||
|
int y1;
|
||||||
|
int inner1;
|
||||||
|
}ParentFSMInnerData;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* 下面的改个名字就行了 */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
#define ParentFSM_Input(pFSM) ((ParentFSMExternalData *)_preloadIn((FSM *)pFSM)) /**< @deprecated 暂时弃用 */
|
||||||
|
|
||||||
|
typedef struct ParentFSMData
|
||||||
|
{
|
||||||
|
ParentFSMExternalData external;
|
||||||
|
ParentFSMInnerData internal;
|
||||||
|
}ParentFSMData;
|
||||||
|
|
||||||
|
typedef struct ParentFSM ParentFSM;
|
||||||
ParentFSM *createParentFSM();
|
ParentFSM *createParentFSM();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
163
父子状态机测试.plecs
163
父子状态机测试.plecs
|
@ -47,7 +47,7 @@ Plecs {
|
||||||
ScriptsDialogGeometry ""
|
ScriptsDialogGeometry ""
|
||||||
ScriptsDialogSplitterPos "0"
|
ScriptsDialogSplitterPos "0"
|
||||||
Schematic {
|
Schematic {
|
||||||
Location [818, 291; 1460, 717]
|
Location [147, 417; 789, 840]
|
||||||
ZoomFactor 1.71498
|
ZoomFactor 1.71498
|
||||||
SliderPosition [0, 0]
|
SliderPosition [0, 0]
|
||||||
ShowBrowser off
|
ShowBrowser off
|
||||||
|
@ -139,9 +139,9 @@ Plecs {
|
||||||
Show off
|
Show off
|
||||||
}
|
}
|
||||||
FSM {
|
FSM {
|
||||||
Location [0, 0; 1918, 923]
|
Location [661, 192; 2579, 1112]
|
||||||
ZoomFactor 0.76361
|
ZoomFactor 0.76361
|
||||||
SliderPosition [0, 44]
|
SliderPosition [0, 47]
|
||||||
FsmState {
|
FsmState {
|
||||||
Name "A"
|
Name "A"
|
||||||
Position [360, 480]
|
Position [360, 480]
|
||||||
|
@ -161,8 +161,8 @@ Plecs {
|
||||||
}
|
}
|
||||||
FsmState {
|
FsmState {
|
||||||
Name "B"
|
Name "B"
|
||||||
Position [1400, 420]
|
Position [1220, 400]
|
||||||
Frame [-710, -260; 710, 260]
|
Frame [-530, -240; 530, 240]
|
||||||
Parameter {
|
Parameter {
|
||||||
Name "EnterAction"
|
Name "EnterAction"
|
||||||
Value "printf(\" enterB \");"
|
Value "printf(\" enterB \");"
|
||||||
|
@ -177,7 +177,7 @@ Plecs {
|
||||||
}
|
}
|
||||||
FsmState {
|
FsmState {
|
||||||
Name "D"
|
Name "D"
|
||||||
Position [-530, 0]
|
Position [-350, 20]
|
||||||
Frame [-100, -90; 100, 90]
|
Frame [-100, -90; 100, 90]
|
||||||
Parameter {
|
Parameter {
|
||||||
Name "EnterAction"
|
Name "EnterAction"
|
||||||
|
@ -194,105 +194,46 @@ Plecs {
|
||||||
}
|
}
|
||||||
FsmState {
|
FsmState {
|
||||||
Name ".Junction"
|
Name ".Junction"
|
||||||
Position [-380, -150]
|
Position [-200, -130]
|
||||||
}
|
}
|
||||||
FsmState {
|
FsmState {
|
||||||
Name ".PointState"
|
Name ".PointState"
|
||||||
Position [-380, -190]
|
Position [-200, -170]
|
||||||
}
|
}
|
||||||
FsmState {
|
FsmState {
|
||||||
Name "E"
|
Name "E"
|
||||||
Position [220, 40]
|
Position [230, 20]
|
||||||
Frame [-400, -130; 400, 130]
|
Frame [-230, -90; 230, 90]
|
||||||
Parameter {
|
Parameter {
|
||||||
Name "EnterAction"
|
Name "EnterAction"
|
||||||
Value "printf(\" enterE \");"
|
Value "printf(\" enterE \");"
|
||||||
}
|
}
|
||||||
Parameter {
|
Parameter {
|
||||||
Name "DuringAction"
|
Name "DuringAction"
|
||||||
Value ""
|
Value "printf(\" duringE \");"
|
||||||
}
|
}
|
||||||
Parameter {
|
Parameter {
|
||||||
Name "ExitAction"
|
Name "ExitAction"
|
||||||
Value "printf(\" exitE \");"
|
Value "printf(\" exitE \");"
|
||||||
}
|
}
|
||||||
FsmState {
|
|
||||||
Name "State"
|
|
||||||
Position [-130, 30]
|
|
||||||
Frame [-90, -60; 90, 60]
|
|
||||||
Parameter {
|
|
||||||
Name "EnterAction"
|
|
||||||
Value "/* enter action */"
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "DuringAction"
|
|
||||||
Value ""
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "ExitAction"
|
|
||||||
Value ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FsmState {
|
|
||||||
Name ".PointState"
|
|
||||||
Position [110, -80]
|
|
||||||
}
|
|
||||||
FsmState {
|
|
||||||
Name "State1"
|
|
||||||
Position [230, 30]
|
|
||||||
Frame [-90, -60; 90, 60]
|
|
||||||
Parameter {
|
|
||||||
Name "EnterAction"
|
|
||||||
Value "/* enter action */"
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "DuringAction"
|
|
||||||
Value ""
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "ExitAction"
|
|
||||||
Value ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FsmState {
|
FsmState {
|
||||||
Name "C"
|
Name "C"
|
||||||
Position [1100, 1110]
|
Position [850, 1050]
|
||||||
Frame [-550, -150; 550, 150]
|
Frame [-300, -90; 300, 90]
|
||||||
Parameter {
|
Parameter {
|
||||||
Name "EnterAction"
|
Name "EnterAction"
|
||||||
Value "printf(\" enterC \");"
|
Value "printf(\" enterC \");"
|
||||||
}
|
}
|
||||||
Parameter {
|
Parameter {
|
||||||
Name "DuringAction"
|
Name "DuringAction"
|
||||||
Value ""
|
Value "printf(\" duringC \");"
|
||||||
}
|
}
|
||||||
Parameter {
|
Parameter {
|
||||||
Name "ExitAction"
|
Name "ExitAction"
|
||||||
Value "printf(\" exitC \");"
|
Value "printf(\" exitC \");"
|
||||||
}
|
}
|
||||||
FsmState {
|
|
||||||
Name "D"
|
|
||||||
Position [-140, 30]
|
|
||||||
Frame [-100, -90; 100, 90]
|
|
||||||
Parameter {
|
|
||||||
Name "EnterAction"
|
|
||||||
Value "printf(\" enterD \");"
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "DuringAction"
|
|
||||||
Value "printf(\" duringD \");"
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "ExitAction"
|
|
||||||
Value "printf(\" exitD \");"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FsmState {
|
|
||||||
Name ".PointState"
|
|
||||||
Position [-10, -100]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
FsmState {
|
FsmState {
|
||||||
Name ".PointState"
|
Name ".PointState"
|
||||||
|
@ -618,70 +559,6 @@ Plecs {
|
||||||
Value "2"
|
Value "2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FsmTransition {
|
|
||||||
FsmSrcInfo {
|
|
||||||
StatePath "C/.PointState"
|
|
||||||
TerminalLoc bottom
|
|
||||||
TerminalCoord 0.5
|
|
||||||
External on
|
|
||||||
}
|
|
||||||
FsmDstInfo {
|
|
||||||
StatePath "C/D"
|
|
||||||
TerminalLoc top
|
|
||||||
TerminalCoord 0.414129
|
|
||||||
External on
|
|
||||||
}
|
|
||||||
SegmentLengths [15,-72.90010560019118,-3]
|
|
||||||
LabelPosition 0.5
|
|
||||||
Parameter {
|
|
||||||
Name "Trigger"
|
|
||||||
Value ""
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "Condition"
|
|
||||||
Value ""
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "Action"
|
|
||||||
Value ""
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "Priority"
|
|
||||||
Value "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FsmTransition {
|
|
||||||
FsmSrcInfo {
|
|
||||||
StatePath "B/E/.PointState"
|
|
||||||
TerminalLoc bottom
|
|
||||||
TerminalCoord 0.5
|
|
||||||
External on
|
|
||||||
}
|
|
||||||
FsmDstInfo {
|
|
||||||
StatePath "B/E/State"
|
|
||||||
TerminalLoc top
|
|
||||||
TerminalCoord 0.490903
|
|
||||||
External on
|
|
||||||
}
|
|
||||||
SegmentLengths [18.5]
|
|
||||||
LabelPosition 0.5
|
|
||||||
Parameter {
|
|
||||||
Name "Trigger"
|
|
||||||
Value ""
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "Condition"
|
|
||||||
Value ""
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "Action"
|
|
||||||
Value ""
|
|
||||||
}
|
|
||||||
Parameter {
|
|
||||||
Name "Priority"
|
|
||||||
Value "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
|
@ -806,17 +683,17 @@ Plecs {
|
||||||
Direction up
|
Direction up
|
||||||
Flipped off
|
Flipped off
|
||||||
LabelPosition south
|
LabelPosition south
|
||||||
Location [811, 582; 1161, 833]
|
Location [849, 525; 1199, 784]
|
||||||
State "AAAA/wAAAAD9AAAAAgAAAAEAAAAAAAAAAPwCAAAAA/sAAAAQAFoAbwBvA"
|
State "AAAA/wAAAAD9AAAAAgAAAAEAAAAAAAAAAPwCAAAAA/sAAAAQAFoAbwBvA"
|
||||||
"G0AQQByAGUAYQAAAAAA/////wAAADQA////+wAAABQAUwBhAHYAZQBkAFYAaQBlAHcAcwAAAAAA//"
|
"G0AQQByAGUAYQAAAAAA/////wAAADQA////+wAAABQAUwBhAHYAZQBkAFYAaQBlAHcAcwAAAAAA//"
|
||||||
"///wAAAGYA////+wAAAAwAVAByAGEAYwBlAHMAAAAAAP////8AAABmAP///wAAAAMAAAAAAAAAAPw"
|
"///wAAAGYA////+wAAAAwAVAByAGEAYwBlAHMAAAAAAP////8AAABmAP///wAAAAMAAAAAAAAAAPw"
|
||||||
"BAAAAAfsAAAAUAEQAYQB0AGEAVwBpAGQAZwBlAHQAAAAAAP////8AAABQAP///wAAAV4AAADgAAAA"
|
"BAAAAAfsAAAAUAEQAYQB0AGEAVwBpAGQAZwBlAHQAAAAAAP////8AAABQAP///wAAAV4AAADoAAAA"
|
||||||
"BAAAAAQAAAAIAAAACPwAAAABAAAAAgAAAAEAAAAOAFQAbwBvAGwAQgBhAHIBAAAAAP////8AAAAAA"
|
"BAAAAAQAAAAIAAAACPwAAAABAAAAAgAAAAEAAAAOAFQAbwBvAGwAQgBhAHIBAAAAAP////8AAAAAA"
|
||||||
"AAAAA=="
|
"AAAAA=="
|
||||||
SavedViews "AAAAAgAAAAA="
|
SavedViews "AAAAAgAAAAA="
|
||||||
HeaderState "AAAA/wAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAL/gMAAAAJAAAAB"
|
HeaderState "AAAA/wAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAL/gMAAAAJAAAAA"
|
||||||
"gAAAGQAAAAHAAAAZAAAAAgAAABkAAAACQAAAGQAAAABAAAAZAAAAAIAAABkAAAAAwAAAGQAAAAEAA"
|
"QAAAGQAAAADAAAAZAAAAAIAAABkAAAABQAAAGQAAAAEAAAAZAAAAAcAAABkAAAABgAAAGQAAAAJAA"
|
||||||
"AAZAAAAAUAAABkAAAAiwAAAAsBAAABAAAAAAAAAAAAAAAAZP////8AAACBAAAAAAAAAAsAAABzAAA"
|
"AAZAAAAAgAAABkAAAAiwAAAAsBAAABAAAAAAAAAAAAAAAAZP////8AAACBAAAAAAAAAAsAAABzAAA"
|
||||||
"AAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAA"
|
"AAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAA"
|
||||||
"AAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAA"
|
"AAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAA"
|
||||||
"AAYAAAAAQAAAAAAAAPoAAAAABg="
|
"AAYAAAAAQAAAAAAAAPoAAAAABg="
|
||||||
|
@ -904,4 +781,4 @@ Plecs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DemoSignature "3mLOZwvyqmZ1g5qsGftq/0aRPBxKRskpkes5wR/pt1M="
|
DemoSignature "GVuBD7S6RWz7S12avKXRuEMLBGx74onrKaOKhUN+KRs="
|
||||||
|
|
Loading…
Reference in New Issue