Hi Deniz,
Using Boost.MSM with eUML I tried to access the attribute of a state from within an action. However, the value is not what I expected when accessing the attribute of the state given as argument to the action. (It seems to be the default-parameter.) If I access the state directly (by name) and retrieve the value from it, it is set correctly as expected.
Could it be that an action gets its arguments as copies?
No, unless there is a recent bug, but I really don't think so. Copies in MSM are something we want to avoid for performance reasons.
// The attribute: BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int, Number) BOOST_MSM_EUML_ATTRIBUTES((attributes_ << Number), NumberAttr) // An event containing the attribute: BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(event1, NumberAttr) // Two states with attributes: BOOST_MSM_EUML_STATE((no_action, no_action, attributes_ << Number), state1) BOOST_MSM_EUML_STATE((no_action, no_action, attributes_ << Number), state2)
// Entry-action which initializes the attributes: BOOST_MSM_EUML_ACTION(init_events_and_states) { template
void operator()(Evt const&, Fsm&, State&) { event1.get_attribute(Number) = 100; state1.get_attribute(Number) = 1; state2.get_attribute(Number) = 2; }; };
Ouch! I admit I didn't think about this use case. This is what happens when
an author tries to hide implementation details ;-)
event1, state1 and state2 are really just "lies".
eUML is simply some syntactic sugar on top of the functor front-end. These
variables are only here because in the review, several people complained
that you had to write in the stt something like State1() + Event1() ==
State2().
state1 simply is a dummy variable, all I want from it is its type. Of
course, one instance exists, but normally, one does not care.
So, there is no copy but msm takes the type of state1 and create its own
instance (though you still have the possibility to copy from an already
existing instance).
What you are allowed to use are the template parameters: source state,
target state, event, and fsm (on which, if you call fsm. template
get_state
fsm.process_event(event1); // this really is event1!
As you can see, the attribute-values of "event1" and "evt" are the same. However, the attribute-values of "state1" and "source" differ although they should be the same, too. (The same applies to "state2" and "target".)
As you process event1, you really are changing the dummy instance, so you get the same as if you used the event in the action. Normally, you shouldn't care because events are temporary variables. I don't recommend using this trick ;-) States differ, as explained above. I hope I could clarify this. Cheers, Christophe