Boost.MSM -> Ignore events that were not explicitly defined for a state

Hello list, I'm experimenting a bit with *boost.msm* from the *boost 1.52* library. Please consider the following small code snippted which generally defines a state machine with the states *State1*, *State2* and *State3*, and the events *Event1* (triggers the transition from State1 to State2) and *Event2* (triggers the transition from State2 to State3): #include <iostream> #include <boost/msm/back/state_machine.hpp> #include <boost/msm/front/state_machine_def.hpp> #include <boost/msm/front/functor_row.hpp> namespace { namespace msm = boost::msm; namespace msmf = boost::msm::front; namespace mpl = boost::mpl; // ----- Events struct Event1 {}; struct Event2 {}; // ----- State machine struct Sm1_:msmf::state_machine_def<Sm1_> { // States struct Init:msmf::state<> {}; struct State1:msmf::state<> { // Entry action template <class Event,class Fsm> void on_entry(Event const&, Fsm&) { std::cout << "State1::on_entry()" << std::endl; } // Exit action template <class Event,class Fsm> void on_exit(Event const&, Fsm&) { std::cout << "State1::on_exit()" << std::endl; } }; struct State2:msmf::state<> { // Entry action template <class Event,class Fsm> void on_entry(Event const&, Fsm&) { std::cout << "State2::on_entry()" << std::endl; } // Exit action template <class Event,class Fsm> void on_exit(Event const&, Fsm&) { std::cout << "State2::on_exit()" << std::endl; } }; struct State3:msmf::state<> { // Entry action template <class Event,class Fsm> void on_entry(Event const&, Fsm&) { std::cout << "State3::on_entry()" << std::endl; } // Exit action template <class Event,class Fsm> void on_exit(Event const&, Fsm&) { std::cout << "State3::on_exit()" << std::endl; } }; // Set initial state typedef State1 initial_state; // Actions struct InitAction { template <class Event, class Fsm, class SourceState, class TargetState> void operator()(Event const&, Fsm&, SourceState&, TargetState&) const { std::cout << "InitAction()" << std::endl; } }; struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, msmf::none, msmf::none >, msmf::Row < State2, Event2, State3, msmf::none, msmf::none > > {}; }; // Pick a back-end typedef msm::back::state_machine<Sm1_> Sm1; void test() { Sm1 sm1; sm1.start(); std::cout << "> Send Event2" << std::endl; sm1.process_event(Event2()); std::cout << "> Send Event1" << std::endl; sm1.process_event(Event1()); } } int main() { test(); return 0; } If I compile and execute the code above the software crashes due to the fact, that *Event2* is received in the state *State1*. My understanding of a state machine and boost.msm was, that all events which are not defined for a particular state, will be just ignored and the state receiving this unknown event (here *Event2*) will keept. Is there a possibility in boost.msm ( maybe by adopting to the transition table) to stay in the current state if an event was received which was not assigned to this state? Thank you in advance! Best regards, RaRi -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-MSM-Ignore-events-that-were-not-exp... Sent from the Boost - Users mailing list archive at Nabble.com.

Hi, <snip>
struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, msmf::none, msmf::none >, msmf::Row < State2, Event2, State3, msmf::none, msmf::none > > {}; }; void test() { Sm1 sm1; sm1.start(); std::cout << "> Send Event2" << std::endl; sm1.process_event(Event2()); std::cout << "> Send Event1" << std::endl; sm1.process_event(Event1()); } }
<snip>
If I compile and execute the code above the software crashes due to the fact, that *Event2* is received in the state *State1*.
My understanding of a state machine and boost.msm was, that all events which are not defined for a particular state, will be just ignored and the state receiving this unknown event (here *Event2*) will keept.
Is there a possibility in boost.msm ( maybe by adopting to the transition table) to stay in the current state if an event was received which was not assigned to this state?
Thank you in advance!
Best regards,
RaRi
Strictly speaking, it is considered an error when an event is sent to a state machine which is not in a state where it can process it. MSM's default is an assert, so you will get this only in debug mode. You have 2 possibilities: - the easy one, overwrite the default handler in the front-end: // 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; } - handle the event to show that you expected this case to arise. A simple internal transition in State1 will do (see http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s03.html#d0e1338). I personally add an action to this transition to log this but it's a matter of taste. Internal<Event2> would actually do. HTH, Christophe

