Implementing a finite state machine

How would you go about implementing a state machine? I've been tossing some ideas around in my head, but can't settle on a decent one. The most promising one I've been thinking of is just having a vector of states. But then I'm not sure how I would actually keep them separate.

I have a state diagram drawn up, but just can't think of how to actually implement this.
You could define the states in an enum, define a set of valid state transitions in a multimap. The state class would maintain your current state and transitions to the next state, using the multimap to maintain valid transitions.
Sticking the states in an enum was another idea I had. Could you explain how a multimap could be used here? I imagine you mean it would function as a lookup table?
The idea is there is a set of valid state transitions. For example, you may allow state transitions: a->b, b->c, b->d, ... These would be held in a multimap and would be used to enforce correct state transitions.
There are a number of different possible state table designs.
Most common are four "columns" in a state table.
-State
-Event
-Action
-Next State
State and Event form a unique key. Action can be an index to a switch statement, or even a function pointer. State and Next State are the same enumerated type. When an event (again an enumerated type) occurs, the current state value and event number row is found in the table. That row indicates the action to be performed and the Next State value is set into the current state variable.

Here's a finite state machine implemented as a template. It does a linear search of the state table, so it's not the most efficient, but it is something that can be implemented easily by simply defining the appropriate enums and providing the overloaded DoAction method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//  A <STATETABLE> is an array of STATEROWS. 
//
//  Where <TS> , <TE>, <TA> are enumerations for the states, events, and action
//  specific to the state machine.
//
//  DoAction is pure virtual and should be implemented in a derived class. 
//
template <typename TS, typename TE, typename TA>   
class STATETABLE  
{   
public:
  typedef struct __staterow
    { TS  state;
      TE  event;
      TA  action;
      TS  next_state;
     } STATEROW;

private:
    const STATEROW *  m_rows;         //  Pointer to array of rows terminated by -1
       
protected:
    //  Terminate due to overloaded action not found
    void ST_Error (TA action)
    {	Abort ("ST=%s Action=%d not handled", m_name, (short) action);
    }
	
    //  Terminate due to missing state table row 
    void ST_Error (TS state, TE event)
    {	Abort ("ST=%s Row not found S=%d E=%d", m_name, state, event);
    }
	             
    //	Return pointer to matching current state and event
    const SR * FindRow (TS state, TE event)
    {   const STATEROW *	row;
               
        row = m_rows;
        while (row->state != -1)
        {   if (row->state == state && row->event == event)
                return row; 
             row++;
       }
        ST_Error (state, event);
        return NULL;		// Not reached
    }    

    //  Returns another event, or 0 if state machine should exit	
    virtual TE DoAction (TA act) = 0;          // pure virtual
	
	
    //	State Machine 
    //	Called with event
    //	Loops until an action returns an EXIT (0) event
    void state_machine (TS & state, TE event)
    {	const STATEROW *  row;

    	while (event) 
	{   row = FindRow (state, event);
                     state = row->next_state;
	     event = DoAction (row->action);
	}
    }
		    
public:
    STATETABLE (const STATEROW * rows)
    {   m_rows = rows;   
    }
	
    virtual ~STATETABLE (void)
    {}
}; 

How would you go about implementing a state machine?

I just use a library -- http://www.boost.org/doc/libs/release/libs/statechart/doc/index.html

There is also http://www.boost.org/doc/libs/release/libs/msm/doc/HTML/index.html but I haven't had a chance to work with it yet.
Last edited on
Well, looks as if grabbing a library is the fastest way to get this going.
Have you tried my library?
It does exactly what you're looking for. It is very easy to implement your own state machine + very easy to maintain.
Have a look at:
http://www.codeproject.com/Articles/406116/Generic-Finite-State-Machine-FSM

and tell me what you think :)

Good luck
Topic archived. No new replies allowed.