#include #define NODEBUG enum states { I0_S0 = 0, I0_S1, I0_S2, I1_S0, I1_S1, I1_S2, I2_S0}; char s_states[7][6] = {"I0_S0", "I0_S1", "I0_S2", "I1_S0", "I1_S1", "I1_S2", "I2_S0"}; enum events {E_UP = 0, E_DOWN, E_LEFT, E_RIGHT}; char s_events[4][12] = {"E_UP", "E_DOWN", "E_LEFT", "E_RIGHT"}; char M_I0_S0[] = "Item One"; char M_I0_S1[] = "Item One - Sub Left"; char M_I0_S2[] = "Item One - Sub Right"; char M_I1_S0[] = "Item Two"; char M_I1_S1[] = "Item Two - Sub Left"; char M_I1_S2[] = "Item Two - Sub Right"; char M_I2_S0[] = "Item Three"; void msg_i0_s0 ( void ) { printf("%s \n",M_I0_S0); } void msg_i0_s1 ( void ) { printf("%s \n",M_I0_S1); } void msg_i0_s2 ( void ) { printf("%s \n",M_I0_S2); } void msg_i1_s0 ( void ) { printf("%s \n",M_I1_S0); } void msg_i1_s1 ( void ) { printf("%s \n",M_I1_S1); } void msg_i1_s2 ( void ) { printf("%s \n",M_I1_S2); } void msg_i2_s0 ( void ) { printf("%s \n",M_I2_S0); } class StateMachine { private: enum states state_curr; // Current state struct branch { int event_type; enum states state_new; void (*do_func)(); }; static struct branch transition_table[7][4]; // Transition map public: StateMachine(states state_init) // Constructor with starting state { state_curr = state_init; } void process_event(int c) { if(c == '\n') // Enter Key return; #ifdef DEBUG printf("\nCurrent State: %s \n", s_states[state_curr]); #endif int idx; if(c == 0x77) // w idx = E_UP; if(c == 0x73) // s idx = E_DOWN; if(c == 0x61) // a idx = E_LEFT; if(c == 0x64) // d idx = E_RIGHT; #ifdef DEBUG printf("Event Recieved: %s \n", s_events[idx]); #endif struct branch *b = &transition_table[state_curr][idx]; state_curr = b->state_new; #ifdef DEBUG printf("Next State: %s \n", s_states[state_curr]); #endif if(b->do_func) { void (*pFunc)() = b->do_func; #ifdef DEBUG printf("pFunc Address: 0x%0X \n\n", pFunc); #endif pFunc(); } } }; struct StateMachine::branch StateMachine::transition_table[7][4] = { /* Current state Recieved event, New state, pFunc to exec */ { // State: I0_S0 {E_UP , I0_S0, &msg_i0_s0}, {E_DOWN , I1_S0, &msg_i1_s0}, {E_LEFT , I0_S1, &msg_i0_s1}, {E_RIGHT, I0_S2, &msg_i0_s2} }, { // State: I0_S1 {E_UP , I0_S1, &msg_i0_s1}, {E_DOWN , I0_S1, &msg_i0_s1}, {E_LEFT , I0_S1, &msg_i0_s1}, {E_RIGHT, I0_S0, &msg_i0_s0}, }, { // State: I0_S2 {E_UP , I0_S2, &msg_i0_s2}, {E_DOWN , I0_S2, &msg_i0_s2}, {E_LEFT , I0_S0, &msg_i0_s0}, {E_RIGHT, I0_S2, &msg_i0_s2}, }, { // State: I1_S0 {E_UP , I0_S0, &msg_i0_s0}, {E_DOWN , I2_S0, &msg_i2_s0}, {E_LEFT , I1_S1, &msg_i1_s1}, {E_RIGHT, I1_S2, &msg_i1_s2}, }, { // State: I1_S1 {E_UP , I1_S1, &msg_i1_s1}, {E_DOWN , I1_S1, &msg_i1_s1}, {E_LEFT , I1_S1, &msg_i1_s1}, {E_RIGHT, I1_S0, &msg_i1_s0}, }, { // State: I1_S2 {E_UP , I1_S2, &msg_i1_s2}, {E_DOWN , I1_S2, &msg_i1_s2}, {E_LEFT , I1_S0, &msg_i1_s0}, {E_RIGHT, I1_S2, &msg_i1_s2}, }, { // State: I2_S0 {E_UP , I1_S0, &msg_i1_s0}, {E_DOWN , I2_S0, &msg_i2_s0}, {E_LEFT , I2_S0, &msg_i2_s0}, {E_RIGHT, I2_S0, &msg_i2_s0}, }, }; int main(void) { int c; StateMachine FSM(I0_S0); // Create & initlize state machine while((c = getchar()) != '\33') // Read input untill ESC is recieved { FSM.process_event(c); } return 0; }