-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMicrowave.cpp
More file actions
176 lines (137 loc) · 3.49 KB
/
Copy pathMicrowave.cpp
File metadata and controls
176 lines (137 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// A simple simulation of an microwave oven:
// Timer can be programmed in minutes, last mode will be resumed if opened.
//
// Compile like this:
// g++ Macho.cpp Microwave.cpp
#include <iostream>
using namespace std;
#include "Macho.hpp"
// Simple microwave simulation
namespace Microwave {
//////////////////////////////////////////////////////////////////////
// State declarations
// Machine's top state
TOPSTATE(Top) {
// Top state data (visible to all substates)
struct Box {
Box() : myCookingTime(0) {}
void printTimer() {
cout << " Timer set to " << myCookingTime << " minutes" << endl;
}
void incrementTimer() { ++myCookingTime; }
void decrementTimer() { --myCookingTime; }
void resetTimer() { myCookingTime = 0; }
int getRemainingTime() { return myCookingTime; }
private:
int myCookingTime;
};
STATE(Top)
// Machine's event protocol
virtual void open() {}
virtual void close() {}
virtual void minute() {} // Increment timer by a minute
virtual void start() {} // Start cooking
virtual void stop() {} // Stop cooking
virtual void tick() {} // Minute has passed
private:
// Initial entry action
void init();
};
// Microwave has been opened
SUBSTATE(Disabled, Top) {
STATE(Disabled)
// Event handler
void close();
private:
// Entry and exit actions of state
void entry();
void exit();
};
// Microwave is ready
SUBSTATE(Operational, Top) {
STATE(Operational)
// State has history enabled
DEEPHISTORY()
void open();
void stop();
private:
void init();
};
// Microwave is idling
SUBSTATE(Idle, Operational) {
STATE(Idle)
void minute();
private:
void entry();
};
// Microwave is being programmed
SUBSTATE(Programmed, Operational) {
STATE(Programmed)
void minute();
void start();
};
// Microwave is heating
SUBSTATE(Cooking, Programmed) {
STATE(Cooking)
void tick();
private:
void entry();
void exit();
};
//////////////////////////////////////////////////////////////////////
// Event handler and box implementations
// Top state
void Top::init() { setState<Operational>(); }
// State Disabled
void Disabled::entry() { cout << " Microwave opened" << endl; }
void Disabled::exit() { cout << " Microwave closed" << endl; }
void Disabled::close() { setStateHistory<Operational>(); }
// State Operational
void Operational::init() { setState<Idle>(); }
void Operational::open() { setState<Disabled>(); }
void Operational::stop() { setState<Idle>(); }
// State Idle
void Idle::entry() {
TOP::box().resetTimer();
cout << " Microwave ready" << endl;
}
void Idle::minute() {
setState<Programmed>();
dispatch(Event(&TOP::minute));
}
// State Programmed
void Programmed::minute() {
TOP::box().incrementTimer();
TOP::box().printTimer();
}
void Programmed::start() { setState<Cooking>(); }
// State Cooking
void Cooking::entry() { cout << " Heating on" << endl; }
void Cooking::exit() { cout << " Heating off" << endl; }
void Cooking::tick() {
cout << " Clock tick" << endl;
TOP::Box &tb = TOP::box();
tb.decrementTimer();
if (tb.getRemainingTime() == 0) {
cout << " Finished" << endl;
setState<Idle>();
} else
tb.printTimer();
}
} // namespace Microwave
int main() {
Macho::Machine<Microwave::Top> m;
cout << "Lets cook ourself a TV dinner:" << endl;
m->minute();
m->minute();
m->minute();
m->start();
m->tick();
m->open();
cout << "Adding a little spice..." << endl;
m->close();
m->tick();
m->tick();
cout << "Now there is the remote...?" << endl;
return 0;
}