State Machine - Structure for storing states, events and pFuncs

If I create a state machine and want to use this interface:

AddState ( state1, state2, Key_UP ); AddEvent ( Key_UP ); AddEventFunction ( Key_UP, &UP_Function); AddStateFunction ( state1, &State1_In_Function, &State1_Out_Function); AddStateFunction ( state2, &State2_In_Function, &State2_Out_Function); State1_In_Function ( void ) { printf ( "In #1 \n" ); } State1_Out_Function ( void ) { printf ( "Out #1 \n" ); } State2_In_Function ( void ) { printf ( "In #2 \n" ); } State2_Out_Function ( void ) { printf ( "Out #2 \n" ); } UP_Function ( void ) { printf ( "Goin UP \n" ); } 

Thus, when I am in state1, and FSM receives Key_UP, the program prints:

 Out #1 Goin UP In #2 

The question is how to save state and transition information inside the class without the need for the programmer to resize the array. I thought I could use a 2D array and make it a state table, as usual, and make it more portable. I would just handle adding events and states using a vector type to resize as needed. The problem with vectors is that not many embedded devices can use memory allocation calls. My second option is to call the constructor with the state machine and pass it the size that the table will need, but then if I add any new states or events, I will also need to change these values โ€‹โ€‹...

So, how do I store my states, events, and function pointers ?!

+4
source share
3 answers

You can just save them on the stack, although it's a little more complicated :)

However, this is a fun decision, so you are here. The basic principle is to play with decorators and volatility. Code example:

 State state1, state2; // creates a state Event KEY_UP; Event KEY_DOWN; Transition t0(state1, KEY_UP, state2); Transition t1(state2, KEY_DOWN, state1); 

How it works?

Instead of state1 being a โ€œsimpleโ€ object, it will be a bit more confusing. Sort of:

 struct State; struct StateImpl { StateImpl(char const* n): name(n) {} char const* name; }; struct StateNode { StateNode(Event e, State const& s, StateNode const* n): event(e), state(s), next(n) {} Event event; State const& destination; StateNode const* next; }; struct State { State(char const* name): me(0), impl(name) {} StateNode const* me; StateImpl impl; }; 

And then we define a Transition :

 struct Transition { Transition(State& origin, Event e, State const& destination): node(e, destination, origin.me) { origin.me = node; } StateNode node; }; 

Informally, we build a singly linked list, and the head sits in State . We update the title every time we add a transition.

If an event occurs, you need to go through this list until an event occurs and, therefore, is properly sent, or a null pointer is reached, indicating that the event should not be received in this state.

+3
source

I suggest you take a look at Boost.StateChart and, if necessary, create a thin layer around it using the API you want.

This should solve your need to develop adequate data structures.

0
source

You can get cute and do it this way , by the way.

0
source