StateMachineStyle

  • 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;
}
}

$[Get Code]3

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;  
    }  
}  

}

$[Get Code]4

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