【状态机】C语言实现的,兼如何做宏展开

状态机的原理,请参阅文章:

《状态机编程》:http://blog.csdn.net/tomsen00/article/details/4932789

《维基百科-自动机编程》:http://zh.wikipedia.org/wiki/%E5%9F%BA%E4%BA%8E%E8%87%AA%E5%8A%A8%E6%9C%BA%E7%BC%96%E7%A8%8B

我感觉上面的文章已经讲的非常清楚了。下面是一个基于C语言实现的,作为记录:

#include <stdio.h>

#define SINGLE_STATE_MAX_EVENT 10
typedef int FSM_EVENT_ID;
typedef struct event_param_st
{
	FSM_EVENT_ID id;
	union
	{
		int i;
	}data;
}FSM_EVENT;

typedef int FSM_STATE_ID;
typedef void (*FSM_FUNC)(FSM_EVENT *);
typedef struct state_event_st
{
	FSM_FUNC func;
	FSM_EVENT_ID event;
	FSM_STATE_ID state;
}FSM_STATE_EVENT;

typedef struct state_st
{
	FSM_STATE_ID id;
	char *name;
	FSM_FUNC enter_func;
	FSM_FUNC exit_func;
	FSM_FUNC default_func;
	FSM_STATE_EVENT event_table[SINGLE_STATE_MAX_EVENT]; 
}FSM_STATE;
typedef FSM_STATE STATE_TABLE[];
typedef FSM_STATE * PTR_STATE_TABLE;
#define END_EVENT_ID -1
#define END_STATE_ID -1
#define BEGIN_FSM_STATE_TABLE(state_stable) static STATE_TABLE state_stable={
#define BEGIN_STATE(id,name,enter_func,exit_func,default_func) {id,name,enter_func,exit_func,default_func,{
#define STATE_EVENT_ITEM(func,event,state) {func,event,state},
#define END_STATE(id) {NULL,END_EVENT_ID,END_STATE_ID}}},
#define END_FSM_STATE_TABLE(state_stable) {END_STATE_ID,NULL,NULL,NULL,NULL,NULL}};

typedef struct fsm_st
{
	FSM_STATE_ID state_id;
	FSM_FUNC default_func;
	PTR_STATE_TABLE state_tables;
	
}FSM;

void fsm_do_event(FSM &fsm, FSM_EVENT &event)
{
	FSM_STATE *state=&(fsm.state_tables[fsm.state_id]);
	int i=0;
	while(state->event_table[i].event!=END_EVENT_ID)
	{
		if(state->event_table[i].event==event.id)
			break;
		i++;
	}
	if(state->event_table[i].event!=END_EVENT_ID)
	{
		if(state->id!=state->event_table[i].state)
		{
			if(state->exit_func ) 
				state->exit_func(&event);
		}
		if(state->event_table[i].func)
			state->event_table[i].func(&event);
		
		if(state->id!=state->event_table[i].state)
		{
			if(fsm.state_tables[state->event_table[i].state].enter_func) 
				fsm.state_tables[state->event_table[i].state].enter_func(&event);
			fsm.state_id=state->event_table[i].state;
		}
	}
	else
	{
		if(state->default_func)
			state->default_func(&event);
		else
		{
			if(fsm.default_func)
				fsm.default_func(&event);
		}
	}
}

void enter_fsm(FSM_EVENT * event)
{
	printf("enter me\n");
}
void exit_fsm(FSM_EVENT * event)
{
	printf("exit me\n");
}
void defualt_fsm(FSM_EVENT * event)
{
	printf("i am defualt_fsm\n");
}
void func_fsm(FSM_EVENT * event)
{
	printf("i am func_fsm\n");
}



BEGIN_FSM_STATE_TABLE(my_state_table)
	BEGIN_STATE(0, "first", enter_fsm, exit_fsm, defualt_fsm)
	STATE_EVENT_ITEM(func_fsm, 1, 1)
	STATE_EVENT_ITEM(func_fsm, 2, 2)
	END_STATE(0)

	BEGIN_STATE(1,"second", enter_fsm,exit_fsm, defualt_fsm)
	STATE_EVENT_ITEM(func_fsm, 1, 2)
	STATE_EVENT_ITEM(func_fsm, 2, 0)
	END_STATE(1)

	BEGIN_STATE(2,"third", enter_fsm,exit_fsm, defualt_fsm)
	STATE_EVENT_ITEM(func_fsm, 1, 0)
	STATE_EVENT_ITEM(func_fsm, 2, 1)
	END_STATE(2)
END_FSM_STATE_TABLE(my_state_table)



int main()
{
	printf("i am main\n");
	FSM fsm={0, defualt_fsm, my_state_table};
	printf("state[%d],name[%s]\n", fsm.state_id, fsm.state_tables[fsm.state_id].name);

	FSM_EVENT event;
	event.id=1;
	event.data.i=1;
	fsm_do_event(fsm, event);
	printf("state[%d],name[%s]\n",fsm.state_id,fsm.state_tables[fsm.state_id].name);

	return 0;
}

因为大量的使用了宏定义,阅读程序非常困难,在VC的开发环境里,【项目】--【设置】--【C++】底下的选项中添加“/P”(大写),编译时可以得到一个.i的宏展开文件,下面是摘自上述最复杂的一部分展开后的:

static STATE_TABLE my_state_table={
	{0,"first",enter_fsm,exit_fsm,defualt_fsm,{
	{func_fsm,1,1},
	{func_fsm,2,2},
	{0,-1,-1}}},

	{1,"second",enter_fsm,exit_fsm,defualt_fsm,{
	{func_fsm,1,2},
	{func_fsm,2,0},
	{0,-1,-1}}},

	{2,"third",enter_fsm,exit_fsm,defualt_fsm,{
	{func_fsm,1,0},
	{func_fsm,2,1},
	{0,-1,-1}}},
{-1,0,0,0,0,0}};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值