jkrumow/TBStateMachine

Question - parent state

Closed this issue · 6 comments

Hi,
How can I create a parent state which listen to event, transition its substates and still listen to the same event.

According to the UML specification events can only be handled on one level of a nested hierarchy at a time. Handling an event starts always at the bottom of the hierarchy. That means: either an active substate will handle the event or the event it will bubble back up the hierarchy so a parent state can handle it.

So if you want to implement the behavior you have mentioned you could create a parent state which handles an event "foo" and then emits another event "bar" which will be handled by one of the substates and perform the transitions.

Hi, thanks for answering, what if I do something like this?
[parent addHandlerForEvent:"GoToChildA" target:nestedA];
[parent addHandlerForEvent:"GoToChildB" target:nestedB];

and then, fire "GoToChildA" and "GoToChildB" consecutively.

Will it enter to nestedA and then to nestedB or stay on nestedA since the event "GoToChildB" won't be listened?

Ah, ok. The event is always handled by the source state of the transition. Since the transitions connect nestedA and nestedB the events must be handled by them:

[nestedB addHandlerForEvent:@"GoToChildA" target:nestedA];
[nestedA addHandlerForEvent:@"GoToChildB" target:nestedB];

In this case parent would only be a container for the sub states.

But on your TBSMStateMachineNestedTests.m file you have this example:

 // local transitions
[b addHandlerForEvent:TRANSITION_8 target:b22 kind:TBSMTransitionLocal];

where b22 is a substate of a substate of b state.
so b is not only a container.

Oh yes. That is a local transition. This means that whenever b receives event TRANSITION_8 the active substate will be b22, no matter which other substate is active at the moment (b22, b1, b311, b312, etc.)

So of course, if you want to have two universal events which make parent switch to nestedA or nestedB at any time you could do it like that:

[parent addHandlerForEvent:@"GoToChildA" target:nestedA kind:TBSMTransitionLocal];
[parent addHandlerForEvent:@"GoToChildB" target:nestedB kind:TBSMTransitionLocal];

So I guess I've found the solution myself than (: