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.