
Hi, I have attached a test program that gives some curious results, indicating the statemachine does not reach its proper state when performing state changes in orthogonal regions. The machine attached contains a main state that handles an "update" event. That main state contains 2 inner states, one of which also handles the "update" event. If that inner state transits to another state and back again, the "update" event no longer arrives at it, which in my opinion is a bug. If I modify the state machine so it does not have 2 but only 1 inner state, then the behavior matches my expectations. Could someone please verify if this is bug or tell me if my usage scenerio is incorrect. Regards, George van Venrooij Organic Vectory http://www.organicvectory.com #include <boost/statechart/state_machine.hpp> #include <boost/statechart/event.hpp> #include <boost/statechart/simple_state.hpp> #include <boost/statechart/custom_reaction.hpp> #include <iostream> namespace bs = boost::statechart; using namespace std; // The main event, should be handles by a sub-state and the main state struct update_event; // An event triggering the sub-state to switch struct toggle_event; // A dummy event struct other_event; // Sub-states in 2 orthogonal regions struct state_1A; struct state_1B; struct state_2A; struct state_2B; // Main state struct parent_state; // State machine consisting of the main state struct machine : bs::state_machine<machine, parent_state> { }; typedef boost::mpl::list < state_1A , state_2A
inner_states_t;
// The main state has 2 orthogonal sub-states struct parent_state : bs::simple_state<parent_state, machine, inner_states_t> { typedef boost::mpl::list < bs::custom_reaction <update_event> > reactions; bs::result react(const update_event&) { cout << __FUNCTION__ << endl; return discard_event(); } }; struct update_event : bs::event<update_event> { }; struct other_event : bs::event<other_event> { }; struct toggle_event : bs::event<toggle_event> { }; struct state_1A : bs::simple_state<state_1A, parent_state::orthogonal<0>> { typedef boost::mpl::list < bs::custom_reaction <toggle_event> , bs::custom_reaction <update_event> > reactions; state_1A() { cout << __FUNCTION__ << endl; } bs::result react(const toggle_event&) { cout << __FUNCTION__ << endl; return transit<state_1B>(); } bs::result react(const update_event&) { cout << __FUNCTION__ << endl; return forward_event(); } }; struct state_1B : bs::simple_state<state_1B, parent_state::orthogonal<0>> { typedef boost::mpl::list < bs::custom_reaction <toggle_event> > reactions; state_1B() { cout << __FUNCTION__ << endl; } bs::result react(const toggle_event&) { cout << __FUNCTION__ << endl; return transit<state_1A>(); } }; struct state_2A : bs::simple_state<state_2A, parent_state::orthogonal<1>> { typedef boost::mpl::list < bs::custom_reaction <other_event> > reactions; state_2A() { cout << __FUNCTION__ << endl; } bs::result react(const other_event&) { cout << __FUNCTION__ << endl; return discard_event(); } }; struct state_2B : bs::simple_state<state_2B, parent_state::orthogonal<1>> { typedef boost::mpl::list < bs::custom_reaction <other_event> > reactions; state_2B() { cout << __FUNCTION__ << endl; } bs::result react(const other_event&) { cout << __FUNCTION__ << endl; return discard_event(); } }; int main(int argc, char* argv[]) { machine m; cout << "0. Initiating state machine:" << endl; m.initiate(); cout << endl << "1. Processing 'other_event':" << endl; m.process_event(other_event ()); cout << endl << "2. Processing 'update_event':" << endl; m.process_event(update_event()); cout << endl << "3. Processing 'toggle_event':" << endl; m.process_event(toggle_event()); cout << endl << "4. Processing 'update_event':" << endl; m.process_event(update_event()); cout << endl << "5. Processing 'toggle_event':" << endl; m.process_event(toggle_event()); cout << endl << "6. Processing 'update_event':" << endl; m.process_event(update_event()); return 0; } ////////////////////////////////////////////////////////////////////////// // Program output after building with VC 9 and Boost 1.37.0 // // Note the different event handling in step 6. as compared to step 2. // although the machine should be back in the same state. ////////////////////////////////////////////////////////////////////////// /* 0. Initiating state machine: state_1A::state_1A state_2A::state_2A 1. Processing 'other_event': state_2A::react 2. Processing 'update_event': state_1A::react parent_state::react 3. Processing 'toggle_event': state_1A::react state_1B::state_1B 4. Processing 'update_event': parent_state::react 5. Processing 'toggle_event': state_1B::react state_1A::state_1A 6. Processing 'update_event': parent_state::react */

Hi George [snip]
Could someone please verify if this is bug or tell me if my usage scenerio is incorrect.
As explained here ... <https://svn.boost.org/trac/boost/ticket/2907> ... the behavior is as intended (please see response in the bug for details). Don't hesitate to follow up in this thread if this leaves any questions. HTH & Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.
participants (2)
-
Andreas Huber
-
George van Venrooij