Search code examples
c++state-machine

Implementing a State Machine in C++


I'm new to C++.

How can I implement a State Machine in C++?

I'm getting only the messages and should know the next state.

What is the proper structure I need to use?


Solution

  • typedef std::pair<State,Message> StateMessagePair;
    typedef std::map<StateMessagePair,State> StateDiagram;
    StateDiagram sd;
    // add logic to diagram
    ...
    State currentState = getInitialState();
    ...
    // process message
    Message m = getMessage();
    StateDiagram::iterator it=sd.find(std::make_pair(currentState,m)));
    if (it==sd.end()) exit("incorrect message");
    currentState = it->second;
    

    EDIT: Building up the state diagram is done like this (example is for a cola-vending machine):

    StateDiagram.insert(std::make_pair(State::Idle           ,Message::MakeChoice   ),State::WaitingForMoney);
    StateDiagram.insert(std::make_pair(State::WaitingForMoney,Message::Cancel       ),State::Idle);
    StateDiagram.insert(std::make_pair(State::WaitingForMoney,Message::MoneyEntered ),State::FindCan);
    StateDiagram.insert(std::make_pair(State::FindCan        ,Message::CanSentToUser),State::Idle);
    

    Default actions can be implemented using a second map, where the key is only the State, like this:

    typedef std::map<State,State> StateDiagramForDefaults;
    

    Instead of printing "incorrect message", the logic can perform a lookup in the StateDiagramForDefaults.

    If actions needs to be added to the state diagram, the value of the map should be a pair consisting of an action, and a new state, like this:

    typedef std::pair<State,Message> StateMessagePair;
    typedef std::pair<State,IAction *> StateActionPair;
    typedef std::map<StateMessagePair,StateActionPair> StateDiagram;
    

    The logic that builds up the diagram should then "new" an instance of a class that implements IAction, and put that in the StateDiagram.

    The executing logic then just executes the IAction implementation via a virtual method (e.g. execute() or the ()-operator).