State
States are fundamental building blocks for the UML representation of a finite-state machine (FSM). States determine the reaction of the FSM to the system inputs and events. Depending on the inputs to the system and also the system transitions, a state can be active or in-active at any given time.
Active and Inactive States¶
When the state machine arrives at one state by taking a transition, that state becomes active, meaning that the state-machine is on that state's mode, and the states actions and transitions describe the behavior of the state-machine. States that are not active are inactive states.
State Types¶
There are two types of state in Weld which determine the execution method of the state's children:
- Serial State which indicates that its child states are Mutually Exclusive and at any given moment during the execution, only one of its child states can be active. The Transition between the child states is the path that the state-machine can take to activate and deactivate the child states.
- Parallel State which indicates that, for as long as the state is active, all its child states are active and get executed one after another, according to their priorities.
In order to change the type of a state, you can navigate to the "Properties" tab while the state is highlighted.
State Hierarchy¶
A state can be a Super State or Child State or both. A state that contains one or more state is called a Super State and a state that exists within another state is a Child State. All the states in a Weld application are children of a Thread, which is a state with no parent.
The Weld code generator assigns a state variable to every parent. This variable tracks which child state is active during the code execution. Think of the state variable as the expression in a switch/case
statement. the value of the expression determines which case (child state) should be executed at any given execution interval.
Tip
When entering and exiting Super States:
- A Super State is activated and its entry actions are executed before its children
- A Child State is exited and its exit actions are executed before its super state parent
Super State¶
In practice, defining the behavior of a FSM using only a single state variable quickly becomes impractical for anything beyond very simple systems. This is why the concept of nested states was introduced in the UML representation of the state machines. A state can become a super state when the state itself becomes a state-machine and hosts other states inside it.
In a Weld application, you can create a super state by simply adding states on the body of a state.
States in Weld can be looked at as a fractal tree. Each state can have child states and the child states can have children of their own. Same rules apply to any level of the hierarchy and same concepts are used to generate the code for each level in the chart.
Child State¶
Child states, are the states that are hosted by another state. In practice, every state is a child state except for a Thread, which has no parent. In order for a child state to be active, its parent state should be activated first and when a parent state becomes inactive, all its children become inactive as well.
Default State¶
A state machine should have at least one active state at all times. The Default State is the state that will be designated as active, when there is an ambiguity on which state is active. This can happen, for example, in the first execution interval when the FSM is executed for the first time. The default state in Weld is denoted by the Start Transition on the chart. Each FSM should have one and only one start transition to determine the default state of the system.
Think of the default state and the default
case in a switch/case
statement. When the switch expression does not resolve to any case, the default case is executed.
The default state is only applicable where the parent state is of Serial Type. For a parallel parent, all the child states are active and the concept of Default State does not apply.
State Actions¶
State actions are snippets of code that are executed upon occurrence of state events. There are three types os state events, Entry, Exit, and During events, which are pretty self explanatory.
Actions can be added to each state using the "Action Blocks" on the top left hand side of the state. In order to add Action Blocks you should use the green plus sign on each state.
Note
Action Blocks on a state are executed based on their priorities, from top to bottom.
Entry¶
The Entry Actions of each state are executed only once, upon the entry to the state. They are executed in the same execution interval as the preceding state exit actions are executed. If the state that is entered is a super state (i.e. it has child states), its entry actions are executed before its children. This follows the logic that a super state is entered first before its child states.
Tip
- The Entry Actions of a super state are executed before its children.
- The code snippets in all the Action Blocks with their "En" option enabled are executed one after another, based on their priorities.
Exit¶
Just like the entry action, the Exit Actions of a state are only executed once, upon exiting the state. An state is marked for exit, if, it has been active since at least the previous execution cycles, and it has one valid outgoing transition in the current cycle. Once a state is marked for exit, its Exit Actions are execute before the Transition actions of the outgoing transition and entry actions of the next state.
During¶
"During" actions are executed if the state has been active, and no valid outgoing transition is present in the current execution cycle. "During" actions of a parent state are executed before its children meaning that the states that are higher in hierarchy, have higher priorities when it come to "during" actions.
State Properties¶
Each state has several properties that determine the behavior of that state and its children during the execution. These properties are listed below.
State Name¶
Name is one of the important properties of an state. State names should be conforming to the C language variable naming rules. Failure to abide by these rules will result in a code generation failure or a generated code that is not going to compile.
The best practice for choosing state names is to use a name that is unique across your project. The reason for that is to avoid any confusion in case you are using the built-in state APIs.
State Type¶
A state can be of one of two types:
- Serial,
- Parallel
When type of a state is set to to serial, only one of its (direct) child states can be active and running at any given time. In an active parallel state however, all of its (direct) child states are active and they get executed sequentially according to their priorities.
Historic¶
A historic State is a state that remembers its last active child state upon exit and enables that state upon re-entry.