>Then... I think we've found a bug?
>I'm attaching a version of
your tutorial as a test case of this bug.
>
>The bug can be reproduced by:
>- Creating a
functor action (FA) that process an event (E)
>- Creating an state machine
(SM) and a submachine (SSM)
>- SM and SSM should call FA in some place of
their transition table
>- E should not be present in the SSM (it can or
not be in SM).
>
>If the FA is called
by the SM, everything works as expected:
>- no_transitions if E is not in
SM
>- the correct transtion if E is in SM (E is not in SSM)
>
>But if the FA is called bu the SSM, nothing
happens:
>- no_transition is not called if E is not in SM
>-
transition is not executed is E is in SM
>- ok, I've just checked when E
is in an orthogonal region of SM...
>
>
>Please, let
me known if it is a real bug and if a patch is easy or not (may be I can
help...?).
>I think that if we fix this bug, then the ugly pointer
solution can be removed!
>;-)
Yes, I oversaw the valid case of no_transition
needing a call when process_event is called on the submachine object directly. I
fixed this in the trunk (rev. 77840) so it should now work.
Note that after your last processing of NextSong,
no_transition of the Playing (not player) fsm is (now correctly) called, but you
are NOT in ErrorMode because error_found is not known in the submachine. If you
want to move to ErrorMode in the outer you will need either the ugly
pointer solution, or UML-conform, a pseudo exit.
However, the UML-conform way is going to cost you a
bit. You'll need to add a second region to the submachine, with a pseudo-exit if
error_found is generated. Then, as in the outer fsm you will be in the first
region (not where ErrorMode is), you'll need to reprocess this event to the fsm,
so that the second region has a chance to get it (through, for example, an
internal transition in Playing).
Using the provided example, I add 2 states in the
submachine, PlayingAllOk and PlayingError, the latest being a pseudo exit
state, then I add a transition in the submachine:
Row < PlayingAllOk, error_found ,PlayingError >
Finally, to reprocess the event, an internal
transition (though one could argue, it is not UML conform, replace this by a
transition to Playing or any state of the first region if you
prefer:
Row < Playing::exit_pt<Playing_::PlayingError> , error_found , none
, ActionErrorFound , none >
Now, the second region will get it and you are in
ErrorMode. But whether it is less ugly than a pointer is a matter of taste
;-)
HTH,
Christophe