Boost logo

Boost Users :

Subject: Re: [Boost-users] [MSM] What's the easiest way to share data between states in a Boost.MSM state machine?
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2012-04-26 15:25:04


>As the subject indicates, I'm trying to find the best way to share data between states in a MSM state machine.

>My first attempt has been to let each sub-machine and state inherit from a common base class, e.g.:

>struct MyStateMachine_ : public msm::front::state_machine_def<MyStateMachine_,CommonBaseClass>

>My idea is to add a reference to some shared data in the base class, making it easy to access the shared data from any state.

>The shared data reference must be passed to the base class.

>Questions:

>1. Is it possible to pass constructor parameters to the common base class' constructor? I have tried different options without >success, it seems that the default constructor with no arguments is the only option.

A state machine and states do need a default-constructor because of an implementation detail, which is unfortunate, but you have the possibility to create a state with your own arguments and replace the default one by yours (http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s05.html#d0e2417). Then you can call your base class constructor. You can also recurse for submachines. However I doubt you want this because if you have many states, it becomes tedious.

>2. If 1. is not possible, what is the best way to initialize the shared property correctly? For example an easy method to iterate over

>all defined states? (not only the active ones). I have tried to iterate over all states with get_state_by_id, but this method does not >enter sub-machines' states.

I answered a similar question some time ago on stackoverflow (http://stackoverflow.com/questions/8288713/how-to-visit-all-states-in-boost-meta-state-machine/8332220#8332220). This allows you to iterate over all the states and call a method they all support. Then, you have the possibility to make the submachine iterate over its states the same way in this call.

>3. In general, what is the preferred way of implementing shared data between state classes in Boost.MSM? It would have been >natural to store the data in the root state, but I can't see that there is an easy way to get access to the root FSM. (only the "nearest >parent" FSM in the hierarchy is passed to the various event handler methods).

It is possible for any state to access data from any other state of the same state machine but usually the easiest is to host common data inside the state machine. All actions and guards get the "nearest" fsm as a parameter.

It has already been requested a few times that MSM provides you with not only the nearest but the parent state machines up to the node. It will be done, but for the moment there is no easy way, so you will need to make your submachines "forward" data to their subsubstates upon visiting. In the previous link I have a Visit class calling resize() on all states. You can easily modify it to call say, set_data(...), then make your submachine use the same method inside set_data to forward to the subsubstates. You can also use the constructor method I pointed to in 1.

>Regards,

>Tommy

HTH,

Christophe



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