Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::msm - A way to get a string representation (ie. getName) of a state?

Tags:

c++

boost-msm

I'm trying to use boost::msm library to create a state machine in my code. Does anyone know a way to get a string name (not int id) of a state? I am trying to get this for logging/debugging purpose. For example in no_transition function, I get the state id but I'm trying to get a name so it's easier to read:

template <class Event ,class Fsm>
    void no_transition(Event const& e, Fsm& fsm, int stateId)
    {
        //This is what I'm trying: 
        auto state = fsm.get_state_by_id(stateId); //This returns a boost::msm::front::default_base_state. Anything I can override in there to set a name?
        const char* stateName = state->getStateName(); //I want to do something like this since I can do e.getEventId()

        print("FSM rejected the event %s as there is no transition from current state %s (%d)\n", e.getEventId(), stateName, stateId);
    }

Here's how I defined an event and a state: State:

struct Idle : front::state<> {
 static const char* const getStateName() {
        return "Idle";
    }
};

Event:

struct SampleEvent {
    SampleEvent() {}
    static const char* const getEventId() {
        return "SampleEvent";
    }
};

Any ideas would be great. Thanks!

like image 633
user1950039 Avatar asked Jan 04 '13 23:01

user1950039


2 Answers

You can achieve the desired effect using the following code:

 #include <boost/msm/back/tools.hpp>
 #include <boost/msm/back/metafunctions.hpp>
 #include <boost/mpl/for_each.hpp>
  .......
  .......
    template <class Event ,class Fsm>
    void no_transition(Event const& e, Fsm& fsm, int stateId){
        typedef typename boost::msm::back::recursive_get_transition_table<FSM>::type recursive_stt;
        typedef typename boost::msm::back::generate_state_set<recursive_stt>::type all_states;
        std::string stateName;
        boost::mpl::for_each<all_states,boost::msm::wrap<boost::mpl::placeholders::_1> >(boost::msm::back::get_state_name<recursive_stt>(stateName, state));
        std::cout << "No transition from state: " << stateName << std::endl;}
like image 137
Kikosha Avatar answered Sep 29 '22 23:09

Kikosha


  1. Best option: using a visitor.
    Have a look to http://www.boost.org/doc/libs/1_53_0/libs/msm/doc/HTML/examples/SM-2Arg.cpp

  2. Use the last argument (state_id) of no_transition, you could retrieve the name from an array:

    static char const* const state_names[] = { "State1", "State2", ... };
    print(state_names[state_id]);

Pay attention to the fact that a state ID is provided for debugging purpose only. The ID is generated at compiling time and depends on the order of the entries in the transition table

References to MSM documentation:

  • http://www.boost.org/doc/libs/1_53_0_beta1/libs/msm/doc/HTML/ch06s03.html
like image 37
ropieur Avatar answered Sep 30 '22 00:09

ropieur