[StateChart] Accessing machine and state members from within state constructor

Hello, I'd like to outsource some common functionality into a base state which needs to access some member variables from the state machine or from its direct context. I've managed to do exactly this in the constructor of the inherited class but not inside the constructor of the base class. I believe I am missing some bits here. Thanks in advance -Andre Code: #include <boost/statechart/event.hpp> #include <boost/statechart/state_machine.hpp> #include <boost/statechart/state.hpp> #include <boost/statechart/simple_state.hpp> #include <boost/statechart/transition.hpp> #include <boost/statechart/custom_reaction.hpp> #include <iostream> namespace sc = boost::statechart; // event definition struct EvReset : sc::event< EvReset > {}; // forward definition struct Active; // starting state struct State1; // define FSM struct TestFsm : sc::state_machine< TestFsm, Active > { TestFsm() { std::cout << "Start TestFsm.\n"; fsmValue = 0; std::cout << "value: " << fsmValue << std::endl; } ~TestFsm() { std::cout << "Shut down TestFsm.\n"; } public: int fsmValue; }; struct Active : sc::state< Active, TestFsm, State1 > { Active(my_context ctx) : my_base( ctx ) { std::cout << "Start Active state!\n"; outermost_context().fsmValue++; stateValue = 0; std::cout << "value: " << outermost_context().fsmValue << std::endl; } ~Active() { std::cout << "Leave and desctruct Active state!\n"; } public: int stateValue; typedef sc::transition< EvReset, Active > reactions; }; template< class MostDerived, class Context > struct StateBase : sc::state< MostDerived, Context> { typedef sc::state< MostDerived, Context> base_type; typedef typename base_type::my_context my_context; typedef StateBase my_base; StateBase( my_context ctx ) : base_type( ctx ) { std::cout << "StateBase cst" << std::endl; // critical section outermost_context().fsmValue++; // access member of FSM (outermost context) ctx().stateValue++; // access member in direct context } }; struct State1 : StateBase< State1, Active > { State1(my_context ctx) : my_base( ctx ) { std::cout << "State1 cst" << std::endl; outermost_context().fsmValue++; std::cout << "value: " << outermost_context().fsmValue << std::endl; }; ~State1() {}; }; int main() { TestFsm myFSM; myFSM.initiate(); return 0; }

StateBase( my_context ctx ) : base_type( ctx ) { std::cout << "StateBase cst" << std::endl; // critical section outermost_context().fsmValue++; // access member of FSM (outermost context) ctx().stateValue++; // access member in direct context
The above line sould be: context<Active>().stateValue++;

On 07/11/2012 01:19 PM, Igor R wrote:
StateBase( my_context ctx ) : base_type( ctx ) { std::cout << "StateBase cst" << std::endl; // critical section outermost_context().fsmValue++; // access member of FSM (outermost context) ctx().stateValue++; // access member in direct context
The above line sould be:
context<Active>().stateValue++;
Hi Igor, what you suggested works from within the constructor of State1 but Active is not known to the constructor of the base class. And that's exactly the problem with outermost_context() too. Thanks again, -Andre

Andre Puschmann <andre.puschmann <at> tu-ilmenau.de> writes:
StateBase( my_context ctx ) : base_type( ctx ) { std::cout << "StateBase cst" << std::endl; // critical section outermost_context().fsmValue++; // access member of FSM (outermost context) ctx().stateValue++; // access member in direct context }
Please try ... StateBase( my_context ctx ) : base_type( ctx ) { std::cout << "StateBase cst" << std::endl; this->outermost_context().fsmValue++; this->template context<Active>().stateValue++; } ... and let me know whether that works for you. Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.

On 07/11/2012 10:13 PM, Andreas Huber wrote:
Please try ...
StateBase( my_context ctx ) : base_type( ctx ) { std::cout << "StateBase cst" << std::endl; this->outermost_context().fsmValue++; this->template context<Active>().stateValue++; }
... and let me know whether that works for you.
Works like a charm, excellent. Thanks. And this->template context<Context>().stateValue++; lets me access the templated state. Thanks Andreas and Igor BR -Andre
participants (3)
-
Andre Puschmann
-
Andreas Huber
-
Igor R