varch/doc/fsm.md

3.2 KiB
Raw Blame History

介绍

fsm是一个用于C语言的通用有限状态机模块它通过定义状态转换相关的数据结构以及提供状态机的初始化和执行等关键函数接口帮助开发者在C语言项目中方便地构建和运用有限状态机以处理具有不同状态及状态转换逻辑的业务场景。

接口

函数

int fsm_init(FSM* fsm, StateTransform* trans, int count, int state);
int fsm_execute(FSM* fsm, int event);

使用例子:

#include <stdio.h>
#include "fsm.h"

enum
{
    TestState_Init = 0,
    TestState_Stanby,
    TestState_Run,
    TestState_Error,
    TestState_Exit,
};

enum
{
    TestEvent_Init = 0,
    TestEvent_ToRun,
    TestEvent_ToStanby,
    TestEvent_Error,
    TestEvent_Exit,
};

/* State transition diagram
+-----------+          +-----------+              +-----------+
|           |          |           | -----------> |           |
|   init    | -------> |  standby  |              |    run    |
|           |          |           | <----------  |           |
+-----------+          +-----------+              +-----------+
                             |       \          /       |
                             |        \        /        |
                             |         \      /         |
                             |          \    /          |
                             |           \  /           |
                             |            \/            |
                             |            /\            |
                             |           /  \           |
                             |          /    \          |
                             |         /      \         |
                             |        /        \        |
                             |       /          \       |
                             v      v            v      v
                       +-----------+              +-----------+
                       |           |              |           |
                       |   error   | -----------> |   exit    |
                       |           |              |           |
                       +-----------+              +-----------+
*/
StateTransform TestFsmTable[] = 
{   /*  from,               to,                 event,              action */
    {TestState_Init,    TestState_Stanby,   TestEvent_Init,     NULL},
    {TestState_Stanby,  TestState_Run,      TestEvent_ToRun,    NULL},
    {TestState_Stanby,  TestState_Error,    TestEvent_Error,    NULL},
    {TestState_Stanby,  TestState_Exit,     TestEvent_Exit,     NULL},
    {TestState_Run,     TestState_Stanby,   TestEvent_ToStanby, NULL},
    {TestState_Run,     TestState_Error,    TestEvent_Error,    NULL},
    {TestState_Run,     TestState_Exit,     TestEvent_Exit,     NULL},
    {TestState_Error,   TestState_Exit,     TestEvent_Exit,     NULL},
};

int main(int argc, char* argv[])
{
    FSM TestFsm;
    int event[] = { TestState_Init, TestEvent_ToRun, TestState_Exit };

    fsm_init(&TestFsm, TestFsmTable, 8, TestState_Init);

    printf("%d\r\n", TestFsm.count);

    for (int i = 0; i < sizeof(event) / sizeof(event[0]); i++)
    {
        fsm_execute(&TestFsm, event[i]);
        printf("state %d\r\n", TestFsm.state);
    }

    printf("%c", getchar());
    return 0;
}