bomb1.c
来自「事件驱动程序设计很好的框架」· C语言 代码 · 共 205 行
C
205 行
/****************************************************************************** Product: Time Bomb Example with "Nested Switch Statement"* Last Updated for Version: 4.0.00* Date of the Last Update: Apr 07, 2008** Q u a n t u m L e a P s* ---------------------------* innovating embedded systems** Copyright (C) 2002-2008 Quantum Leaps, LLC. All rights reserved.** This software may be distributed and modified under the terms of the GNU* General Public License version 2 (GPL) as published by the Free Software* Foundation and appearing in the file GPL.TXT included in the packaging of* this file. Please note that GPL Section 2[b] requires that all works based* on this software must also be made publicly available under the terms of* the GPL ("Copyleft").** Alternatively, this software may be distributed and modified under the* terms of Quantum Leaps commercial licenses, which expressly supersede* the GPL and are specifically designed for licensees interested in* retaining the proprietary status of their code.** Contact information:* Quantum Leaps Web site: http://www.quantum-leaps.com* e-mail: info@quantum-leaps.com*****************************************************************************/#include "bsp.h"enum BombSignals { /* all signals for the Bomb FSM */ UP_SIG, DOWN_SIG, ARM_SIG, TICK_SIG};enum BombStates { /* all states for the Bomb FSM */ SETTING_STATE, TIMING_STATE};typedef struct EventTag { uint16_t sig; /* signal of the event */ /* add event parameters by derivation from the Event structure... */} Event;typedef struct TickEvtTag { Event super; /* derive from the Event structure */ uint8_t fine_time; /* the fine 1/10 s counter */} TickEvt;typedef struct Bomb1Tag { /* the Bomb FSM */ uint8_t state; /* the scalar state-variable */ uint8_t timeout; /* number of seconds till explosion */ uint8_t code; /* currently entered code to disarm the bomb */ uint8_t defuse; /* secret defuse code to disarm the bomb */} Bomb1;void Bomb1_ctor(Bomb1 *me, uint8_t defuse); /* the "constructor" */void Bomb1_init(Bomb1 *me); /* init() function */void Bomb1_dispatch(Bomb1 *me, Event const *e); /* macro for taking a state transition */#define TRAN(target_) (me->state = (uint8_t)(target_)) /* the initial value of the timeout */#define INIT_TIMEOUT 10/*..........................................................................*/void Bomb1_ctor(Bomb1 *me, uint8_t defuse) { me->defuse = defuse; /* the defuse code is assigned at instantiation */}/*..........................................................................*/void Bomb1_init(Bomb1 *me) { me->timeout = INIT_TIMEOUT; /* timeout is initialized in initial tran. */ TRAN(SETTING_STATE);}/*..........................................................................*/void Bomb1_dispatch(Bomb1 *me, Event const *e) { switch (me->state) { case SETTING_STATE: { switch (e->sig) { case UP_SIG: { if (me->timeout < 60) { ++me->timeout; BSP_display(me->timeout); } break; } case DOWN_SIG: { if (me->timeout > 1) { --me->timeout; BSP_display(me->timeout); } break; } case ARM_SIG: { me->code = 0; TRAN(TIMING_STATE); /* transition to "timing" */ break; } } break; } case TIMING_STATE: { switch (e->sig) { case UP_SIG: { me->code <<= 1; me->code |= 1; break; } case DOWN_SIG: { me->code <<= 1; break; } case ARM_SIG: { if (me->code == me->defuse) { TRAN(SETTING_STATE); /* transition to "setting" */ } break; } case TICK_SIG: { if (((TickEvt const *)e)->fine_time == 0) { --me->timeout; BSP_display(me->timeout); if (me->timeout == 0) { BSP_boom(); /* destroy the bomb */ } } break; } } break; } }}/* Test harness ------------------------------------------------------------*/#include <stdio.h>#include <conio.h>#include <dos.h>static Bomb1 l_bomb; /* time bomb FSM *//*..........................................................................*/void main() { Bomb1_ctor(&l_bomb, 0x0D); /* the secret defuse code, 1101 binary */ printf("Time Bomb (Nested switch)\n" "Press 'u' for UP event\n" "Press 'd' for DOWN event\n" "Press 'a' for ARM event\n" "Press <Esc> to quit.\n"); Bomb1_init(&l_bomb); /* take the initial transition */ for (;;) { /* event loop */ static TickEvt tick_evt = { TICK_SIG, 0}; delay(100); /* 100 ms delay */ if (++tick_evt.fine_time == 10) { tick_evt.fine_time = 0; } printf("T(%1d)%c", tick_evt.fine_time, (tick_evt.fine_time == 0) ? '\n' : ' '); Bomb1_dispatch(&l_bomb, (Event *)&tick_evt); /* dispatch tick event */ if (kbhit()) { static Event const up_evt = { UP_SIG }; static Event const down_evt = { DOWN_SIG }; static Event const arm_evt = { ARM_SIG }; Event const *e = (Event *)0; switch (getch()) { case 'u': { /* UP event */ printf("\nUP : "); e = &up_evt; /* generate the UP event */ break; } case 'd': { /* DOWN event */ printf("\nDOWN: "); e = &down_evt; /* generate the DOWN event */ break; } case 'a': { /* ARM event */ printf("\nARM : "); e = &arm_evt; /* generate the ARM event */ break; } case '\33': { /* <Esc> key */ printf("\nESC : Bye! Bye!"); exit(0); break; } } if (e != (Event *)0) { /* keyboard event available? */ Bomb1_dispatch(&l_bomb, e); /* dispatch the event */ } } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?