Whenever a state machine is in a composite or orthogonal state, multiple states are active at the same time: the composite/orthogonal state itself (“parent”) and one or more of its substates (“children”).
When a micro step is executed e.g. triggered by an event, then the state machine checks each active state for a transition that can be taken, based to the event(s) received and the guard conditions on the transitions. As soon as a matching transition is found, it is taken immediately, and its target state becomes active. This will be done for each active state, i.e. all orthogonal regions are processed. Since the first match always wins, it is crucial in which order states are checked and how you can control that. In an orthogonal state, active substates are checked according to the order of their regions. The order of top level regions is displayed in the region itself. Child regions in a state are arranged either from left to right or from top to bottom depending on the visual region alignment.
Whether the parent state or its child state(s) are checked first, you can specify by setting either the
@ParentFirstExecution
annotation or the
@ChildFirstExecution
annotation in the statechart’s definition section. If the definition section contains none of these annotations, @ChildFirstExecution
is assumed. Whichever variant you choose, it is statechart-global and thus applies to
all composite and orthogonal states.
Please note: Specifying parent-first or child-first execution pertains to checking for matching transitions only, not to entry and exit actions. Entry actions are always executed from the outside to the inside, i.e., on the parent state first and after that on the children. Exit actions are executed in reverse : in child states first, followed by the parent state.
Parent-first versus child-first execution are best explained by a couple of examples.
Example 1a:
Consider the statechart in the
figure below. Composite state
A and its substate
B are active, and the @ChildFirstExecution
annotation has been specified in the definition section.
Child-first, example 1a, before transition
When event e occurs, the state machine considers child state B first, finds a matching transition, and thus immediately proceeds to state D, see the figure below.
Child-first, example 1a, after transition
Example 1b:
Consider the statechart in the
figure below. Composite state
A and its substate
B are active, and the @ParentFirstExecution
annotation has been specified in the definition section.
Parent-first, example 1b, before transition
When event e occurs, the state machine considers parent state A first, finds a matching transition, and thus immediately proceeds to state C, see the figure below.
Parent-first, example 1b, after transition
The following examples are somewhat more complex. The statechart used in the examples defines the integer variables m, n, o, p, q, and r. Initially, they are all set to 0. Reactions in states A and B set these variables to non-zero values on certain conditions:
This is useful to understand which actions are performed (or not performed) and in which order.
The reactions in composite state A are as follows:
entry / m = 1
e / n = 1
exit / o = 1; r = 1
The reactions in substate B are as follows:
entry / m = 2
e / p = 1
exit / q = 1; r = 2
The settings above are the same for all subsequent examples, except for example 4.
Example 2a:
Consider the statechart in the
figure below. Composite state
A and its substate
B are active, and the @ChildFirstExecution
annotation has been specified in the definition section.
Child-first, example 2a, before transition
In this scenario, A and B have just been entered, and their entry actions have already been executed. Since the execution order of entry actions is independent of parent-first/child-first execution order and always proceeds from outer states to inner states, the entry action of A is executed first and sets variable m to 1. After that, the entry action of B is executed and overrides variable m with a value of 2.
When event e occurs, the state machine considers child state B first, finds a matching transition, and thus immediately proceeds to state D, see the figure below. The state machine executes the exit actions of A and B after these states have become inactive.
Child-first, example 2a, after transition
It is worth having a look at the variables and understand what has happened. When the state machine is in state D, the variable values are as follows:
Variable | Value |
---|---|
m | 2 |
n | 0 |
o | 1 |
p | 0 |
q | 1 |
r | 1 |
We have already seen why m is 2.
Variable
n would be set to 1 by a reaction in
A, triggered by event
e. However, since the statechart is in child-first mode, and the
e event triggers an immediate transition from
B to
D, it is no surprise that
n remains 0. The composite state is left before
e / n = 1
in
A gets any chance to be executed.
However,
p is also 0, although
B has priority over
A, according to child-first execution. The reason is that an active state is checked for possible transitions
first, and reactions within the state are executed
second. This can lead to certain reactions not being executed at all. In this case, checking for possible transitions after receiving
e finds the transition from
B to
D. This transition is executed
immediately. “Immediately” means that
B is left straight away. No further action will be done on it, and consequently the reaction
e / p = 1
fails to be executed.
The only exception to the rule is are exit actions, because they are always executed when the corresponding state becomes inactive. That’s why the variables o, q, and r all have a value of 1: They have been modified in the exit actions of A and B. The execution of exit actions starts with the inner-most state and then proceeds to the outside. Here, the exit action of B has set q to 1 and r to 2. After that, the exit action of A has set o to 1 and has overridden r with 1.
Example 2b:
Consider the statechart in the
figure below. Composite state
A and its substate
B are active, and the @ChildFirstExecution
annotation has been specified in the definition section.
Parent-first, example 2b, before transition
In this scenario, A and B have just been entered, and their entry actions have already been executed. Variable m has a value of 2, as explained in example 2a.
When event e occurs, the state machine considers parent state A first, finds a matching transition, and thus immediately proceeds to state C, see the figure below. The state machine executes the exit actions of A and B after these states have become inactive.
Parent-first, example 2b, after transition
The variable values are the same as in example 2a and essentially for the same reasons: Entry and exit actions are executed in the same order, and any reactions on event e are not executed at all.
Example 3a:
Let’s make a small change now to the
statechart in example 2a and add a guard condition
[p == 1]
to the transition
B → D, see the
figure below. Please note that the @ChildFirstExecution
annotation has been specified in the definition section.
Child-first, example 3a, before transition
Event e causes the following to happen:
@ChildFirstExecution
annotation, state
B is checked first for any transitions to be taken. However, since
p is 0, the guard condition of
B → D is not fulfilled, and the transition is not triggered.
The figure below shows the result.
Child-first, example 3a, after transition
The variables are set as follows:
Variable | Value |
---|---|
m | 2 |
n | 0 |
o | 1 |
p | 1 |
q | 1 |
r | 1 |
Example 3b:
This example is here for the sake of completeness only. It is like
example 3a, but with the @ParentFirstExecution
annotation in effect.
The state machine reacts to an event e just like the one in example 2b: Since the parent is checked first and a matching transition from A to C is found, that transition is taken immediately, without considering B in any way, except for executing its exit action.
Thus in state C the variable values are as follows:
Variable | Value |
---|---|
m | 2 |
n | 0 |
o | 1 |
p | 0 |
q | 1 |
r | 1 |
Example 4:
Last but not least, here’s an example that is left as an exercise to the reader: What is the next state in the statechart below after event e arrives? To find out whether your guess is correct, recreate the example and check it with the interactive statechart simulator.
Child-first, example 4, before transition