Listing 2: The Keyboard FSM implementation (see state diagram from Figure 2)

 1: #include "fsm.h"
 2:
 3: typedef struct Keyboard Keyboard;
 4: struct Keyboard {
 5:    Fsm super_; /* extend the Fsm class */
 6:    /* ... other attributes of Keyboard */
 7: };
 8:
 9: void KeyboardCtor(Keyboard *me);
10: void Keyboard_initial(Keyboard *me, Event const *e);
11: void Keyboard_default(Keyboard *me, Event const *e);
12: void Keyboard_shifted(Keyboard *me, Event const *e);
13:
14: typedef struct KeyboardEvt KeyboardEvt;
15: struct KeyboardEvt {
16:    Event super_; /* extend the Event class */
17:    char code;
18: };
19:
20: enum { /* signals used by the Keyboard FSM */
21:    SHIFT_DEPRESSED_SIG,
22:    SHIFT_RELEASED_SIG,
23:    ANY_KEY_SIG,
24: };
25:
26: void KeyboardCtor(Keyboard *me) {
27:    FsmCtor_(&me->super_, &Keyboard_initial);
28: }
29:  
30: void Keyboard_initial(Keyboard *me, Event const *e) {
31:    /* ... initalization of Keyboard attributes */
32:    printf("Keyboard initialized");
33:    FsmTran_((Fsm *)me, &Keyboard_default);
34: }
35:
36: void Keyboard_default(Keyboard *me, Event const *e) {
37:    switch (e->sig) {
38:    case SHIFT_DEPRESSED_SIG:
39:       printf("default::SHIFT_DEPRESSED");
40:       FsmTran_((Fsm *)me, &Keyboard_shifted);
41:       break;
42:    case ANY_KEY_SIG:
43:       printf("key %c", (char)tolower(((KeyboardEvt *)e)->code));
44:       break;
45:    }
46: }
47:
48: void Keyboard_shifted(Keyboard *me, Event const *e) {
49:    switch (e->sig) {
50:    case SHIFT_RELEASED_SIG:
51:       printf("shifted::SHIFT_RELEASED");
52:       FsmTran_((Fsm *)me, &Keyboard_default);
53:       break;
54:    case ANY_KEY_SIG:
55:       printf("key %c", (char)toupper(((KeyboardEvt *)e)->code));
56:       break;
57:    }
58: }