Boost logo

Boost Users :

Subject: Re: [Boost-users] [MSM] Unable to retrieve correct value of attribute of a state from within actions. (Possible Bug?)
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2013-02-24 15:41:08


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 <class Evt, class Fsm, class State>
> 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<BOOST_MSM_EUML_STATE_NAME(state1)>() will give you a reference to
the real state1).

I'm not very happy with this. To replace some parens, I pay with more
macros. If I could redo it, I'd not take this review recommendation.

<snip code>
> 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


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