Browse Source

state machine uses array of function pointers

Thomas Buck 1 year ago
parent
commit
2386fb0893
2 changed files with 60 additions and 69 deletions
  1. 2
    0
      include/state.h
  2. 58
    69
      src/state.c

+ 2
- 0
include/state.h View File

@@ -25,6 +25,8 @@ enum system_state {
25 25
     STATE_VOLCANO_WORKFLOW,
26 26
     STATE_VOLCANO_RUN,
27 27
     STATE_CRAFTY,
28
+
29
+    STATE_INVALID,
28 30
 };
29 31
 
30 32
 void state_switch(enum system_state next);

+ 58
- 69
src/state.c View File

@@ -24,6 +24,49 @@
24 24
 #include "state_crafty.h"
25 25
 #include "state.h"
26 26
 
27
+#define stringify(name) # name
28
+
29
+struct state {
30
+    const char * const name;
31
+    void (*enter)(void);
32
+    void (*exit)(void);
33
+    void (*run)(void);
34
+};
35
+
36
+static const struct state states[STATE_INVALID + 1] = {
37
+    {
38
+        .name = stringify(STATE_INIT),
39
+        .enter = NULL,
40
+        .exit = NULL,
41
+        .run = NULL,
42
+    }, {
43
+        .name = stringify(STATE_SCAN),
44
+        .enter = state_scan_enter,
45
+        .exit = state_scan_exit,
46
+        .run = state_scan_run,
47
+    }, {
48
+        .name = stringify(STATE_VOLCANO_WORKFLOW),
49
+        .enter = state_volcano_wf_enter,
50
+        .exit = state_volcano_wf_exit,
51
+        .run = state_volcano_wf_run,
52
+    }, {
53
+        .name = stringify(STATE_VOLCANO_RUN),
54
+        .enter = state_volcano_run_enter,
55
+        .exit = state_volcano_run_exit,
56
+        .run = state_volcano_run_run,
57
+    }, {
58
+        .name = stringify(STATE_CRAFTY),
59
+        .enter = state_crafty_enter,
60
+        .exit = state_crafty_exit,
61
+        .run = state_crafty_run,
62
+    }, {
63
+        .name = stringify(STATE_INVALID),
64
+        .enter = NULL,
65
+        .exit = NULL,
66
+        .run = NULL,
67
+    }
68
+};
69
+
27 70
 static enum system_state state = STATE_INIT;
28 71
 
29 72
 void state_switch(enum system_state next) {
@@ -31,85 +74,31 @@ void state_switch(enum system_state next) {
31 74
         return;
32 75
     }
33 76
 
34
-    // clean up old state when leaving it
35
-    switch (state) {
36
-    case STATE_SCAN:
37
-        debug("leaving STATE_SCAN");
38
-        state_scan_exit();
39
-        break;
40
-
41
-    case STATE_VOLCANO_WORKFLOW:
42
-        debug("leaving STATE_VOLCANO_WORKFLOW");
43
-        state_volcano_wf_exit();
44
-        break;
45
-
46
-    case STATE_VOLCANO_RUN:
47
-        debug("leaving STATE_VOLCANO_RUN");
48
-        state_volcano_run_exit();
49
-        break;
50
-
51
-    case STATE_CRAFTY:
52
-        debug("leaving STATE_CRAFTY");
53
-        state_crafty_exit();
54
-        break;
55
-
56
-    default:
57
-        break;
77
+    if (next > STATE_INVALID) {
78
+        debug("invalid new state %d", next);
79
+        next = STATE_INVALID;
58 80
     }
59 81
 
60
-    // prepare new state on entering
61
-    switch (next) {
62
-    case STATE_SCAN:
63
-        debug("entering STATE_SCAN");
64
-        state_scan_enter();
65
-        break;
66
-
67
-    case STATE_VOLCANO_WORKFLOW:
68
-        debug("entering STATE_VOLCANO_WORKFLOW");
69
-        state_volcano_wf_enter();
70
-        break;
71
-
72
-    case STATE_VOLCANO_RUN:
73
-        debug("entering STATE_VOLCANO_RUN");
74
-        state_volcano_run_enter();
75
-        break;
76
-
77
-    case STATE_CRAFTY:
78
-        debug("entering STATE_CRAFTY");
79
-        state_crafty_enter();
80
-        break;
82
+    debug("leaving %s", states[state].name);
83
+    if (states[state].exit) {
84
+        states[state].exit();
85
+    }
81 86
 
82
-    default:
83
-        break;
87
+    debug("entering %s", states[next].name);
88
+    if (states[next].enter) {
89
+        states[next].enter();
84 90
     }
85 91
 
86 92
     state = next;
87 93
 }
88 94
 
89 95
 void state_run(void) {
90
-    switch (state) {
91
-    case STATE_INIT:
92
-        break;
93
-
94
-    case STATE_SCAN:
95
-        state_scan_run();
96
-        break;
97
-
98
-    case STATE_VOLCANO_WORKFLOW:
99
-        state_volcano_wf_run();
100
-        break;
101
-
102
-    case STATE_VOLCANO_RUN:
103
-        state_volcano_run_run();
104
-        break;
105
-
106
-    case STATE_CRAFTY:
107
-        state_crafty_run();
108
-        break;
109
-
110
-    default:
96
+    if (state >= STATE_INVALID) {
111 97
         debug("invalid main state %d", state);
112 98
         state_switch(STATE_SCAN);
113
-        break;
99
+    }
100
+
101
+    if (states[state].run) {
102
+        states[state].run();
114 103
     }
115 104
 }

Loading…
Cancel
Save