|
Boost : |
Subject: Re: [boost] [msm]exit pseudo state and event
From: Takatoshi Kondo (redboltz_at_[hidden])
Date: 2011-07-03 23:53:27
On Sat, Jul 2, 2011 at 1:55 AM, Christophe Henry
<christophe.j.henry_at_[hidden]> wrote:
>> Hello,
>>
>> Boost.Msm supports the UML2.0 feature "exit pseudo state".
>> Here is a description about exit pseudo state in the document.
>>
>>> exit_pseudo_state
>>>
>>> Basic type for exit pseudo states. Exit pseudo states are an
>>> predefined exit from a submachine and connect two transitions.
>>> The first argument is the name of the event which will be
>>> "thrown" out of the exit point. This event does not need to
>>> be the same as the one sent by the inner region but must be
>>> convertible from it. The second argument is needed if you
>>> want your state (and all others used in a concrete state machine)
>>> to inherit a basic type for logging or providing a common behavior.
>>>
>>> template<class Event,class Base =
>>> default_base_state, {
>>> }
>>> class SMPtrPolicy = no_sm_ptr>
>>> exit_pseudo_state {
>>> }
>>
>> Why the 1st template parameter "Event" is needed?
>
> It is needed for implementation reasons. Actually it might not be needed if
> I decided to hardcode an event (like "none" as you later suggest).
OK.
>> Consider the attached diagram "11_ExitPointEvent.png".
>>
>> IMHO, the Exit2 is typical usecase of exit pseudo state.
>> Outgoing transition from exit pseudo state shouldn't have
>> any events and guards.
>> The point is how to divide the concerns.
>> When we design the Sm1, we can depend only State1,
>> State1::Exit1, State1::Exit2 and State2.
>> And we shouldn't depend on which event triggers the
>> transition to pseudo exit state.
>> It's State1's concern.
>
> True. OTOH, letting a submachine decide which event is exiting this
> submachine creates a constraint on the main state machine. The goal of the
> implementation is to remove this constraint.
I agree.
>> To implement that, I pass the "none" as 1st template parameter.
>
> It is acceptable to msm and probably in the spirit of the Standard.
>
>> namespace msmf = boost::msm::front;
>> struct Exit2:public msm::front::exit_pseudo_state<msmf::none> {};
>> (See the attached file 11_ExitPointEvent.cpp)
>>
>> I think it is suitable for the default template parameter.
>
> Maybe (see below).
>
>> The example in the Boost.Msm tutorial document, the usage of
>> exit pseudo state is similar as Exit1 in "11_ExitPointEvent.png".
>>
>> The behavior that I understand is below.
>> In State1
>> 1. Event1 is occurred,
>> 2. Transition to Exit1.
>> 3. Event1 is converted to Event2 (Exit1's template argument).
>> In Sm1
>> 4. Dispatch Event2.
>> 5. Transition to State2.
>> (Entry, Exit action is omitted)
>>
>> Is that right?
>
> Yes.
>
>> I'd like to know why such complicated mechanism is needed?
>> Is the purpose to propagate the event parameter?
>
> As implementer, I allow myself from time to time to ignore the standard
> (implementer's privilege ;-) ) where I feel it forces unacceptable
> constraints on me. This is such a case.
> There are several reasons. One is as you noticed, not to lose the event type
> and even more, data. If an event has some attributes, converting it to
> "none" will lose them. Slicing and subtle bugs in waiting.
>
> The second reason is this extra constraint. It is a constraint coming from
> down in your design. This simply feels wrong to me. The implementation of
> msm allows the writer of the main machine to have less constraints. He can
> decide to write an event convertible from any other event, or to take over
> only data from the inner event. Consider event6 from the tutorial. I could
> write:
>
> struct event6
> {
> event6(){}
> template <class Event>
> event6(Event const& e)
> {
> some_id_ = e.id();
> }
> int some_id_;
> };
>
> The dependency to the submachine is only a weak one.
>
> The third reason is that we would have in our main machine a second-class
> transition. No event, no guard. Which implies no possible transition
> conflict resolution. What if I want to implement an "if/else" mechanism in
> the main machine? Not possible. I will be forced to add a state as target of
> this transition whose sole purpose would be to provide me with a set of
> outgoing transitions implementing my "if/else". But without event data (as
> we would only have "none"), I would not be able to implement every case and
> I will be forced to resort to lesser solutions (like adding attributes to
> the submachine to store event data).
>
> This is a personal choice but these reasons matter to me more than the extra
> complexity added by a template parameter.
> If your taste is the Standard one, it is fine with me, just define "none" as
> event parameter.
In my approach (using none), it is also possible to implement that
"if/else" mechanism.
See the attached file. We can access the "stored" event parameter in
guard functor.
(Use the get_param() instead of get_result().)
Of course some public interface is required in State1_.
There are two different ways of thinking about dependency.
A.
The event that occurs in the sub state machine is submachines concern.
If outside state machine want to know which event is occurred in submachine,
submachine should provide the proper interface.
Of course we can know not only events but also everything occurs in submachine.
For example action result in submachine.(See 12_InsideOutsideInfo.cpp)
B.
Events are the concept separate from state machine (and sub machine).
They exist independent. Hence the mechanism should treat events exceptionally.
My opinion is A. But I can understand B.
What do you think?
> The next point to consider is whether to make "none" a default parameter.
> One one hand, it would make the pseudo exit almost Standard-conform (if we
> ignore the possible on_entry/on_exit handlers which are not foreseen by the
> Standard), on the other hand, someone not knowing this finesse of the
> Standard and providing no event parameter and a normal outer transition with
> an event will be quite surprised to get no_transition handler calls.
> I do not favor forcing bugs on msm users (which qualifies as a "complicated
> mechanism") only to please the Standard.
>
>> Thanks,
>> Takatoshi
>
> Regards,
> Christophe
>
> PS: I just realize this post would be a good addition to a Rationale section
> ;-)
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
Regards,
Takatoshi
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk