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?