(stdin)
1 #!/usr/bin/env tclsh
2
3 package require oomoore
4
5 # The model class is a meta-class. Creating an instance of model creates a new
6 # class. The constructor accepts a script that configures the state model. The
7 # resulting class can then be used as a superclass to give state behavior.
8
9 oomoore model create wmachine {
10 # The state model is defined by executing commands to specify the states
11 # and transitions of the model.
12
13 # The "state" command defines a state and the Tcl code that is run when the
14 # state is entered.
15 state Idle {} {
16 # Stop motor
17 puts "[self]: Stopping motor"
18
19 # For testing purpose, we want to be able to run the Tcl event loop and
20 # when we are done with the cycle we will use "vwait" to determine that
21 # we have finished.
22 set ::wmachine([self]) Idle
23 }
24
25 # The "transition" command defines what happens when an event is received
26 # in a state. Notice that there is no command to define the events to which
27 # the model responds. The events are simply gleened from the "transition"
28 # commands. The "-" and "->" arguments are simply syntactic sugar to
29 # suggest the transition from current state to new state that the event
30 # causes.
31 transition Idle - Run -> FillingForWashing
32
33 state FillingForWashing {} {
34 # Open water valve
35 puts "[self]: Opening water valve"
36
37 # At this point we need the washing tub sensor to tell us that the
38 # tub is full. For simplicity, we will simulate the sensor by
39 # signalling a delayed event to ourselves.
40 # SIMULATING THE TUB SENSOR
41 my delayedSignal 5000 Full
42 }
43 transition FillingForWashing - Full -> Agitating
44
45 state Agitating {} {
46 # Close water value
47 puts "[self]: Closing water valve"
48 # Set motor to agitate
49 puts "[self]: Setting motor to agitate"
50 # Signal "Done" to self delayed by the wash time.
51 my variable wash
52 my delayedSignal $wash Done
53 }
54 transition Agitating - Done -> EmptyingWashWater
55
56 state EmptyingWashWater {} {
57 # Stop motor
58 puts "[self]: Stopping motor"
59 # Start pump
60 puts "[self]: Starting pump"
61
62 # SIMULATING THE TUB SENSOR
63 my delayedSignal 5000 Empty
64 }
65 transition EmptyingWashWater - Empty -> FillingForRinse
66
67 state FillingForRinse {} {
68 # Stop pump
69 puts "[self]: Stopping pump"
70 # Open water valve
71 puts "[self]: Opening water valve"
72
73 # SIMULATING THE TUB SENSOR
74 my delayedSignal 5000 Full
75 }
76 transition FillingForRinse - Full -> Rinsing
77
78 state Rinsing {} {
79 # Close water valve
80 puts "[self]: Closing water valve"
81 # Set motor to agitate
82 puts "[self]: Setting motor to agitate"
83 # Signal Done to self delayed by the rinse time
84 my variable rinse
85 my delayedSignal $rinse Done
86 }
87 transition Rinsing - Done -> EmptyingRinseWater
88
89 state EmptyingRinseWater {} {
90 # Stop motor
91 puts "[self]: Stopping motor"
92 # Start pump
93 puts "[self]: Starting pump"
94
95 # SIMULATING THE TUB SENSOR
96 my delayedSignal 5000 Empty
97 }
98 transition EmptyingRinseWater - Empty -> Spinning
99
100 state Spinning {} {
101 # Stop pump
102 puts "[self]: Stopping pump"
103 # Set motor to spin
104 puts "[self]: Setting motor to spin"
105 # Signal Done to self delayed by the spin time
106 my variable spin
107 my delayedSignal $spin Done
108 }
109 transition Spinning - Done -> Idle
110 }
111
112 # Draw the "as implemented" model
113 wmachine draw {-Tsvg -o%s.svg -Gsize=7.5,10}
114 # Create a state machine from the model
115 oo::class create wm_model100 {
116 superclass wmachine
117 constructor {} {
118 next
119
120 # Define the variables used in the state actions.
121 my variable wash rinse spin
122 set wash 3000
123 set rinse 3000
124 set spin 4000
125 }
126 }
127 wm_model100 create wm1
128 # Turn on tracing
129 wm1 loglevel info
130 # Kick things off
131 wm1 signal Run
132 # Wait until the cycle is complete
133 vwait ::wmachine(::wm1)
134 # Clean up
135 wm1 destroy
Generated by GNU Enscript 1.6.5.90.