Hi Christophe, thx for the fast response. I will check evaluate your suggestion as fast as possible. I have another issue with MSM: Is there a possibility to model a "do:)"-activity within a state (some UML modelling tools like enterprise architect support this kind of activity)? This means an action which is executed between the entry-Action ( void on_exit (...)) and the exit-action (void on_exit (...))? Maybe this can be solved by using an internal transition within a state which defines among the entry- and exit function additionally the functor "operator ()(...){// Do something state-specific}" ?! It would be great IFA you could provide me within something information if MSM supports such "Do"-activities in a state. Thanks in advanced, RaRi -- Diese Nachricht wurde von meinem Android Mobiltelefon mit GMX Mail gesendet. "Christophe Henry-3 [via Boost]" <ml-node+s2283326n4640304h12@n4.nabble.com> schrieb: Hi, <snip>
struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, msmf::none, msmf::none >, msmf::Row < State2, Event2, State3, msmf::none, msmf::none > > {}; }; void test() { Sm1 sm1; sm1.start(); std::cout << "> Send Event2" << std::endl; sm1.process_event(Event2()); std::cout << "> Send Event1" << std::endl; sm1.process_event(Event1()); } }
<snip>
If I compile and execute the code above the software crashes due to the fact, that *Event2* is received in the state *State1*.
My understanding of a state machine and boost.msm was, that all events which are not defined for a particular state, will be just ignored and the state receiving this unknown event (here *Event2*) will keept.
Is there a possibility in boost.msm ( maybe by adopting to the transition table) to stay in the current state if an event was received which was not assigned to this state?
Thank you in advance!
Best regards,
RaRi
Strictly speaking, it is considered an error when an event is sent to a state machine which is not in a state where it can process it. MSM's default is an assert, so you will get this only in debug mode. You have 2 possibilities: - the easy one, overwrite the default handler in the front-end: // 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; } - handle the event to show that you expected this case to arise. A simple internal transition in State1 will do (see http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s03.html#d0e1338). I personally add an action to this transition to log this but it's a matter of taste. Internal<Event2> would actually do. HTH, Christophe _______________________________________________ Boost-users mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/boost-users _____________________________________________ If you reply to this email, your message will be added to the discussion below: http://boost.2283326.n4.nabble.com/Boost-MSM-Ignore-events-that-were-not-exp... To unsubscribe from Boost.MSM -> Ignore events that were not explicitly defined for a state, click here. NAML -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-MSM-Ignore-events-that-were-not-exp... Sent from the Boost - Users mailing list archive at Nabble.com.

Hi Christophe, thx for the fast response. I will check evaluate your suggestion as fast as possible. I have another issue with MSM: Is there a possibility to model a "do:)"-activity within a state (some UML modelling tools like enterprise architect support this kind of activity)? This means an action which is executed between the entry-Action ( void on_exit (...)) and the exit-action (void on_exit (...))? Maybe this can be solved by using an internal transition within a state which defines among the entry- and exit function additionally the functor "operator ()(...){// Do something state-specific}" ?! It would be great IFA you could provide me within something information if MSM supports such "Do"-activities in a state. Thanks in advanced, RaRi -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-MSM-Ignore-events-that-were-not-exp... Sent from the Boost - Users mailing list archive at Nabble.com.

Hi,
Hi Christophe,
thx for the fast response. I will check evaluate your suggestion as fast as possible.
I have another issue with MSM: Is there a possibility to model a "do:)"-activity within a state (some UML modelling tools like enterprise architect support this kind of activity)? This means an action which is executed between the entry-Action ( void on_exit (...)) and the exit-action (void on_exit (...))?
At the moment no.
Maybe this can be solved by using an internal transition within a state which defines among the entry- and exit function additionally the functor "operator ()(...){// Do something state-specific}" ?!
It's not so simple. Do is defined as an operation which lasts from entry to exit, continuously, not a single call. To implement this will require a second thread so that not to block the state machine.
It would be great IFA you could provide me within something information if MSM supports such "Do"-activities in a state.
MSM does not support it yet, and I insist on yet (I'm working on it) ;-) At the moment, you'll have to handle the extra thread yourself, which is not trivial.
Thanks in advanced,
RaRi
HTH, Christophe
participants (2)
-
Christophe Henry
-
RaRi