一种C语言的状态机

一、背景

以前写状态机的思路都是if else或者switch case,今天我们稍微把思路整理一下,把状态机的状态迁移,和事件触发管理的更直观一些。

二、正题

假设有3个状态,3个事件,每个事件都会触发状态机的状态迁移。在状态机处于某个状态时,都需要执行一次该状态的函数;在事件来临时,即状态发生迁移时,只需要执行一次

状态迁移函数。

StateTransform stateTran[] =
{
    /*currState,event,  nextState,  func cycle,         func trigger */
    {state_1,   event_3,state_3,    func_s1_runing,     NULL},
    {state_2,   event_3,state_3,    func_s2_runing,     func_s1_Tr_13},
    {state_3,   event_1,state_2,    NULL,               func_s3_Tr_s2},
};

表中分别是:当前状态,事件,下个状态,周期执行的函数(或空),执行一次的函数(或空)。

这里有3个状态,分别时state_1,2,3。有3个事件,分别是event_1,2,3。

例如处于state_2时,每次都执行func_s2_runing函数,当发生event_3事件时,状态要从2迁移到3,并且只会执行一次func_s1_Tr_13函数。

三、调度与执行

runStateMachine(&stateMachine, num);

num为事件,传入状态机引擎函数即可。

StateTransform* findTranss(StateMachine_T* pSM)
{
    int i;
    for (i = 0; i < pSM->transNum; i++)
    {
        if ((pSM->p_transform[i].curState == pSM->state))// && (pSM->p_transform[i].eventId == evt))
        {
            return &pSM->p_transform[i];
        }
    }
    return NULL;
}

void runStateMachine(StateMachine_T* pSM, EventID evt)
{
    StateTransform* pTrans;
    pTrans = findTranss(pSM);
    if (pTrans == NULL)
    {
        printf( "CurState= %d Do not process enent: %d\r\n", pSM->state,evt);
        return;
    }
    printf("curState = %d;",pTrans->curState);
    if(evt == pTrans->eventId)
    {
        printf("Event = %d\r\n",pTrans->eventId);
        if (pTrans->CBTrigFunc != NULL)
        {
            pTrans->CBTrigFunc(&evt);
        }
        else
        {
            printf("triger func is NULL\r\n");
        }
        pSM->state = pTrans->nextState;
    }
    else
    {
        if (pTrans->CBfunc != NULL)
        {
            pTrans->CBfunc(&evt);
        }
        else
        {
            printf("running func is NULL\r\n");
        }
    }
}

执行过程很简单,根据当前的状态,去表里找到该状态,然后执行周期性的函数,此时如果有事件发生,那么就发生状态迁移,只执行迁移函数。

四、测试

-----------func_s1_Tr_13-----------
num = 0
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 1
curState = 3;Event = 1
-----------func_s3_Tr_s2-----------
num = 1
curState = 2;***********state 2 running***********
num = 0
curState = 2;***********state 2 running***********
num = 2
curState = 2;***********state 2 running***********
num = 3
curState = 2;Event = 3
-----------func_s1_Tr_13-----------
num = 2
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 1
curState = 3;Event = 1
-----------func_s3_Tr_s2-----------
num = 2
curState = 2;***********state 2 running***********
num = 1
curState = 2;***********state 2 running***********
num = 3
curState = 2;Event = 3
-----------func_s1_Tr_13-----------
num = 2
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 1
curState = 3;Event = 1
-----------func_s3_Tr_s2-----------
num = 0
curState = 2;***********state 2 running***********
num = 1
curState = 2;***********state 2 running***********
num = 2
curState = 2;***********state 2 running***********
num = 0
curState = 2;***********state 2 running***********
num = 2
curState = 2;***********state 2 running***********
num = 2
curState = 2;***********state 2 running***********
num = 0
curState = 2;***********state 2 running***********
num = 3
curState = 2;Event = 3
-----------func_s1_Tr_13-----------
num = 0
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 1
curState = 3;Event = 1
-----------func_s3_Tr_s2-----------
num = 3
curState = 2;Event = 3
-----------func_s1_Tr_13-----------
num = 2
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 0
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 0
curState = 3;running func is NULL
num = 0
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 0
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 0
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 0
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 1
curState = 3;Event = 1
-----------func_s3_Tr_s2-----------
num = 2
curState = 2;***********state 2 running***********
num = 2
curState = 2;***********state 2 running***********
num = 1
curState = 2;***********state 2 running***********
num = 2
curState = 2;***********state 2 running***********
num = 2
curState = 2;***********state 2 running***********
num = 0
curState = 2;***********state 2 running***********
num = 2
curState = 2;***********state 2 running***********
num = 2
curState = 2;***********state 2 running***********
num = 1
curState = 2;***********state 2 running***********
num = 1
curState = 2;***********state 2 running***********
num = 3
curState = 2;Event = 3
-----------func_s1_Tr_13-----------
num = 3
curState = 3;running func is NULL
num = 2
curState = 3;running func is NULL
num = 1
curState = 3;Event = 1
-----------func_s3_Tr_s2-----------
num = 0
curState = 2;***********state 2 running***********
num = 0
curState = 2;***********state 2 running***********
num = 3
curState = 2;Event = 3
-----------func_s1_Tr_13-----------
num = 3
curState = 3;running func is NULL
num = 0
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 0
curState = 3;running func is NULL
num = 0
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 3
curState = 3;running func is NULL
num = 0
curState = 3;running func is NULL

五、源代码

https://gitee.com/Yinqinghui/state-machine.git

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值