At a high level, systems have two kinds of behavior - actions and changes of state. In Frame, changes of state come in two flavors - transitions and state changes.
Statecharts, the software modeling technique Frame descends from, distinguishes between “actions” which take very little time to execute and “activities” which are relatively long running asynchronous or background behavior, typically managed by actions. For now we can consider all other categories of things systems can do as being derivative from or enabled by actions and transitions.
We will now explore these two broad categories of behavior and discuss the Frame notation for executing them.
Actions
Frame promotes a “self-documenting” coding style and generally suggests that Frame specs utilize descriptively named action methods to execute operations. Partly this is due to Frame not (currently) supporting much in the way of data manipulation or test syntax.
Actions are simply private methods, if privacy is supported by the target language, that do lower level operations, tests or functional operations. More structure and differentiation may evolve and further categories of methods may emerge as Frame advances in sophistication, but for now actions fulfill a large number of fine-grained roles for Frame specifications.
Changes of State
Frame supports two operators for changing state:
Symbol | Meaning | Operations |
---|---|---|
->> “opt_label” $NewState | State Change | Change State |
-> “opt_label” $NewState | Transition | Send Exit Event, Change State, Send Enter Event |
Both operators update the state variable with the target state. However they are radically different in the machinery that they utilize.
Here is a spec showing both in use:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ChangingState
-interface-
transition
changeState
-machine-
$S0
|<| handleTransitionExitEvent() ^
|transition| -> "transition" $S1 ^
$S1
|>| handleTransitionEnterEvent() ^
|changeState| ->> "change state" $S0 ^
-actions-
handleTransitionExitEvent
handleTransitionEnterEvent
##
To visually differentiate these two operators in documentation, Frame specifies that the change state operator is drawn with a dotted line while the transition with a solid line.
We will now examine how both of these operators work under the hood.
The Transition Operator
As mentioned, transitions are a powerful but heavyweight operator that do the following steps:
- Send an Exit Event (
|<|
) to the current state. - Update the state variable to be the new state.
- Send an Enter Event (
|>|
) to the new state.
Let us see this machinery in the C# output for our #ChangingState
spec:
Above we can see the declaration of the _state_
member variable that tracks the current state. C# also requires state references to be declared as a C# delegate
, so the FrameState type is declared as such and used as the type for _state_
. Other languages have different requirements for how member variables must be declared to reference methods.
Invoking a transition is a simple matter of calling the _transition_(newState)
method:
Frame
1
2
3
$S0
|<| handleTransitionExitEvent() ^
|transition| -> "transition" $S1 ^
C#
Above we see the _transition_(_sS1_)
call that will trigger the |<|
call for $S0
and subsequently send the $S1
state the |>|
message:
C#
Now let us take a look at the change state mechanisms, which are decidedly simpler.
The Change State Operator
The machinery for a state change is trivial:
C#
Using a method to change state is arguably inefficient. However the code the Framepiler currently generates is a “reference architecture” for defining the functional pattern Frame promotes. It also provides a choke point for centralized debugging as well. In the future, the Framepiler will provide options to generate optimized code.
The Frame change state notation shown here:
Frame
1
2
$S1
|changeState| ->> "change state" $S0 ^
generates the following C# code:
C#
State changes are useful not only for efficient context switches when enter/exit events are not available but also for certain situations where they are available but shouldn’t be triggered. This gives the system architect a means to quietly “slip into” and “slip out of” a state. This can be very useful for a number of situations that will be discussed later in more architecture oriented articles.
Conclusion
Actions and changing state make up the bulk of the capabilities of state machine behavior and align with traditional Statechart concepts. Frame will continue to develop new “mechanisms” of various kinds that will become part of the notation which will not be clearly be in either of these camps. In doing so, it is hoped that Frame can expand the set of capabilities that are considered “behavior” by automata.
Here is a working demo of the #ChangingState
spec: