On 2005-12-07, nilavya <ni*****@gmail.com> wrote:
HI,
I have got a C++ application involving State machine.
Now I have got too many states and too many events which
changes the state of the Staet machine. So my code is somewhat
unmanageable. It is:
switch(nState)
{
case state1:
{
switch(nEvent)
{
case event1:
break;
case event2:
break;
case event3:
default:
break;
}
}
break;
case state2:
break;
default:
break;
}
Now the problem I have is that some of the handling in various
states-events combo is almost same. That makes my code
redundant.
Any part of the code that's truly redundant can be moved to a
function that all the states can rely on.
Also the function size is toooo large. Is there any way or
design to write this code. I heard about writing a seperate
function for each state. But not sure???
You can define each state as a function, yes.
What you need is a function type that returns a pointer
to function of it's own type. This is not possible to
declare directly in C++.
Here's a finite state machine, which is implemented using
functions, that recognizes the word "cat". A struct is used to
simulate a recursive function type.
#include <iostream>
struct state_t;
typedef state_t state(char c);
struct state_t
{
state_t(state* p): process(p) { }
state *function;
};
state_t start(char);
state_t got_c(char);
state_t got_a(char);
state_t terminal(char);
state_t start(char c)
{
if (c == 'c') return state_t(got_c);
else return state_t(start);
}
state_t got_c(char c)
{
if (c == 'a') return state_t(got_a);
else if (c == 'c') return state_t(got_c);
else return state_t(start);
}
state_t got_a(char c)
{
if (c == 't') return state_t(terminal);
else if (c == 'c') return state_t(got_c);
else return state_t(start);
}
state_t terminal(char)
{
return state_t(0);
}
int main ()
{
char m[]="The fat cat sits on the hat.";
state_t machine = start;
int i;
int len = strlen(m);
for (i = 0; i < len && machine.function != terminal; ++i) {
machine = machine.function(m[i]);
}
if (i != len) {
std::cout << "found \"cat\" at " << i-2 << '\n';
} else {
std::cout << "\"cat\" not found.\n";
}
return 0;
}
It might be more efficient on your implementation to use generic
function pointers to simulate the recursive return type. I didn't
do that here since I find it more confusing.
--
Neil Cerutti