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: Deniz Bahadir (deniz.bahadir_at_[hidden])
Date: 2013-02-25 05:08:55


Hi Christophe,

>> // 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.
[snip]
> 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).

Thank you, that clarifies a lot.

> 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).

You are missing a '&' or '*' behind the macro, but you are right, that
does what I wanted in the first place.

>> fsm.process_event(event1); // this really is event1!
[snip]
> 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 ;-)

Just for final clarification three more questions:

1.
You mean, that from within the "operator()" of an action I am only
allowed to use the parameters for accessing states, events, and the FSM
internals? (Neither "event_", "source_", "target_", "fsm_", nor
accessing the dummy-instances directly.)

This is now clear for the current event, current source- and target
state as well as for all other states of the FSM (by accessing them with
"get_state").

2.
However, how to access other events than the current one?

It seems to work as I did before (by accessing the "dummy"-instance of
the event), but if you do not recommend it, maybe there is a better
solution?
(I need to access all events directly to initialize their event-number
attributes from within the FSM's entry-action.)

3.
And all the underscore-accessors "event_", "source_", "target_", "fsm_"
are only allowed to be used from within the transition table?

Maybe you could emphasize the real usage in the documentation, so that
nobody misuses it (like I did).

Thanks,
Deniz


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