Subject: Re: [boost] [MSM] exit_ps stuks in case of outer state machine uses Row with event to event base class
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2011-06-14 16:55:12


> Hi Christophe and All
>
> after splitting our complicated several level deep contained state
> machines to small run-time instances.
> I have to use feature Event Hierarchy
> (http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s02.html#d0e1176)
> which is really cool.

Great :)

> But this feature in combination with pseudo exits state, breaks the
> pseudo exit state functionality and the
> pseudo exit state is entered but never left.
>
> I have made a small example where the problem is reproduced see
> attachment. (the file name is misleading was just lazy to rename it
> something more appropriate)
>
> Here is the output of the execution :
>
> entering: Idle MS1_
> leaving: Idle
> Action: MS1::onEvent1
> entering: RunningStateMachine MS1_
> entering: RunningStateMachine::PseudoEntry1
> leaving: RunningStateMachine::PseudoEntry1
> entering: Inner1 RunningStateMachine_
> entering: InnerState11
> leaving: InnerState11
> leaving: Inner1

----> look here, PseudoEntry1

> entering: RunningStateMachine::PseudoEntry1

Hi Richard,

I think it's because there are a few mistakes in your state machine:
1.
You are in PseudoEntry1, not PseudoExit1, so it won't work:
_row < Inner1 , event3 , PseudoEntry1
>

should probably be:

_row < Inner1 , event3 , PseudoExit1
>

2. The outside event (event4) must be constructible from the inside event
(event3). As stated
there(http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s02.html#d0e942),
it requires a copy-constructor to build an event4 from event3. You need to
change event4 to:
  struct event4 : public baseEvent
  {
      event4(){}
      template <class Event>
      event4(Event const&){}
  };

Why it compiles is still a mystery to me, to be honest. I would expect the
compiler to complain about not being able to construct event4 from event3. I
need to have a look at this.

3. This one is my fault and might be a problem for you as you seek
performance. I think we discussed this but I forgot it in the doc. Pseudo
exits require the message queue and you deactivated it with:
typedef int no_message_queue;

4. It's probably just the example here but just in case you created a
transition conflict which is unlikely to please you between:

      _row < RunningStateMachine::exit_pt< RunningStateMachine::PseudoExit1
> , event4 , Idle >
and:
      Row < RunningStateMachine, baseEvent, RunningStateMachine >

In this case, event4 is a baseEvent and both transitions are conflicting.
MSM will take the latest defined, which is correct but probably not what you
want.

Now it should work. I tried to replace event4 with baseEvent (and add the
constructor) and all works as advertised.

Regards,
Christophe