Orthogonal Regions |
Describes how orthogonal regions are created, how they entail the concept of fork and join transitions and how this all functions.
Systems controlled through state machines can often be de-composed into largely separate sub-systems. It is definitely a reasonable strategy to model the sub-systems with separate state machines and coordinate them through events.
However the state chart formalism provides the possibility to model such systems within the same state machine diagram through the concept of orthogonal sub-regions. This allows to keep the system description on the visual level.
An orthogonal sub-region is an additional separate region within a composite state. Entering the composite state enters all sub-regions collectively. The fundamental extension is that the state machine may now be in multiple states at the same time. This introduces a further level of possibilities for transition source and target states within the state machine.
The below state diagram has a state with two orthogonal regions and shows a few typical cases for transitions.
All transitions that target the composite state ultimately bring the state machine into a state where two states are active at the same time:
If the transition forks and ends at individual sub-states, the intended states to enter are obvious. If the transition ends at the composite state border, the initial states of the involved sub-regions are entered. And finally a transition, that explicitly targets only a subset of the sub-regions while leaving other sub-regions unspecified, is executed by entering the initial state for each unspecified sub-region and entering the defined states for all directly targeted sub-regions.
Similar situations arise for transitions that leave composite states with orthogonal sub-regions:
If the transition joins from the individual sub-states it will be considered as reached when all of these sub-states are active. The transition can then execute if the corresponding event arrives or the guard condition is fulfilled. If the transition starts on the composite state border, it will be considered as reached if the state machine is in any configuration of states of the orthogonal sub-regions. And finally, if only some of the orthogonal sub-regions are defined as source states while other sub-regions are unspecified, the transition is considered as reached when the configuration of defined sub-states matches while the other unspecified sub-regions are not considered and may be in any state.
Transitions may also be both join and fork in case the source state and the target state are composite states with orthogonal sub-regions.
As all these transitions enter or leave multiple states, the state machine also executes the corresponding entry and exit actions of the sub-states when the transition is executed. The sequence of the sub-regions in the code determines the sequence how entry actions are executed. Exit actions are executed in reverse order.
Orthogonal sub-regions of a composite state are added through multiple Region..EndRegion statement blocks, embedded within the State..EndState statement pair of the composite state, after any Transition statements of the composite state.
The Transition statement accepts arrays of state names instead of a single state name, in order to specify individual sub-states within orthogonal sub-regions. Arrays of state names can be passed in for both the source and the target state of the transition.
The source state must be specified in case it references a sub-state of the composite state where the transition belongs to.
StateMachineTemplate t = new StateMachineTemplate(); t.Region(StateA, false); t.State(StateA, null, null); t.Transition(Transit1, new string[] {StateB1B, StateB2B}, Event1, null, null); t.Transition(Transit2, StateB, Event2, null, null); t.Transition(Transit3, StateB1B, Event3, null, null); t.EndState(); t.State(StateB, null, null); t.Transition(Transit4, new string[] {StateB1B, StateB2B}, StateC, Event4, null, null); t.Transition(Transit5, StateC, Event5, null, null); t.Region(StateB1A, false); t.State(StateB1A, null, null); t.Transition(Transit99, StateB1B, null, null, null); t.EndState(); t.State(StateB1B, null, null); t.Transition(Transit6, StateC, Event6, null, null); t.EndState(); t.EndRegion(); t.Region(StateB2A, false); t.State(StateB2A, null, null); t.Transition(Transit98, StateB2B, null, null, null); t.EndState(); t.State(StateB2B, null, null); t.EndState(); t.EndRegion(); t.EndState(); t.State(StateC, null, null); t.EndState(); t.EndRegion();
In case a sub-state of an orthogonal sub-region is itself again a composite state, then all entry actions of this composite state are executed before any entry actions of the next sibling orthogonal sub-region.
Unlike the other transitions, Transit4 explicitly specifies the source states StateB1B and StateB2B to indicate that the transition starts from these sub-states.
Note |
---|
The OMG UML Specification describes the possibility to build transitions as a directed acyclic graph with multiple intermediate vertices including choice and junction vertices, named compound transitions. While this provides an enormous flexibility and comfort for the possibilities to define transitions, there are also downsides like the undefined precedence of execution in case of conflicting transition paths. StaMa provides a rigorous reduced model, where each transition has a single event signal and guard condition per transition but still allows to specify source and target states of orthogonal sub-regions. |
Events are distributed separately to orthogonal sub-regions.
Each orthogonal sub-region individually and separately evaluates the event. In case the orthogonal sub-regions have reached transitions that are triggered through the same event signal, these transitions are reported to the state machine execution logic, and after complete traversal of the entire state machine these transitions are excuted within the same run-to-completion step. The order of execution of the transitions is according to the order of the orthogonal sub-regions in the code.
Transitions local to a single orthogonal sub-region may still reference source states from sibling, "external" orthogonal sub-regions. Local means in this case that the transition is aggregated at a state within a region.
At first sight this source state topology could be interpreted that it should cause the least common ancestor to be elevated to the common ancestor region of all source states. Elevating the least common ancestor would in turn cause that the enclosing composite state would be left when the transition is executed and re-entered with the effect that all sub-regions are left and re-entered. However this is visually somewhat unexpected as none of the transition segments crosses the enclosing composite state.
StaMa defines the semantic for such transitions as follows: The transition is considered reached, if all source states are active, however the least common ancestor of the transition is calculated from the subtree of the source states that are offspring of the state where the transition is aggregated, with the target state.
If the transition aggregation state and the target state are within the same orthogonal sub-region, then the additional source state acts only as a guard for the transition.
Below state diagram shows such a transition:
StateMachineTemplate t = new StateMachineTemplate(); t.Region(StateA, false); t.State(StateA, null, null); t.Region(StateA1A, false); t.State(StateA1A, null, null); t.Transition(Transi20, StateA1B, Event1, null, null); t.EndState(); t.State(StateA1B, null, null); t.EndState(); t.EndRegion(); t.Region(StateA2A, false); t.State(StateA2A, null, null); t.Transition(Transi11, new string[] {StateA1B, StateA2A}, StateA2B, Event2, null, null); t.EndState(); t.State(StateA2B, null, null); t.EndState(); t.EndRegion(); t.EndState(); t.EndRegion();
When the state machine starts, it enters StateA1A and StateA2A.
Sending Event2 in this situation will not have an effect, as the transition of Event2 is guarded with StateA1B.
Sending Event1 in this situation will execute the transition from StateA1A to StateA1B. The transition of Event2 is now reached.
Now sending Event2 will execute the transition from StateA2A to StateA2B but won't leave StateA1B or StateA in its entirety.