Boost logo

Boost Users :

Subject: [Boost-users] [statechart] history in the different state hierarchies
From: Vlad Orlov (monsta_at_[hidden])
Date: 2012-06-27 10:10:49


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?


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net