Stateful machines
In the last article we successfully had a Frame system say “Hello World”. In this one we will guild the lily a bit and explore some of the core Frame syntax for implementing basic state machines.
Event Message Aliasing
By default the Frame syntax for interface methods sends an event with a message that is the same name as the interface method:
1
2
3
4
5
6
7
8
9
#World_v6
-interface-
speak
...
##
The Frame notation above generates the following C#
code:
Frame event message aliases provide a way to send a different message into the state machine:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#World_v7
-interface-
speak @(|parler|)
-machine-
$Begin
|parler|
print("Coucou le monde") ^
-actions-
print [msg:string]
##
Here we see that the interface method speak
now sends parler
instead of the default speak
message.
Aliasing allows us to decouple the interface from the details of the event handling in the state machine. This feature enables Frame to support a few symbolic messages that are reserved for certain standard semantic operations:
Message | Meaning |
> | Enter State |
< | Exit State |
>> | Start System |
<< | Stop System |
>>> | Save System |
<<< | Restore System |
Let’s convert our World to use this new ability:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#World_v8
-interface-
start @(|>>|)
-machine-
$Begin
|>>|
print("Hello World") ^
-actions-
print [msg:string]
##
Now we are able to send the standard Frame start
message >>
to trigger our greeting:
Cool. However, we don’t want to be a one state pony. Instead we are going to stretch our boundaries and introduce a new $Working
state to do the heavy lifting of printing our greeting.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#World_v9
-interface-
start @(|>>|)
-machine-
$Begin
|>>| ^
$Working
|>|
print("Hello World") ^
-actions-
print [msg:string]
##
In the $Working
state we see the use of the new enter message >
that calls the print()
action now.
This is the same event handler pattern we have seen before but there is a big mystery here - where does the enter message come from? So far we have only seen messages on events created by the interface. What’s worse is there is the major problem of not knowing how to get to the $Working
state in the first place.
The answer to both questions is the inner workings of the transition.
Transitions
Central to state machine theory is the idea of a transition from one state to another. Frame notates transitions with the ->
symbol. So to get from $Begin
to $Working
we can do this:
1
2
3
$Begin
|>>|
-> $Working ^
This notation generates this code:
Transitions do three core activities:
- Send an exit event to the current state
- Change the
_state_
variable to the new state - Send an enter event to the new state
Here is the code for the _transition_()
method:
Enter and exit events are, essentially, constructors and destructors for states and enable powerful mechanisms for managing resources. For instance the following code is a template for how to use a timer properly to do an activity report:
1
2
3
4
5
6
7
8
9
10
11
12
#TimeStudy
-machine-
$Working
|>|
startTimer() ^
|<|
stopTimer()
generateTimeStudy() ^
##
You can try it yourself in the Framepiler.
We now have all the tools to understand how “Hello World” can be emitted from a true state machine:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
---------------------------------------
#World_v10
-interface-
start @(|>>|)
-machine-
$Begin
|>>|
-> $Working ^
$Working
|>|
print("Hello World") ^
-actions-
print [msg:string]
##
Here is what it looks like in C#
:
You can see a working demo of this on .NET fiddle. (NOTE: In the online version I have added code to the print()
action to actually write the greeting. More to come on how to use Frame state machines in real world development later).
Conclusion
We have now seen a couple of ways to implement “Hello World” which have allowed us to explore some of Frame’s core capabilities.
In the next and final installment of our “Hello World” saga, we will dive deep into the power of hierarchical state machines as well as bring the world to a tidy $End
with stop events using Frame notation.