Coding the Washing Machine
The code is a relatively straighforward encoding of the graphic.We define a state model, wmachine, using the model command (line 6). Each state of the model is declared with the State command. The State command invocations correspond to the boxes on the state model graphic. The State command has an interface like the core proc command. Any parameters would be listed in the second argument. The body of the State command is the Tcl code that will be run when the state is entered upon a transition. A Tcl variable called, self is implicitly declared in the state action. The value of the variable is set to the name of the state machine command that is currently executing the transition. This value is useful for accessing the configuration of the state machine and can serve as the source of event generation.
For this example, the components of the washing machine, such as the pump and motor, are simulated by simple puts commands. In a real program these would be replaced by procedure invocations or event generation to other state machines. Also note that there are several places where we simulate the behavior of some of these components by using the after command.
The Transition command defines which state is entered when a given event is delivered (i.e. line 28). The Transition command invocations correspond to the arcs on the state model graphic.
Several things are worth noting in the specification of a state model.
- There is no command to specify events. The events to which the state model responds is simply the set of events mentioned in the Transition commands.
- The order of State and Transition command invocation is arbitrary. You may put all the State commands followed by all the Transition commands or any other combination that you find clear. The style here is to put the Transitions after the state to which they apply, but that is strictly a stylistic convention.
The state model definition completes at line 105. The remainder of the code shows how to create and run an instance of a state machine.
At line 108, we draw the as-implemented state model. The moore package can run dot(1) if it is available. The result shows the as-implemented model in a graphical representation.
At line 110, an instance of the state model is created using the machine command. Since no initial state argument was given, the initial state is the default initial state. In this case that is the Idle state since it was declared first. The default initial state can also be explicitly declared during the state model specification using the InitialState command.
At line 112, the times used in the machine are configured. The times are in milliseconds.
Line 113 and 114 configure state model tracing on. It is necessary that the log level for the moore namespace be at least info and the trace configuration be set to true. The tracing for each individual state machine can be configured on and off using the trace configuration. This can help to limit the trace output to specific machines.
Finally at line 117, we start the washing machine running by generating a Run event to it. The source of the event is the empty string ({}) and this indicates that the event was generated from outside the context of any state machine.
At line 119, the program enters the Tcl event loop. Recall that the state action of the Idle state writes the the ::wmachine array and this is used as the synchronization mechanism between the state model and the test code.
Finally at line 121, we clean up the state machine by destroying it.