From 74c357c04658ba575de966780af00caae224b865 Mon Sep 17 00:00:00 2001 From: godcreator <974980621@qq.com> Date: Tue, 30 Jan 2024 15:50:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=8Aparentchild=E7=9A=84=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E5=A4=8D=E5=88=B6=E8=BF=87=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FSM_OOP/childtest/ParentFSM.c | 212 ++++++++++++++++++++++ FSM_OOP/childtest/childFSM.c | 75 ++++++++ FSM_OOP/childtest/childFSM.h | 15 ++ FSM_OOP/childtest/childFSM_private.h | 121 ++++++++++++ FSM_OOP/childtest/main.c | 34 ++++ FSM_OOP/childtest/parentFSM.h | 13 ++ FSM_OOP/{usr => keytest}/keyFSM.c | 0 FSM_OOP/{usr => keytest}/keyFSM.h | 0 FSM_OOP/{usr => keytest}/keyFSM_private.h | 0 main.c => FSM_OOP/keytest/main.c | 0 10 files changed, 470 insertions(+) create mode 100644 FSM_OOP/childtest/ParentFSM.c create mode 100644 FSM_OOP/childtest/childFSM.c create mode 100644 FSM_OOP/childtest/childFSM.h create mode 100644 FSM_OOP/childtest/childFSM_private.h create mode 100644 FSM_OOP/childtest/main.c create mode 100644 FSM_OOP/childtest/parentFSM.h rename FSM_OOP/{usr => keytest}/keyFSM.c (100%) rename FSM_OOP/{usr => keytest}/keyFSM.h (100%) rename FSM_OOP/{usr => keytest}/keyFSM_private.h (100%) rename main.c => FSM_OOP/keytest/main.c (100%) diff --git a/FSM_OOP/childtest/ParentFSM.c b/FSM_OOP/childtest/ParentFSM.c new file mode 100644 index 0000000..324c7fe --- /dev/null +++ b/FSM_OOP/childtest/ParentFSM.c @@ -0,0 +1,212 @@ +#include +#include + +#include "parentFSM.h" +#include "FSM_protected.h" + +#define DEFAULT_STATE Idle +#define NAME Parent + +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(){ + printf(" start "); + return A; +} + +State A2BHandler(){ + printf(" A2B "); + return B; +} + +State B2AHandler(){ + printf(" B2A "); + return A; +} + +State B2CHandler(){ + printf(" B2C "); + return C; +} + +State C2AHandler(){ + printf(" C2A "); + return A; +} + + +void A_enterAction(){ + printf(" enterA "); +} +void A_duringAction(){ + printf(" duringA "); +} +void A_exitAction(){ + printf(" exitA "); +} + +void B_enterAction(FSM *pFSM){ + printf(" enterB "); + + FSM *cFSM = pFSM->privateVars.childFSM[0]; + cFSM->vtbl.step(cFSM); +} +void B_duringAction(FSM *pFSM){ + printf(" duringB "); + + FSM *cFSM = pFSM->privateVars.childFSM[0]; + cFSM->vtbl.step(cFSM); +} +void B_exitAction(FSM *pFSM){ + FSM *cFSM = pFSM->privateVars.childFSM[0]; + cFSM->vtbl.reset(cFSM); + + printf(" exitB "); +} + + +void C_enterAction(){ + printf(" enterC "); +} +void C_duringAction(){ + printf(" duringC "); +} +void C_exitAction(){ + printf(" exitC "); +} + + + +static void setupHandler(FSMHandler* fcns){ + typedef int (*transitionHandlerPtr)(FSM* pFSM); + #define AVOID_WARNING(handler) (transitionHandlerPtr)handler + + fcns->duringActionTable[A] = A_duringAction; + fcns->duringActionTable[B] = B_duringAction; + fcns->duringActionTable[C] = C_duringAction; + + fcns->enterActionTable[B] = B_enterAction; + fcns->enterActionTable[C] = C_enterAction; + fcns->enterActionTable[A] = A_enterAction; + + fcns->exitActionTable[A] = A_exitAction; + fcns->exitActionTable[B] = B_exitAction; + fcns->exitActionTable[C] = C_exitAction; + + fcns->transitionTable[index(Idle, Start)] = AVOID_WARNING(StartHandler); + fcns->transitionTable[index(A, A2B)] = AVOID_WARNING(A2BHandler); + fcns->transitionTable[index(B, B2A)] = AVOID_WARNING(B2AHandler); + fcns->transitionTable[index(B, B2C)] = AVOID_WARNING(B2CHandler); + fcns->transitionTable[index(C, C2A)] = AVOID_WARNING(C2AHandler); +} + + + +/* + 用户自定义事件选择逻辑—————————————————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){ + printf("\tParentFSM: "); + + printf("当前状态:%s, 当前事件:%s, 动作:", stateStr[pFSM->base.privateVars.curState], eventStr[pFSM->base.privateVars.curEvent]); +} + + +static void step(ParentFSM* pFSM){ + printFSM(pFSM); + stepBaseFSM(BASE_FSM(pFSM)); +} + +static void reset(ParentFSM* pFSM){ + resetBaseFSM(BASE_FSM(pFSM)); + printf(" ParentFSM-reset"); +} + +static void initData(ParentFSM *pFSM){ + ParentFSMData *data = (ParentFSMData *)malloc(sizeof(ParentFSMData)); + data->arrindex = 0; + + pFSM->base.data = data; +} + + +ParentFSM *createParentFSM(){ + + ParentFSM *pFSM; + pFSM = (ParentFSM *)newBaseFSM(Count_State, Count_Event, DEFAULT_STATE); + + pFSM->base.vtbl.step = (Avoid_WARNING_void_FSM)step; + pFSM->base.vtbl.selectEvent = (Avoid_WARNING_int_data)selectEvent; + pFSM->base.vtbl.initData = (Avoid_WARNING_void_FSM)initData; + pFSM->base.vtbl.setupHandler = (Avoid_WARNING_void_fcns)setupHandler; + + + constructFSM((FSM_Ptr)pFSM); + return pFSM; +} + + + + diff --git a/FSM_OOP/childtest/childFSM.c b/FSM_OOP/childtest/childFSM.c new file mode 100644 index 0000000..686fa7e --- /dev/null +++ b/FSM_OOP/childtest/childFSM.c @@ -0,0 +1,75 @@ +#include +#include + +#include "FSM_protected.h" +#include "childFSM.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]; +} + +static void step(ChildFSM* pFSM){ + printFSM(pFSM); + stepBaseFSM(BASE_FSM(pFSM)); +} + +static void initData(ChildFSM *pFSM){ // 必须重新实现 + ChildFSMData *data = (ChildFSMData *)malloc(sizeof(ChildFSMData)); + data->arrindex = 0; + + pFSM->base.data = data; +} + +static void setupHandler(FSMHandler* fcns){ // 必须重新实现 + fcns->duringActionTable[E] = (Avoid_WARNING_void_FSM)actionFcn(during, E); + fcns->duringActionTable[D] = (Avoid_WARNING_void_FSM)actionFcn(during, D); + + fcns->enterActionTable[D] = (Avoid_WARNING_void_FSM)actionFcn(enter, D); + fcns->enterActionTable[E] = (Avoid_WARNING_void_FSM)actionFcn(enter, E); + + fcns->exitActionTable[D] = (Avoid_WARNING_void_FSM)D_exitAction; + fcns->exitActionTable[E] = (Avoid_WARNING_void_FSM)E_exitAction; + + fcns->transitionTable[index(Idle, Idle2D)] = (Avoid_WARNING_int_FSM)transitionHandler(Idle2D); + fcns->transitionTable[index(Idle, Idle2E)] = (Avoid_WARNING_int_FSM)transitionHandler(Idle2E); + fcns->transitionTable[index(D, D2E)] = (Avoid_WARNING_int_FSM)transitionHandler(D2E); + fcns->transitionTable[index(E, E2D)] = (Avoid_WARNING_int_FSM)transitionHandler(E2D); +} + +/* + 唯一外界调用的函数 + */ + +ChildFSM *createChildFSM(){ + + ChildFSM *pFSM; + pFSM = (ChildFSM *)newBaseFSM(Count_State, Count_Event, DEFAULT_STATE); + + pFSM->base.vtbl.step = (Avoid_WARNING_void_FSM)step; + pFSM->base.vtbl.selectEvent = (Avoid_WARNING_int_data)selectEvent; + pFSM->base.vtbl.initData = (Avoid_WARNING_void_FSM)initData; + pFSM->base.vtbl.setupHandler = (Avoid_WARNING_void_fcns)setupHandler; + + constructFSM((FSM_Ptr)pFSM); + + return pFSM; +} diff --git a/FSM_OOP/childtest/childFSM.h b/FSM_OOP/childtest/childFSM.h new file mode 100644 index 0000000..23f9aaa --- /dev/null +++ b/FSM_OOP/childtest/childFSM.h @@ -0,0 +1,15 @@ +#ifndef __CHILD_FSM_H_ +#define __CHILD_FSM_H_ + +typedef struct _childFSMData +{ + int arrindex; +}ChildFSMData; + +typedef struct _ChildFSM ChildFSM; + +ChildFSM *createChildFSM(); + + + +#endif diff --git a/FSM_OOP/childtest/childFSM_private.h b/FSM_OOP/childtest/childFSM_private.h new file mode 100644 index 0000000..3560f94 --- /dev/null +++ b/FSM_OOP/childtest/childFSM_private.h @@ -0,0 +1,121 @@ +#ifndef __CHILD_PRIVATE_FSM_H_ +#define __CHILD_PRIVATE_FSM_H_ + +#include "FSM_protected.h" +#include "childFSM.h" +#include + + +/* + 继承基类 + */ +typedef struct _ChildFSM +{ + // 继承父类 + FSM base; +}ChildFSM; + +/* + 状态和对应的 action, exit, during 函数 + */ + +typedef enum _State +{ + Idle, + D, + E, + + Count_State, +} State; +#define DEFAULT_STATE E + +void actionFcn(enter, D)() +{ + printf(" enterD "); +} +void actionFcn(during, D)() +{ + printf(" duringD "); +} +void actionFcn(exit, D)() +{ + printf(" exitD "); +} + +void actionFcn(enter, E)() +{ + printf(" enterE "); +} +void actionFcn(during, E)() +{ + printf(" duringE "); +} +void actionFcn(exit, E)() +{ + printf(" exitE "); +} + +/* + 事件和对应的转移函数 + */ + +typedef enum _Event{ + Idle_Event, + Idle2D, + Idle2E, + D2E, + E2D, + + Count_Event, +}Event; + + +State transitionHandler(Idle2D)() +{ + printf(" Idle2D "); + return D; +} + +State transitionHandler(Idle2E)() +{ + printf(" Idle2E "); + return E; +} + +State transitionHandler(D2E)() +{ + printf(" D2E "); + return E; +} + +State transitionHandler(E2D)() +{ + printf(" E2D "); + return D; +} + + + + +/* + 用户自定义事件选择逻辑—————————————————begin +*/ +const static char *stateStr[] = { + "Idle", + "D", + "E", + }; +const static char *eventStr[] = { + "Idle", + "Idle2D", + "Idle2E", + "D2E", + "E2D", +}; +static void printFSM(ChildFSM* pFSM){ + printf(" \t\tChildFSM: "); + printf("当前状态:%s, 当前事件:%s, 动作:", stateStr[getFSMCurState((FSM_Ptr)pFSM)], eventStr[getFSMCurEvent((FSM_Ptr)pFSM)]); +} + + +#endif diff --git a/FSM_OOP/childtest/main.c b/FSM_OOP/childtest/main.c new file mode 100644 index 0000000..cfe69d8 --- /dev/null +++ b/FSM_OOP/childtest/main.c @@ -0,0 +1,34 @@ +#include + +#include "childFSM.h" +#include "parentFSM.h" +#include "FSM_public.h" + +ChildFSM *cFSM; +ParentFSM *pFSM; + +int main(){ + + cFSM = createChildFSM(); + pFSM = createParentFSM(); + + setChildNum(BASE_FSM(pFSM), 1); + registerChildFSM(BASE_FSM(pFSM), BASE_FSM(cFSM), 0); + + for (int i = 0; i < 15; i++) + { + ((ChildFSMData *)getData((FSM_Ptr)(cFSM)))->arrindex = i; + ((ParentFSMData *)getData((FSM_Ptr)(pFSM)))->arrindex = i; + + ChildFSMData* data = getData((FSM_Ptr)(cFSM)); + printf(" %d ", data->arrindex); + + setEvent((FSM_Ptr)pFSM); + + vptrFSM((FSM_Ptr)pFSM)->step((FSM_Ptr)pFSM); + + printf("\n"); + } + + return 0; +} \ No newline at end of file diff --git a/FSM_OOP/childtest/parentFSM.h b/FSM_OOP/childtest/parentFSM.h new file mode 100644 index 0000000..39ad9a8 --- /dev/null +++ b/FSM_OOP/childtest/parentFSM.h @@ -0,0 +1,13 @@ +#ifndef __PARENT_FSM_H_ +#define __PARENT_FSM_H_ + +typedef struct _parentFSMData +{ + int arrindex; +}ParentFSMData; +typedef struct _ParentFSM ParentFSM; + +ParentFSM *createParentFSM(); + + +#endif diff --git a/FSM_OOP/usr/keyFSM.c b/FSM_OOP/keytest/keyFSM.c similarity index 100% rename from FSM_OOP/usr/keyFSM.c rename to FSM_OOP/keytest/keyFSM.c diff --git a/FSM_OOP/usr/keyFSM.h b/FSM_OOP/keytest/keyFSM.h similarity index 100% rename from FSM_OOP/usr/keyFSM.h rename to FSM_OOP/keytest/keyFSM.h diff --git a/FSM_OOP/usr/keyFSM_private.h b/FSM_OOP/keytest/keyFSM_private.h similarity index 100% rename from FSM_OOP/usr/keyFSM_private.h rename to FSM_OOP/keytest/keyFSM_private.h diff --git a/main.c b/FSM_OOP/keytest/main.c similarity index 100% rename from main.c rename to FSM_OOP/keytest/main.c