#include <stdio.h>
#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;
}