OOSMOS
objects.OOSMOS
quicker.EventDemo
is an implementation of a controller for a simulated pump and
a motor. The pump
and motor
objects are independent
and can be started and stopped individually by a control
object.
Events are triggered by pressing and releasing keys on the
Windows PC keyboard which are detected and announced by key
objects. The speed of the
pump
can be adjusted by up and down key events.
motor
and pump
are
off. We guarantee this by requiring the 's' key to be depressed while the option
is being set. (By pressing the '1' or '2' key.) When 's' is pressed, both
the motor
and pump
are stopped. (See the statechart, below.)
key
class uses OS calls to
react to keystrokes, turning them into OOSMOS
events.
CL
compiler. Locate and run bld.py
to compile and link the example.
Once built, you can run control.exe
.
control
,
pump
, motor
, and key
. This section details
each object, including its requirements, statechart and code.
control
is the main orchestration object that reacts to keystroke events and directs
the pump and motor objects.
control
's statechart in Figure 1.
Off
when
this key is pressed, the motor will turn On
. If the motor is On
when
this key is pressed, the motor will turn Off
.Off
when
this key is pressed, the pump will turn On
. If the pump is off when
this key is pressed, the pump will turn Off
.Operational
state is exited (also
exiting any nested states). When the 's' key is released, the Operational
state is entered, and then the MotionControl/Idle
and
PumpControl/Idle
states will be entered.1 | |
---|---|
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 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | |
204 | |
205 | |
206 | |
207 | |
208 | |
209 | |
210 | |
211 | |
212 | |
213 | |
214 | |
215 | |
216 | |
217 | |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | |
230 | |
231 | |
232 | |
233 | |
234 | |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | |
241 | |
242 | |
243 | |
244 | |
245 | |
246 | |
247 | |
248 | |
249 | |
250 | |
251 | |
252 | |
253 | |
254 | |
255 | |
256 | |
257 | |
258 | |
259 | |
260 | |
261 | |
262 | |
263 | |
264 | |
265 | |
266 | |
267 | |
268 | |
269 | |
270 | |
271 | |
272 | |
273 | |
274 | |
275 | |
276 | |
277 | |
278 | |
279 | |
280 | |
281 | |
282 | |
283 | |
284 | |
285 | |
286 | |
287 | |
288 | |
289 | |
290 | |
291 | |
292 | |
293 | |
294 | |
295 | |
296 | |
[GPLv2] | |
#include "oosmos.h" | |
#include "control.h" | |
#include "motor.h" | |
#include "pump.h" | |
#include "pin.h" | |
#include "sw.h" | |
#include <stdbool.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
//>>>EVENTS | |
enum { | |
evMovePressed = 1, | |
evOption1Pressed = 2, | |
evOption2Pressed = 3, | |
evPumpPressed = 4, | |
evQuitPressed = 5, | |
evStopPressed = 6, | |
evStopReleased = 7 | |
}; | |
#ifdef oosmos_DEBUG | |
static const char * OOSMOS_EventNames(int EventCode) | |
{ | |
switch (EventCode) { | |
case evMovePressed: return "evMovePressed"; | |
case evOption1Pressed: return "evOption1Pressed"; | |
case evOption2Pressed: return "evOption2Pressed"; | |
case evPumpPressed: return "evPumpPressed"; | |
case evQuitPressed: return "evQuitPressed"; | |
case evStopPressed: return "evStopPressed"; | |
case evStopReleased: return "evStopReleased"; | |
default: return ""; | |
} | |
} | |
#endif | |
//<<<EVENTS | |
typedef union { | |
oosmos_sEvent Event; | |
} uEvents; | |
struct controlTag | |
{ | |
motor * m_pMotor; | |
pump * m_pPump; | |
bool m_Option1; | |
bool m_Option2; | |
//>>>DECL | |
oosmos_sStateMachine(ROOT, uEvents, 3); | |
oosmos_sLeaf StartingUp_State; | |
oosmos_sOrtho Operational_State; | |
oosmos_sOrthoRegion Operational_Region1_State; | |
oosmos_sLeaf Operational_Region1_Moving_State; | |
oosmos_sLeaf Operational_Region1_Idle_State; | |
oosmos_sOrthoRegion Operational_Region2_State; | |
oosmos_sLeaf Operational_Region2_Idle_State; | |
oosmos_sLeaf Operational_Region2_Pumping_State; | |
oosmos_sLeaf StopPressed_State; | |
oosmos_sLeaf Terminated_State; | |
//<<<DECL | |
}; | |
static void ToggleOption1(control * pControl) | |
{ | |
pControl->m_Option1 = !(pControl->m_Option1); | |
oosmos_DebugPrint("Option1: %d\n", pControl->m_Option1); | |
} | |
static void ToggleOption2(control * pControl) | |
{ | |
pControl->m_Option2 = !(pControl->m_Option2); | |
oosmos_DebugPrint("Option2: %d\n", pControl->m_Option1); | |
} | |
//>>>CODE | |
static bool StartingUp_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
control * pControl = (control *) pObject; | |
switch (oosmos_EventCode(pEvent)) { | |
case oosmos_ENTER: { | |
return oosmos_StateTimeoutSeconds(pState, (uint32_t) 1); | |
} | |
case oosmos_TIMEOUT: { | |
return oosmos_Transition(pControl, pState, Operational_State); | |
} | |
} | |
return false; | |
} | |
static bool Operational_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
control * pControl = (control *) pObject; | |
switch (oosmos_EventCode(pEvent)) { | |
case evStopPressed: { | |
return oosmos_Transition(pControl, pState, StopPressed_State); | |
} | |
case evQuitPressed: { | |
return oosmos_Transition(pControl, pState, Terminated_State); | |
} | |
} | |
return false; | |
} | |
static bool StopPressed_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
control * pControl = (control *) pObject; | |
switch (oosmos_EventCode(pEvent)) { | |
case evOption1Pressed: { | |
ToggleOption1(pControl); | |
return true; | |
} | |
case evOption2Pressed: { | |
ToggleOption2(pControl); | |
return true; | |
} | |
case evStopReleased: { | |
return oosmos_Transition(pControl, pState, Operational_State); | |
} | |
} | |
return false; | |
} | |
static bool Operational_Region1_Moving_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
control * pControl = (control *) pObject; | |
switch (oosmos_EventCode(pEvent)) { | |
case oosmos_ENTER: { | |
motorOn(pControl->m_pMotor); | |
return true; | |
} | |
case oosmos_EXIT: { | |
motorOff(pControl->m_pMotor); | |
return true; | |
} | |
case evMovePressed: { | |
return oosmos_Transition(pControl, pState, Operational_Region1_Idle_State); | |
} | |
} | |
return false; | |
} | |
static bool Operational_Region1_Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
control * pControl = (control *) pObject; | |
switch (oosmos_EventCode(pEvent)) { | |
case evMovePressed: { | |
return oosmos_Transition(pControl, pState, Operational_Region1_Moving_State); | |
} | |
} | |
return false; | |
} | |
static bool Terminated_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
switch (oosmos_EventCode(pEvent)) { | |
case oosmos_ENTER: { | |
exit(1); | |
} | |
} | |
oosmos_UNUSED(pObject); | |
oosmos_UNUSED(pState); | |
return false; | |
} | |
static bool Operational_Region2_Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
control * pControl = (control *) pObject; | |
switch (oosmos_EventCode(pEvent)) { | |
case evPumpPressed: { | |
return oosmos_Transition(pControl, pState, Operational_Region2_Pumping_State); | |
} | |
} | |
return false; | |
} | |
static bool Operational_Region2_Pumping_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
control * pControl = (control *) pObject; | |
switch (oosmos_EventCode(pEvent)) { | |
case oosmos_ENTER: { | |
pumpOn(pControl->m_pPump); | |
return true; | |
} | |
case oosmos_EXIT: { | |
pumpOff(pControl->m_pPump); | |
return true; | |
} | |
case evPumpPressed: { | |
return oosmos_Transition(pControl, pState, Operational_Region2_Idle_State); | |
} | |
} | |
return false; | |
} | |
//<<<CODE | |
extern control * controlNew(void) | |
{ | |
oosmos_Allocate(pControl, control, 1, NULL); | |
oosmos_sQueue * const pControlEventQueue = &pControl->m_EventQueue; | |
pin * pStopPin = pinNew('s', pinActiveHigh); | |
sw * pStopSwitch = swNew(pStopPin); | |
swSubscribeCloseEvent(pStopSwitch, pControlEventQueue, evStopPressed, NULL); | |
swSubscribeOpenEvent(pStopSwitch, pControlEventQueue, evStopReleased, NULL); | |
pin * pMovePin = pinNew('m', pinActiveHigh); | |
sw * pMoveSwitch = swNew(pMovePin); | |
swSubscribeCloseEvent(pMoveSwitch, pControlEventQueue, evMovePressed, NULL); | |
pin * pQuitPin = pinNew('q', pinActiveHigh); | |
sw * pQuitSwitch = swNew(pQuitPin); | |
swSubscribeCloseEvent(pQuitSwitch, pControlEventQueue, evQuitPressed, NULL); | |
pin * pPumpPin = pinNew('p', pinActiveHigh); | |
sw * pPumpSwitch = swNew(pPumpPin); | |
swSubscribeCloseEvent(pPumpSwitch, pControlEventQueue, evPumpPressed, NULL); | |
pin * pOption1Pin = pinNew('1', pinActiveHigh); | |
sw * pOption1Switch = swNew(pOption1Pin); | |
swSubscribeCloseEvent(pOption1Switch, pControlEventQueue, evOption1Pressed, NULL); | |
pin * pOption2Pin = pinNew('2', pinActiveHigh); | |
sw * pOption2Switch = swNew(pOption2Pin); | |
swSubscribeCloseEvent(pOption2Switch, pControlEventQueue, evOption2Pressed, NULL); | |
pin * pUpPin = pinNew('u', pinActiveHigh); | |
sw * pUpSwitch = swNew(pUpPin); | |
pin * pDownPin = pinNew('d', pinActiveHigh); | |
sw * pDownSwitch = swNew(pDownPin); | |
pControl->m_pMotor = motorNew(); | |
pControl->m_pPump = pumpNew(pUpSwitch, pDownSwitch); | |
pControl->m_Option1 = false; | |
pControl->m_Option2 = false; | |
//>>>INIT | |
oosmos_StateMachineInit(pControl, ROOT, NULL, StartingUp_State); | |
oosmos_LeafInit(pControl, StartingUp_State, ROOT, StartingUp_State_Code); | |
oosmos_OrthoInit(pControl, Operational_State, ROOT, Operational_State_Code); | |
oosmos_OrthoRegionInit(pControl, Operational_Region1_State, Operational_State, Operational_Region1_Idle_State, NULL); | |
oosmos_LeafInit(pControl, Operational_Region1_Moving_State, Operational_Region1_State, Operational_Region1_Moving_State_Code); | |
oosmos_LeafInit(pControl, Operational_Region1_Idle_State, Operational_Region1_State, Operational_Region1_Idle_State_Code); | |
oosmos_OrthoRegionInit(pControl, Operational_Region2_State, Operational_State, Operational_Region2_Idle_State, NULL); | |
oosmos_LeafInit(pControl, Operational_Region2_Idle_State, Operational_Region2_State, Operational_Region2_Idle_State_Code); | |
oosmos_LeafInit(pControl, Operational_Region2_Pumping_State, Operational_Region2_State, Operational_Region2_Pumping_State_Code); | |
oosmos_LeafInit(pControl, StopPressed_State, ROOT, StopPressed_State_Code); | |
oosmos_LeafInit(pControl, Terminated_State, ROOT, Terminated_State_Code); | |
oosmos_Debug(pControl, OOSMOS_EventNames); | |
//<<<INIT | |
return pControl; | |
} |
pump
object controls a pumping device that can
be started and stopped by a controller but it can also react to
keystrokes to pump faster or slower.
pump
object shall startup in an idle, non-pumping state.pump
object shall implement pumpOn
which will turn the
pump on.pump
object shall implement pumpOff
which will turn the
pump off.On
, the speed of the
pump will increase.Off
,
no speed adjustment is made.On
, the speed of the
pump will decrease.Off
,
no speed adjustment is made.pump
is pumping, the message "Pumping...
"
shall be displayed more often if the pump speed is high and less often
if the pump speed is low.1 | |
---|---|
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
[GPLv2] | |
#ifndef _pump_h | |
#define _pump_h | |
#include "sw.h" | |
typedef struct pumpTag pump; | |
extern pump * pumpNew(sw * pUpSwitch, sw * pDownSwitch); | |
extern void pumpOn(const pump * pPump); | |
extern void pumpOff(const pump * pPump); | |
#endif |
1 | |
---|---|
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 | |
[GPLv2] | |
#include "oosmos.h" | |
#include "pump.h" | |
#include <stdbool.h> | |
#include <stddef.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
//>>>EVENTS | |
enum { | |
evDownPressed = 1, | |
evStart = 2, | |
evStop = 3, | |
evUpPressed = 4 | |
}; | |
#ifdef oosmos_DEBUG | |
static const char * OOSMOS_EventNames(int EventCode) | |
{ | |
switch (EventCode) { | |
case evDownPressed: return "evDownPressed"; | |
case evStart: return "evStart"; | |
case evStop: return "evStop"; | |
case evUpPressed: return "evUpPressed"; | |
default: return ""; | |
} | |
} | |
#endif | |
//<<<EVENTS | |
typedef union { | |
oosmos_sEvent Event; | |
} uEvents; | |
struct pumpTag | |
{ | |
uint32_t PumpSpeed; | |
//>>>DECL | |
oosmos_sStateMachine(ROOT, uEvents, 3); | |
oosmos_sLeaf Idle_State; | |
oosmos_sLeaf Pumping_State; | |
//<<<DECL | |
}; | |
#ifndef pumpMAX | |
#define pumpMAX 3 | |
#endif | |
static void Thread(const pump * pPump, oosmos_sState * pState) | |
{ | |
oosmos_ThreadBegin(); | |
for (;;) { | |
printf("PUMPING...\n"); | |
oosmos_ThreadDelayMS(oosmos_Max(100, (10 - pPump->PumpSpeed) * 200)); | |
} | |
oosmos_ThreadEnd(); | |
} | |
//>>>CODE | |
static bool Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
pump * pPump = (pump *) pObject; | |
switch (oosmos_EventCode(pEvent)) { | |
case evStart: { | |
return oosmos_Transition(pPump, pState, Pumping_State); | |
} | |
} | |
return false; | |
} | |
static bool Pumping_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
pump * pPump = (pump *) pObject; | |
switch (oosmos_EventCode(pEvent)) { | |
case oosmos_POLL: { | |
Thread(pPump, pState); | |
return true; | |
} | |
case evUpPressed: { | |
pPump->PumpSpeed = oosmos_Min(10, pPump->PumpSpeed+1); | |
return true; | |
} | |
case evDownPressed: { | |
pPump->PumpSpeed = oosmos_Max(1, pPump->PumpSpeed-1); | |
return true; | |
} | |
case evStop: { | |
return oosmos_Transition(pPump, pState, Idle_State); | |
} | |
} | |
return false; | |
} | |
//<<<CODE | |
extern pump * pumpNew(sw * pUpSwitch, sw * pDownSwitch) | |
{ | |
oosmos_Allocate(pPump, pump, pumpMAX, NULL); | |
pPump->PumpSpeed = 5; | |
swSubscribeCloseEvent(pUpSwitch, oosmos_EventQueue(pPump), evUpPressed, NULL); | |
swSubscribeCloseEvent(pDownSwitch, oosmos_EventQueue(pPump), evDownPressed, NULL); | |
//>>>INIT | |
oosmos_StateMachineInit(pPump, ROOT, NULL, Idle_State); | |
oosmos_LeafInit(pPump, Idle_State, ROOT, Idle_State_Code); | |
oosmos_LeafInit(pPump, Pumping_State, ROOT, Pumping_State_Code); | |
oosmos_Debug(pPump, OOSMOS_EventNames); | |
//<<<INIT | |
return pPump; | |
} | |
extern void pumpOn(const pump * pPump) | |
{ | |
oosmos_PushEventCode(pPump, evStart); | |
} | |
extern void pumpOff(const pump * pPump) | |
{ | |
oosmos_PushEventCode(pPump, evStop); | |
} |
motor
object simulates a motor that can turned
On
or Off
.
motor
object shall startup in an idle, motionless state.motor
object shall implement motorOn
which will turn the
motor on.motor
object shall implement motorOff
which will turn the
motor off.motor
is moving, the message "Moving...
" shall be
displayed every 2 seconds.1 | |
---|---|
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
[GPLv2] | |
#ifndef _motor_h | |
#define _motor_h | |
typedef struct motorTag motor; | |
extern motor * motorNew(void); | |
extern void motorOn(const motor * pMotor); | |
extern void motorOff(const motor * pMotor); | |
#endif |
1 | |
---|---|
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 | |
[GPLv2] | |
#include "oosmos.h" | |
#include "motor.h" | |
#include <stdbool.h> | |
#include <stdio.h> | |
//>>>EVENTS | |
enum { | |
evStart = 1, | |
evStop = 2 | |
}; | |
#ifdef oosmos_DEBUG | |
static const char * OOSMOS_EventNames(int EventCode) | |
{ | |
switch (EventCode) { | |
case evStart: return "evStart"; | |
case evStop: return "evStop"; | |
default: return ""; | |
} | |
} | |
#endif | |
//<<<EVENTS | |
typedef union { | |
oosmos_sEvent Event; | |
} uEvents; | |
struct motorTag | |
{ | |
//>>>DECL | |
oosmos_sStateMachine(ROOT, uEvents, 3); | |
oosmos_sLeaf Idle_State; | |
oosmos_sLeaf Moving_State; | |
//<<<DECL | |
}; | |
#ifndef motorMAX | |
#define motorMAX 3 | |
#endif | |
static void MovingThread(oosmos_sState * pState) | |
{ | |
oosmos_ThreadBegin(); | |
for (;;) { | |
printf("motor: MOVING...\n"); | |
oosmos_ThreadDelayMS(500); | |
} | |
oosmos_ThreadEnd(); | |
} | |
//>>>CODE | |
static bool Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
motor * pMotor = (motor *) pObject; | |
switch (oosmos_EventCode(pEvent)) { | |
case evStart: { | |
return oosmos_Transition(pMotor, pState, Moving_State); | |
} | |
} | |
return false; | |
} | |
static bool Moving_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent) | |
{ | |
motor * pMotor = (motor *) pObject; | |
switch (oosmos_EventCode(pEvent)) { | |
case oosmos_POLL: { | |
MovingThread(pState); | |
return true; | |
} | |
case evStop: { | |
return oosmos_Transition(pMotor, pState, Idle_State); | |
} | |
} | |
return false; | |
} | |
//<<<CODE | |
extern motor * motorNew(void) | |
{ | |
oosmos_Allocate(pMotor, motor, motorMAX, NULL); | |
//>>>INIT | |
oosmos_StateMachineInit(pMotor, ROOT, NULL, Idle_State); | |
oosmos_LeafInit(pMotor, Idle_State, ROOT, Idle_State_Code); | |
oosmos_LeafInit(pMotor, Moving_State, ROOT, Moving_State_Code); | |
oosmos_Debug(pMotor, OOSMOS_EventNames); | |
//<<<INIT | |
return pMotor; | |
} | |
extern void motorOn(const motor * pMotor) | |
{ | |
oosmos_PushEventCode(pMotor, evStart); | |
} | |
extern void motorOff(const motor * pMotor) | |
{ | |
oosmos_PushEventCode(pMotor, evStop); | |
} |
oosmos_RunStateMachines
.
This delay makes sure that we only
take small sips from the processor, but it is often enough that we are sufficiently reactive to keystrokes.
1 | |
---|---|
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
[GPLv2] | |
#include "oosmos.h" | |
#include "control.h" | |
extern int main(void) | |
{ | |
(void) controlNew(); | |
for (;;) { | |
oosmos_RunStateMachines(); | |
oosmos_DelayMS(1); | |
} | |
} |
pump
object to itself and from the motor
object to itself
are examples of a method enqueuing work to itself, effectively implementing
an asynchronous call.