Boost logo

Boost Users :

Subject: Re: [Boost-users] [1.44 MSM meta state machine] accessing objects fromactions
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2010-10-25 15:54:41


> Currently my queue object is a member of the state machine itself, so I
> can write
>
> struct Send_ : public msm::front::state_machine_def<Send_>
> {
> string m_next_line_to_send;
> socket m_socket;
> string get_next_send_line();
> };
>
> and in my a_send action
> void operator()(Event &const &evt, Fsm &fsm, S&, T&)
> {
> fsm.m_next_line_to_send=fsm.get_next_send_line();
> fsm.m_socket.async_write(fsm.m_next_line_to_send);
> }
>
> This works well as long as I am not using sub-statemachines.
>
> Here is my problem:
> I would like to use a substate machine for the actual sending. The main
> state machine has the states Disconnected, Working, Error, Shutdown. The
> Working state should actually be a substate machine.
>
> The problem is, when a_send gets called by the substate machine Working,
> the fsm object is of type Working.

Correct. There is no "fsm call stack" yet. This gets complicated if
you have a submachine of a submachine of ...
For the moment I don't have this.

> How can I access the member variables of the parent of a substate
> machine? Or is there a better way of accessing the objects the state
> machine should work with from actions?

For the moment, all we can do is adding a pointer to the main fsm's
data in the submachine. It is less elegant with the 1.44 than the
coming 1.45:
With 1.44 (for example inside the on_entry method of Send_):
Send_::Working& w = fsm.get_state<Send_::Working&>();
w.data = &fsm.data; // w.data is a pointer

True, this is not really nice. With the upcoming 1.45 (or trunk for
the moment), you could use the new constructors:
Send myfsm (msm::back::states_ << Working(data) ); //data being
externally defined and Working_ having a corresponding constructor

But this won't work for your case where data is contained in Send_
(and therefore does not exist at the time of construct). You can
however reuse the same syntax with the new set_states method:
Replace the version with get_state by:
fsm.set_states(msm::back::states_ << Working(fsm.data)); //data being
defined in Send_ and Working_ having a corresponding constructor.
The whole explanation is there
(http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s05.html#backend-fsm-constructor-args).

> The tutorial explains state machines very nicely with the example of a
> CD player. But all the actions are empty and nowhere is explained, how
> you would actually access a CD player member variable or other such
> object so that you could actually manipulate the player to do something.

Seems that I need to improve my doc here. It's too late for the 1.45
but I'll do it for the 1.46.

I agree that this is still not perfect and it's on my list but the
list is still pretty long so I hope this solution will be ok for the
time being.

Regards,
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