🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.lang.c.moderated
3 messages
3 total messages Started by terres Sun, 31 Mar 1996 16:43
State engine
#2442
Author: terres
Date: Sun, 31 Mar 1996 16:43
24 lines
995 bytes
Hello!

I think that when you have complex problem like many conditions, paths 
and cases, a traditional program could be to big and inneficient on 
execution.

I have seen a system that uses a state engine that triggers some pieces 
of code when an encounters take effect between: states & stimuli.

Like this:
        Stimuli
State | 1  2  3
1     |           
2     |
3     |

When some conditions are acomplished some specific pieces of code are 
executed and that pieces send the control to another crosspoint.

I want to know how to implement this idea in C.

Thanks

Austin
Re: State engine
#2446
Author: Kazimir Kylheku
Date: Mon, 01 Apr 1996 13:19
178 lines
4386 bytes
In article <4jmcoa$lri@solutions.solon.com>,
terres  <terres@servidor.dgsca.unam.mx> wrote:
>Hello!
>
>I think that when you have complex problem like many conditions, paths 
>and cases, a traditional program could be to big and inneficient on 
>execution.
>
>I have seen a system that uses a state engine that triggers some pieces 
>of code when an encounters take effect between: states & stimuli.
>
>Like this:
>        Stimuli
>State | 1  2  3
>1     |           
>2     |
>3     |
>
>When some conditions are acomplished some specific pieces of code are 
>executed and that pieces send the control to another crosspoint.
>
>I want to know how to implement this idea in C.

There are all kinds of ways. One is to simply have nested switch statements:

	switch (state) {
	case 1:
		switch(stimulus) {
			case 1:
				do_something();
				state = 2;
				break;
			case 2:
				do_something_else();
				state = 3;
				break;
			case 3:
				break;
		}
		break;
	case 2:
		break;
	case 3:
		break;
	default:
		/* shouldn't reach this	*/
		break;
	}

You fill in the missing bits from the table. If you move a lot of the work to
functions, you can keep the switch statement manageable.

Another way is to assing to each state/input combination a function. The
functions don't have to be unique. For instance, if you have a lot of
state/input pairs that do nothing, you can assign to them a function called
idle(). To each state/input combination, you also assign a number which tells
it what state to go into next after the action is called:

enum states {
	IDLE, HUNGRY, SLEEPING, IRRITATED, NUMSTATES
};

enum inputs {
	FOOD, BELL, NEW_AGE_MUSIC, TIMER, NUMINPUTS
};

typedef void (* action_fun)(void);

struct actiongoto {
	action_fun action;
	int go;
};

void idle(void);
void eat(void);
void salivate(void);
void growl(void);

static struct actiongoto statetable[NUMSTATES][NUMINPUTS] =
{
	{	/* IDLE state	*/
		{ idle, IDLE },		/* FOOD input		*/
		{ idle, IDLE },		/* BELL input		*/
		{ idle, SLEEPING },	/* NEW_AGE_MUSIC input	*/
		{ idle, HUNGRY },	/* TIMER input		*/
	},
	{	/* HUNGRY state	*/
		{ eat, IDLE },		/* eat FOOD, be idle	*/
		{ salivate, HUNGRY },	/* salivate on BELL	*/
		{ growl, IRRITATED },	/* growl on music	*/
		{ idle, HUNGRY },	/* stay hungry on timer	*/
	},	/* SLEEPING state */
	{
		{ idle, SLEEPING },
		{ idle, IDLE },		/* awake on bell	*/
		{ idle, SLEEPING },	/* stay asleep w/ music	*/
		{ idle, SLEEPING },
	},	/* IRRITATED state */
	{
		{ eat, IDLE },		/* soothing food	*/
		{ growl, IRRITATED },	/* bell is irritating	*/
		{ growl, IRRITATED },	/* so is new age music	*/
		{ idle, HUNGRY },	/* irritation timeout	*/
	}
};

To use the state table, you look at what state you are in, and what the input
is, and lookup the appropriate actiongoto structure in the two-dimensional
table. You invoke the given function pointer, and advance to the given state.

Assuming you start in the IDLE state, and a TIMER input happens, you call
function idle() and advance to the HUNGRY state. Then, when a BELL input
arrives, you salivate() and stay in the HUNGRY state, and so forth:

#include <stdio.h>

unsigned int getnextinput(void)

{
	unsigned int input;
	char *menu = 
		"Enter input\n\n"
		"0. FOOD\n"
		"1. BELL\n"
		"2. NEW_AGE_MUSIC\n"
		"3. TIMER\n";

	puts(menu);
	do {
		fputs(">",stdout);
		scanf("%u",&input);
	} while (input >= NUMINPUTS);

	return input;
}

int main()

{
	unsigned int input;
	unsigned int state = 0;

	while(1) {
		input = getnextinput();
		statetable[state][input].action();
		state = statetable[state][input].go;
	}

	return 0;
}

void eat(void)

{
	puts("Munch munch!");
}

void salivate(void)

{
	puts("drool!");
}

void growl(void)

{
	puts("grr!");
}

void idle(void)

{
	puts("yawn!");
}



-- 
Re: State engine
#2587
Author: Mike McCarty
Date: Sat, 13 Apr 1996 13:57
58 lines
1869 bytes
In article <4jmcoa$lri@solutions.solon.com>,
terres  <terres@servidor.dgsca.unam.mx> wrote:
)Hello!
)
)I think that when you have complex problem like many conditions, paths 
)and cases, a traditional program could be to big and inneficient on 
)execution.
)
)I have seen a system that uses a state engine that triggers some pieces 
)of code when an encounters take effect between: states & stimuli.
)
)Like this:
)        Stimuli
)State | 1  2  3
)1     |           
)2     |
)3     |
)
)When some conditions are acomplished some specific pieces of code are 
)executed and that pieces send the control to another crosspoint.
)
)I want to know how to implement this idea in C.
)
)Thanks
)
)Austin


typedef enum { InActive, Ready, RarinToGo } State_t;
#define LastState RarinToGo

typedef enum { CountDown, Ignition, LiftOff } Event_t;
#define LastEvent LiftOff

typedef struct {
	State_t	NextState;
	void	(*action)(void);
} StMachine_t

void	GetReady(void);

StMachine_t	StateMachine[LastState+1][LastEvent+1] = {
/* InActive */	{
  /* Countdown */	{ Ready, GetReady},
  /* Ignition  */	{ 

...
}

void	HandleState(State_t *State,Event_t Event) {
	StateMachine[*State][Event].action();
	*State = StateMachine[*State][Event].NextState;
}
-- 
----
char *p="char *p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}

I don't speak for DSC.         <- They make me say that.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads