有限状态机/FSM

有限状态机(FSM)的设计与实现(一)

有限状态机(FSM)是表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用。通常FSM包含几个要素:状态的管理、状态的监控、状态的触发、状态触发后引发的动作。本文主要阐述一下状态机的几种设计方法。

1:switch case/if else设计方法

复制代码
curEvent = getEvent();
curState = getCurState();
switch(curState)
{case state1:{switch(curEvent ){TODO...setCurState();break; }break;}...
}
复制代码

这种设计方法最简单,通过一大堆判断来处理,适合小规模的状态切换流程,但如果规模扩大难以扩展和维护。

2:基于表结构的状态机设计方法:建立相应的状态表和动作查询表,根据状态表、事件、动作表定位相应的动作处理函数,执行完成后再进行状态的切换。

一个通用的状态机处理模块的设计如下:

复制代码
/*状态表注册*/
void
FSM_Regist(FSM_T* pFsm,STATE_TABLE_S* pStateTable) {pFsm->FsmTable = pStateTable;return; } /*状态迁移*/ void FSM_MoveState(FSM_T* pFsm,int state) {pFsm->curState = state;return; }
/*事件处理*/
void FSM_EventHandle(FSM_T* pFsm,int event) {ACT_TABLE_T* pActTable = NULL;ActFun eventActFun = NULL;/*获取当前状态动作表*/pActTable = FSM_getActTable(pFsm);/*获取当前动作函数*/for(int i=0;i<MAX_ACT_NUM;i++){if(event == pActTable[i].event){eventActFun = pActTable[i].eventActFun;break;}}/*动作执行*/if(eventActFun){eventActFun(pFsm);} }
复制代码

假设我们的状态图如下:


相应的状态机设置如下:

复制代码
/*状态1的动作表*/
ACT_TABLE_T state1ActTable[] = {{EVENT1,state1Event1Fun},{EVENT3,state1Event3Fun},
};
/*状态2的动作表*/
ACT_TABLE_T state2ActTable[] = {{EVENT2,state2Event2Fun},
};
/*状态表*/
STATE_TABLE_T FsmTable[] = {{STATE1,state1ActTable},{STATE2,state2ActTable},
};int main(int argc, _TCHAR* argv[])
{FSM_T fsm;/*状态表注册*/FSM_Regist(&fsm,FsmTable);FSM_MoveState(&fsm,STATE1);FSM_EventHandle(&fsm,EVENT1);FSM_EventHandle(&fsm,EVENT2);return 0;
}
/*客户端提供的状态处理函数*/
void state1Event1Fun(void* pFsm) {FSM_MoveState((FSM_T*)pFsm,STATE2);
return; } void state1Event3Fun(void* pFsm) {FSM_MoveState((FSM_T*)pFsm,STATE3);
return; } void state2Event2Fun(void* pFsm) {FSM_MoveState((FSM_T*)pFsm,STATE3);
return; }

通过设计一个通用的基于表结构的状态机模块,针对不同的状态图,我们只需要根据状态图得到其状态表结构,然后通过FSM_Regist注册,就可以方便的使用了状态机的功能了。这种机制便于我们添加新的状态流程,并且可以很好的进行分层状态机的设计。

复制代码转载请注明原始出处:http://www.cnblogs.com/chencheng/archive/2012/06/25/2562660.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/509871.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

web通讯录之通讯录主界面

界面展示&#xff1a; 界面所用的素材网址点击打开链接&#xff0c;在用网上素材时候首先要把代码看懂才能进行修改&#xff0c;因此希望读者好好看看源码&#xff0c;看的时候着重看看字母排序原理、JQuery设计等等。 分组展示&#xff1a;这个地方有个不好的地方&#xff0c…

NameNode 启动失败 - There appears to be a gap in the edit log. We expected txid xxx, but got tx

场景 NameNode迁移&#xff0c;导致一个节点无法启动 异常 在Namenode主动迁移&#xff0c;或者Namenode机器挂掉无法恢复时&#xff0c;我们需要Namenode节点迁移&#xff0c;迁移经常会出现一个NameNode启动成功&#xff0c;另外一个standby启动失败&#xff0c;报错如下 …

opengl光照

看一张图片&#xff1a; 图中绘制了两个大小相同的白色球体。其中右边的一个是没有使用任何光照效果的&#xff0c;它看起来就像是一个二维的圆盘&#xff0c;没有立体的感觉。左边的一个是使用了简单的光照效果的&#xff0c;我们通过光照的层次&#xff0c;很容易的认为它是一…

Nifi 之 kafka消费存入hbase

添加kafka processor&#xff0c;配置如下 kakfa数据格式为JSON&#xff1a; {"events_tag":"103913","query_word":"华大癌变 虎嗅","time":"2018-08-09 13:01:11"} 添加putHbaseJSON&#xff0c;json格式添加数…

web通讯录之搜索功能

手机号搜索&#xff1a; 姓名搜索&#xff1a; 拼音搜索&#xff1a; 城市搜索&#xff1a; 性别搜索&#xff1a; 点击姓名或者电话显示完整信息 相信大家期待自己所写的搜索功能类似于百度、谷歌这种搜索引擎&#xff0c;有兴趣的读者可以去学学SEO&#xff0c;在这里我…

Hbase 删表过程

Hbase 执行删表命令后(drop)&#xff0c;表的数据会移动到 /hbase/archive 目录下&#xff0c;并不会直接从hdfs删除&#xff0c;后台会有进程定期去检查&#xff08;默认五分钟&#xff09;&#xff0c;如果这张表没有快照则会删除&#xff0c;有快照会保留数据。 刚drop时&a…

