
On 19 July 2011 23:16, Christophe Henry <christophe.j.henry@googlemail.com> wrote:
I'm running the attached test program it generates the following output :
entering: Idle MS1_ leaving: Idle Action: MS1::onEvent1 entering: RunningStateMachine MS1_ entering: RunningStateMachine::PseudoEntry1 leaving: RunningStateMachine::PseudoEntry1 entering: Inner1 RunningStateMachine_ entering: InnerState11 FwdGuard: returns:0, event: event5 FwdGuard: returns:0, event: event1 FwdGuard: returns:0, event: event1 FwdGuard: returns:0, event: event5 FwdGuard: returns:0, event: event1 FwdGuard: returns:0, event: event1 FwdGuard: returns:0, event: event5 FwdGuard: returns:0, event: event1 FwdGuard: returns:0, event: event1 FwdGuard: returns:0, event: event5
Hi Richard,
unfortunately, I don't have good news. We are using non-standard, self-made UML features (base event, Defer functor) here so we're moving in uncharted territory.
I believe it is incorrect after state machine entered state InnerState11 . FwdGuard should have been called ones with event5 and than 3 times with event1 and event1 shall have triggered after the first dispatching a no transaction. But this case no trans was triggers on even1 and and the deferred event5 got dispatched even there was no state change for every event1 dispatching.
After thinking about it, I think I will disagree. What you could expect at first would be one call with event5, then with event1, then event5, then event1, then event5 etc. Why? Because we have a transition conflict between the transition: Row < Inner1 , baseEvent , none , ProcessBaseEvent , FwdGuard > and Row < RunningStateMachine, event5 , none , Defer, none >
If you follow the other discussion on this list, there is talk about priority. The Standard says that the most inner transitions have higher priority, so when you want to process event5, the above transition gets tried first and rejects event5. So the transition did not fire. Again, as the Standard says, we continue until one fires. We then try the second one, which has no guard, so it fires and defers the event5.
Then comes event1, the above transition rejects, processing of event1 stops here. We try again the deferrd event5, and you see it again. And again it is deferred. And again and again. So, what you COULD expect would be: FwdGuard: returns:0, event: event5 FwdGuard: returns:0, event: event1 FwdGuard: returns:0, event: event5 FwdGuard: returns:0, event: event1
But there is a second factor here, a conflict between an event (event1) and its base state. I can only advise you to avoid this. I see this as the fsm equivalent of Meyer's tip "make base classes abstract". In our case, we get rows added by msm in your SM1 transition table for events present in RunningStateMachine's table: RunningStateMachine: event1 (comes from _row < PseudoEntry1 , event1 , Inner1 >) RunningStateMachine: baseEvent (comes from Row < Inner1 , baseEvent , none , ProcessBaseEvent , FwdGuard >)
This means event1 is in conflict with his base class. MSM tries both transitions, with event1 and baseEvent, as with any conflict. Interestingly, both map to the one from baseEvent, so it is called twice, which gives you what you see.
So, what should msm do? Remove the transition with eventBase? No because base events would not work for submachines any more. Remove the transition with event1 because eventBase is present? Also no, because you would only get the submachine called with baseEvent (would be slicing, again, see Meyer).
So, I need to think about it, but I really see no way to make this work :(
this breaks our code execution completely :(.
I understand it's bad. All I can suggest you is: - do not create conflicts between an event and its base. I don't see how this could be a right design. - if you don't want event5 to come haunt you forever, stick to the UML conform deferring inside a state unless you really know you will get no transition conflict.
Ok if I use UML like definition for the event deferral than at least event 5 is not getting dispatched each time thanks for that. And actually I can leave with the situation that even1 is dispatched 2 times it only happens when no trans is taken in sub state machine so than it is not hurting. What I find disturbing that in this case the No Trans in not getting called ? Is it possible to fix at least this ?.
Sorry, not to be able to help more.
No problem you are a great help to us !.
Regards,
Christophe
Cheers Richard
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost