Re: [Boost-users] [1.44 MSM meta state machine] accessing objects fromactions
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-...).
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
Thanks Christophe,
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?
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
ah, passing the pointer in the on_entry method. That's a neat trick.
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. That would be great. "How do I actually _do_ something with the state machine" was a question that was always on my mind. Static/global variables are absolutely out of the question.
list is still pretty long so I hope this solution will be ok for the time being. Yes, certainly. It also addresses the question of how a substate machine can remain reusable.
Many thanks Hajo
Sorry for answering so late, hard week ;-) 2010/10/26 Hajo Kirchhoff <mailinglists@hajo-kirchhoff.de>:
Thanks Christophe,
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?
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
ah, passing the pointer in the on_entry method. That's a neat trick.
Actually it's not as neat as I would like so I'll come back to this in future. The best would be some variadic list of super state machines.
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. That would be great. "How do I actually _do_ something with the state machine" was a question that was always on my mind. Static/global variables are absolutely out of the question.
Apart from actions, what other "howto" would you like to see? I'm very interested in making the doc better. Regards, Christophe
participants (2)
-
Christophe Henry
-
Hajo Kirchhoff