opengl纹理单元

可以这样简单的理解为&#xff1a;显卡中有N个纹理单元&#xff08;具体数目依赖你的显卡能力&#xff09;&#xff0c;每个纹理单元&#xff08;GL_TEXTURE0、GL_TEXTURE1等&#xff09;都有GL_TEXTURE_1D、GL_TEXTURE_2D等&#xff0c;如下代码&#xff1a; [cpp] view plain…

Spark 创建 hive表报错 ROW FORMAT DELIMITED is only compatible with 'textfile', not 'parquet'

场景&#xff1a; 在spark分析数据时&#xff0c;创建hive表失败。 提示异常 &#xff1a; 19/10/09 10:59:18 INFO execution.SparkSqlParser: Parsing command: CREATE EXTERNAL TABLE IF NOT EXISTS dm_xxx.user_area(biFollowersCount String,city String,created_at Str…

多重纹理和纹理组合器

多重纹理和纹理组合器 本文主要介绍OpenGL中两种技术的使用方法&#xff1a;多重纹理技术和纹理组合器技术&#xff0c;最终根据参考【2】中的代码&#xff0c;实现了两个简单的演示DEMO&#xff0c;其中使用到了《八叉树颜色量化、BMP、TGA文件解析》篇章中提供的图像解析类。…

ClouderaManager agent 报错,无法连接到结群 Error, CM server guid updated, expected xxx , received xxx

场景 集群版本&#xff1a;CDH 6.0.1 服务器版本&#xff1a;Centos 7.3 JAVA版本&#xff1a;1.8 异常出现原因 搭建集群中遇到异常&#xff0c;删除agent节点&#xff0c;重新部署CM后发现异常&#xff0c;CDH处于无法使用状态 异常 查看agent日志会出现,说无法连接到…

CDH Kerberos 认证下Kafka 消费方式

集群Kerberos认证安装参考&#xff1a;https://datamining.blog.csdn.net/article/details/98480008 目录 环境&#xff1a; 配置 Java Producer 代码 文件内容&#xff1a; kafka_client_jaas.conf krb5.conf ( kerberos 配置文件复制过来即可) kafka.keytab Java Co…

IntelliJ IDEA Maven jar包冲突解决,快速发现jar包冲突

IntelliJ IDEA 自带的Diagrams 去查看jar包冲突相当费劲 ~ &#xff0c;安装个插件即可快速解决该问题 打开Settings&#xff0c;搜索maven helper&#xff0c;并安装 安装完成后&#xff0c;直接打开pom文件&#xff0c;点击Dependency Analyzer 删除冲突jar包&#xff0c;在…

osg基本图元

OSG绘制几何体学习总结&#xff08;超全&#xff09;在osg中&#xff0c;场景图形采用一种自顶向下的&#xff0c;分层的树状数据结构来组织空间数据集&#xff0c;以提高渲染的效率 场景图形树结构的顶部是一个根节点&#xff0c;从根节点向下延伸&#xff0c;各个组节点中均包…

如何用css设计出商品购物图片

代码&#xff1a; 常见问题&#xff1a;背景填充时候图片大小不一致、重复等等问题&#xff0c;建议在插入图片的时候最好不用img标签直接在div中添加背景图片&#xff0c;有利于对背景图片的更改。 插入图片&#xff1a;background-image: url(../img/product-auto/benz-amg-s…

OLTP、OLAP与HTAP 区别

OLTP On-Line Transaction Processing联机事务处理过程(OLTP) 也称为面向交易的处理过程&#xff0c;其基本特征是前台接收的用户数据可以立即传送到计算中心进行处理&#xff0c;并在很短的时间内给出处理结果&#xff0c;是对用户操作快速响应的方式之一。 这样做的最大优点…

osg布告板技术(Billboard)

公告牌技术,即billboard技术,在3D游戏中有着广泛的应用.它的本质就是用预先做好的几幅 位图来代替3D物体,极大地节省资源和提高速度.仔细观察<<魔法门>>系列游戏,它的精灵,树木,物 品都是二维图象,但由于它始终朝向观察者,你根本看不到它"扁"的一面,所以…

osg坐标系转换

osg中将局部坐标系下的点坐标换算成全局坐标系下点的坐标 标签&#xff1a; matrixlist2012-05-17 16:27 2940人阅读 评论(1) 收藏 举报分类&#xff1a;osg&#xff08;7&#xff09; 坐标变换版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 今天…

C#/WPF 播放音频文件

C#播放音频文件的方式&#xff1a; 播放系统事件声音使用System.Media.SoundPlayer播放wav使用MCI Command String多媒体设备程序接口播放mp3&#xff0c;wav&#xff0c;avi等使用WindowsMediaPlayer的COM组件来播放(可视化)使用DirectX播放音频文件使用Speech播放(朗读器&am…

Hbase 二级索引 Solr int字段排序问题 can not sort on multivalued field

Hbase Solr 同步二级索引后&#xff0c;进行int字段排序时报错 报错如下 {"responseHeader":{"zkConnected":true,"status":400,"QTime":75,"params":{"q":"*:*","sort":"hbase_index…

OpenGL渲染管线,着色器,光栅化等概念理解

卧槽&#xff0c;前些日子看这几个概念就十分想吐槽&#xff0c;这么难理解的概念窃以为纯属翻译的不够接地气。————首先&#xff0c;光栅化&#xff08;Rasterize/rasteriztion&#xff09;。这个词儿Adobe官方翻译成栅格化或者像素化。没错&#xff0c;就是把矢量图形转化…