
I try to use boost::MSM to implement a simple state machine for testing purpose. There are several events which have to be processed in the right order, so i defer the other events, which are currently not allowed. I try to defer the events in the transition table, to have one place to look for it, despite having all states to look, what events they defer. I tried to change the transition rows to change their priorities, but it didnt help. If i unkomment the anonymous transition from live_got_image to live_wait_for_image, it works as expected, but i want to transition automaticly to repeatedly enter the states live_wait_for_image/live_got_image until the ev_stop_live get sent. I expect the following output: ------------------------------ entering: fsm_master entering: not_ready no transition from state 0 on event struct `anonymous namespace'::ev_stop_live leaving: not_ready starting: live_wait_for_image leaving: live_wait_for_image starting: live_got_image leaving: live_got_image entering: not_ready but actually i get the following output: ---------------------------------------- entering: fsm_master entering: not_ready no transition from state 0 on event struct `anonymous namespace'::ev_stop_live leaving: not_ready starting: live_wait_for_image leaving: live_wait_for_image starting: live_got_image leaving: live_got_image starting: live_wait_for_image I use boost 1.57.0 and MSVC-2013 (VS-12). Could anybody get me a useful hint? Georg Here is the code: #include <iostream> // back-end #include <boost/msm/back/state_machine.hpp> //front-end #include <boost/msm/front/state_machine_def.hpp> #include <boost/msm/front/functor_row.hpp> namespace msm = boost::msm; namespace mpl = boost::mpl; namespace { using namespace boost::msm::front; // events struct ev_start_stop {}; struct ev_start_live {}; struct ev_stop_live {}; struct ev_learn {}; struct ev_load {}; struct ev_got_image { int payload; }; // front end: define the FSM structure struct fsm_master_ : public msm::front::state_machine_def<fsm_master_> { typedef int activate_deferred_events; template <class Event, class FSM> void on_entry(Event const&, FSM&) { std::cout << "entering: fsm_master" << std::endl; } template <class Event, class FSM> void on_exit(Event const&, FSM&) { std::cout << "leaving: fsm_master" << std::endl; } // the fsm states which are not sub state machines struct not_ready : public msm::front::state<> { template <class Event, class FSM> void on_entry(Event const&, FSM&) { std::cout << "entering: not_ready" << std::endl; } template <class Event, class FSM> void on_exit(Event const&, FSM&) { std::cout << "leaving: not_ready" << std::endl; } }; // The list of FSM states struct live_wait_for_image : public msm::front::state<> { template <class Event, class FSM> void on_entry(Event const&, FSM&) { std::cout << "starting: live_wait_for_image" << std::endl; } template <class Event, class FSM> void on_exit(Event const&, FSM&) { std::cout << "leaving: live_wait_for_image" << std::endl; } }; struct live_got_image : public msm::front::state<> { // here we got the image and we can check, if we need to react on an external event // otherwise transit to wait_for_image and fetch the next image template <class Event, class FSM> void on_entry(Event const&, FSM&) { std::cout << "starting: live_got_image" << std::endl; } template <class Event, class FSM> void on_exit(Event const&, FSM&) { std::cout << "leaving: live_got_image" << std::endl; } }; // --------------------------------------------------- // initial state: fsm_master_ typedef not_ready initial_state; typedef fsm_master_ l; struct transition_table : mpl::vector< // Start Event Next Action Guard // +---------------------+----------------+-------------------+-------------------+----------------+ _row < not_ready, ev_start_live, live_wait_for_image >, _row < live_wait_for_image, ev_got_image, live_got_image >, Row < live_wait_for_image, ev_stop_live, none , Defer , none >, _row < live_got_image, none, live_wait_for_image >, _row < live_got_image, ev_stop_live, not_ready > // +---------------------+----------------+-------------------+-------------------+----------------+ > {}; // Replaces the default no-transition response. template <class FSM, class Event> void no_transition(Event const& e, FSM&, int state) { std::cout << "no transition from state " << state << " on event " << typeid(e).name() << std::endl; } }; // back-end: fsm_master typedef msm::back::state_machine<fsm_master_> fsm_master; } void test() { fsm_master s; s.start(); s.process_event(ev_stop_live()); // this gets no transitioned s.process_event(ev_start_live()); // this one enters live s.process_event(ev_stop_live()); // this gets defered s.process_event(ev_got_image()); // this one enters got_image and the stop live should get processed. // now we should be in not ready again, but we are still in live_wait_for_image } int main() { test(); return 0; }