- 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