• Contrast methods of implementing state machines in C

State-Event lookup table

  • Lookup event and state in 2D array
  • Optionally lookup next state in table

Enum state variable

  • Switch statement
  • OnState (transition) and DoState (tick)
  • function-scope static state variables?

Example

typedef enum STATE STATE_T;
enum STATE {
    STATE_ONE,
    STATE_TWO,
    ...
    STATE_COUNT
} currentState;

void OnEvent(EVENT_T evt)
{
    switch(currentState)
    {
    case STATE_ONE:
        switch (evt)
        {
        case EVENT_ONE:
            ...
            break;
        ...    
        }
        ...
        break;
    case STATE_TWO:
        ...
        break;
    }
}

Static arrays 1

  • State is an array of (event, transition) pairs
  • FSM is a struct containing set of states
  • Linear event lookup

Benefits

  • Variable transition array per state
  • Static initialization
  • Closely matches theoretical definition of FSM
  • OO adaptability
  • Refactor easily by passing fsm context?

Drawbacks

  • Linear lookup

Example

/* Transition function */
typedef void (* const HANDLER_FNP)(EVENT_T e);

typedef struct
{
    EVENT_T event;       /* Event ID */
    HANDLER_FNP handler;  /* Pointer to corresponding handler */
} TRANSITION_T;

static const TRANSITION\_T STATE\_ONE[] = {
    {EVENT\_ONE, handler\_one},
    {EVENT\_TWO, handler\_two},
    ...
    {EVENT_MAX,  NULL}
};

struct FSM
{
    const TRANSITION_T** currentState;

    const TRANSITION_T* stateOne;
    const TRANSITION_T* stateTwo;
    ...
};

// Instantiation
struct FSM fsm = {
    NULL,  // currentState
    STATE_ONE,
    STATE_TWO,
    ...
};

void OnEvent(EVENT_T event)
{
    const TRANSITION_T* current = fsm->current;

    // stop searching when a NULL handler is found
    for (i = ; currentState[i].handler != NULL ; i++)
    {
        if (currentState[i].event == event)
        {
            currentState[i].handler(event);
            break;
        }
    }
}

Static arrays 2

  • State is an array of (event, new state, handler) triples
  • FSM is a pointer to the current state.
  • Explicit initialization of resultant states.

TODO