[statechart] history in the different state hierarchies

Hello everybody. I have a problem similar to the one described in the Statechart tutorial, but a little different. My state machine has two states (let's call them A and B) in the different state hierarchies and a third state C that can be transited to from either A or B. The transition from C must be done to either A or B, depending on where we came to C from. So I've decided to use the history. The difference between this problem and what's described in the tutorial is that A and B don't belong to the same composite state (they only belong to the same state machine). I can't simply declare "has_xxx_history" in the outer state like it's done in the tutorial. Here's what I've tried to do: #include <iostream> #include <boost/statechart/shallow_history.hpp> #include <boost/statechart/simple_state.hpp> #include <boost/statechart/state_machine.hpp> #include <boost/statechart/transition.hpp> namespace sc = boost::statechart; // events struct transfer_to_B : sc::event<transfer_to_B> {}; struct visit_C : sc::event<visit_C> {}; struct exit_to_history : sc::event<exit_to_history> {}; // forward declarations struct state_A; struct substate_A; struct substate_B; struct state_C; // state machine struct test_fsm : sc::state_machine<test_fsm, state_A> {}; // composite state A struct state_A : sc::simple_state<state_A, test_fsm, substate_A, sc::has_shallow_history> {}; struct substate_A : sc::simple_state<substate_A, state_A> { typedef boost::mpl::list < sc::transition<transfer_to_B, substate_B> , sc::transition<visit_C, state_C> > reactions; substate_A() { std::cout << "Entered A" << std::endl; } ~substate_A() { std::cout << "Exited A" << std::endl; } }; // composite state B struct state_B : sc::simple_state<state_B, test_fsm, substate_B, sc::has_shallow_history> {}; struct substate_B : sc::simple_state<substate_B, state_B> { typedef sc::transition<visit_C, state_C> reactions; substate_B() { std::cout << "Entered B" << std::endl; } ~substate_B() { std::cout << "Exited B" << std::endl; } }; // simple state C struct state_C : sc::simple_state<state_C, test_fsm> { typedef sc::transition < exit_to_history, sc::shallow_history<substate_A> > reactions; state_C() { std::cout << "Entered C" << std::endl; } ~state_C() { std::cout << "Exited C" << std::endl; } }; int main() { test_fsm fsm; fsm.initiate(); fsm.process_event(visit_C()); fsm.process_event(exit_to_history()); fsm.process_event(transfer_to_B()); fsm.process_event(visit_C()); fsm.process_event(exit_to_history()); } Unfortunately, this doesn't work as intended. The transition to history always leads to substate_A and never to substate_B: Entered A Exited A Entered C Exited C Entered A Exited A Entered B Exited B Entered C Exited C Entered A Exited A Can anyone please clarify if I've got something wrong or made a mistake somewhere? Is history supposed to work in the different state hierarchies?

Hi
I have a problem similar to the one described in the Statechart tutorial, but a little different. My state machine has two states (let's call them A and B) in the different state hierarchies and a third state C that can be transited to from either A or B. The transition from C must be done to either A or B, depending on where we came to C from.
So I've decided to use the history. The difference between this problem and what's described in the tutorial is that A and B don't belong to the same composite state (they only belong to the same state machine). I can't simply declare "has_xxx_history" in the outer state like it's done in the tutorial.
If you want to transition to either state_A or state_B from state_C based on history, I'm afraid putting state_A and state_B in the same direct or indirect outer state is your only option. That's how history works. In your example, it seems it would be possible to put state_A and state_B into a new outer state state_X and transition to state_X with deep history, no? Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.

Hi Andreas,
If you want to transition to either state_A or state_B from state_C based on history, I'm afraid putting state_A and state_B in the same direct or indirect outer state is your only option. That's how history works.
Thanks, that's what I needed to know, I guess... At first I thought it could work without putting the states in some outer state.
In your example, it seems it would be possible to put state_A and state_B into a new outer state state_X and transition to state_X with deep history, no?
Yes, it works fine with the outer state, just like it's explained in the tutorial. I think I'll have to revise the layout of my state machine. Thanks again for the explanation.
participants (2)
-
Andreas Huber
-
Vlad Orlov