﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>YuYuYouEr工作室 &#187; 状态机</title>
	<atom:link href="http://www.yuyuyouer.cn/blog/?feed=rss2&#038;tag=%E7%8A%B6%E6%80%81%E6%9C%BA" rel="self" type="application/rss+xml" />
	<link>http://www.yuyuyouer.cn/blog</link>
	<description>AREA OF 雨雨油儿 ~~ 承接体感互动软件、游戏定制开发 ~~</description>
	<lastBuildDate>Sat, 30 Mar 2024 16:41:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>Kinect超时按钮实现 &#8211; 基于qfFSM有限状态自动机类库</title>
		<link>http://www.yuyuyouer.cn/blog/?p=347</link>
		<comments>http://www.yuyuyouer.cn/blog/?p=347#comments</comments>
		<pubDate>Tue, 23 Jul 2013 17:06:20 +0000</pubDate>
		<dc:creator>rabbit5455</dc:creator>
				<category><![CDATA[kinect]]></category>
		<category><![CDATA[qfFSM有限自动机]]></category>
		<category><![CDATA[体感浏览器]]></category>
		<category><![CDATA[Button]]></category>
		<category><![CDATA[fsm]]></category>
		<category><![CDATA[Web体感应用]]></category>
		<category><![CDATA[YuYuYouEr]]></category>
		<category><![CDATA[有限状态自动机]]></category>
		<category><![CDATA[有限自动机]]></category>
		<category><![CDATA[状态机]]></category>

		<guid isPermaLink="false">http://www.yuyuyouer.cn/blog/?p=347</guid>
		<description><![CDATA[qfFSM有限状态自动机类库目前拥有C++、C#、Java、JavaScript版本，对于同一份UML状态图，不同语言均可用qfFSM来实现。 本文使用JavaScript版本在浏览器中实现一个超时按钮，为方便测试，我使用鼠标指针来模拟Kinect关节，接入Kinect数据后，只需将手部关节坐标替换进来即可。 首先看超时按钮的UML状态图： 主状态机中有STATE_Normal、STATE_PointIn、STATE_PointOut三个状态，其中后面两个作为子状态机存在，他们内部分别含有3个状态：激活/非激活开始状态、正在激活/非激活状态、已激活/非激活状态。 设计 正在激活/非激活状态 是为了配合相应动画机制，如经典的按钮注水、按钮转满一周等计时方式。 事件方面支持UserLeave、PointIn、PointOut，以及MultiActive（多次连续激活）。 MultiActive机制可以很方便的实现 保持按住按钮，系统会周期触发某个事件。 源码中分为以下几个部分： 1、首先定义了各种常量：状态名称、事件名称、属性名称： var timeoutButton_const_def = { &#8230; }; 2、定义数据模型Model实现类： var TimeoutButton_Model = { &#8230; }; 在Model中定义各种属性，如激活时间、指针是否在对象可视范围内、计时器开始和结束。 3、定义各个子状态机、状态的实现类，他们分别继承自qfStateMachine/qfState基类，并实现doAction()事件： var State_Normal = { &#8230; }; var STATE_PointIn = { &#8230; }; var STATE_PointOut = { &#8230; }; var STATE_Active_start = { &#8230; }; var STATE_Activing = { [...]]]></description>
			<content:encoded><![CDATA[<p>qfFSM有限状态自动机类库目前拥有C++、C#、Java、JavaScript版本，对于同一份UML状态图，不同语言均可用qfFSM来实现。</p>
<p>本文使用JavaScript版本在浏览器中实现一个超时按钮，为方便测试，我使用鼠标指针来模拟Kinect关节，接入Kinect数据后，只需将手部关节坐标替换进来即可。</p>
<p>首先看超时按钮的UML状态图：</p>
<p><a href="http://www.yuyuyouer.cn/blog/wp-content/uploads/2013/07/kinect_NUI_Button_timeout_detect.jpg"><img class="alignnone size-full wp-image-348" title="kinect_NUI_Button_timeout_detect" src="http://www.yuyuyouer.cn/blog/wp-content/uploads/2013/07/kinect_NUI_Button_timeout_detect.jpg" alt="" width="491" height="293" /></a></p>
<p>主状态机中有STATE_Normal、STATE_PointIn、STATE_PointOut三个状态，其中后面两个作为子状态机存在，他们内部分别含有3个状态：激活/非激活开始状态、正在激活/非激活状态、已激活/非激活状态。</p>
<p>设计 正在激活/非激活状态 是为了配合相应动画机制，如经典的按钮注水、按钮转满一周等计时方式。</p>
<p>事件方面支持UserLeave、PointIn、PointOut，以及MultiActive（多次连续激活）。</p>
<p>MultiActive机制可以很方便的实现 保持按住按钮，系统会周期触发某个事件。</p>
<p>源码中分为以下几个部分：</p>
<p><span id="more-347"></span></p>
<p>1、首先定义了各种常量：状态名称、事件名称、属性名称：</p>
<blockquote><p>var timeoutButton_const_def = { &#8230; };</p></blockquote>
<p>2、定义数据模型Model实现类：</p>
<blockquote><p>var TimeoutButton_Model = { &#8230; };</p>
<p>在Model中定义各种属性，如激活时间、指针是否在对象可视范围内、计时器开始和结束。</p></blockquote>
<p>3、定义各个子状态机、状态的实现类，他们分别继承自qfStateMachine/qfState基类，并实现doAction()事件：</p>
<blockquote><p>var State_Normal =  { &#8230; };</p>
<p>var STATE_PointIn = { &#8230; };</p>
<p>var STATE_PointOut = { &#8230; };</p>
<p>var STATE_Active_start = { &#8230; };</p>
<p>var STATE_Activing = { &#8230; };</p>
<p>var STATE_Actived = { &#8230; };</p>
<p>var STATE_DeActive_start = {&#8230; };</p>
<p>var STATE_DeActiving = { &#8230; };</p>
<p>var STATE_DeActived = { &#8230; };</p></blockquote>
<p>4、定义了主逻辑状态机，继承自qfFsmLogic基类：</p>
<blockquote><p>var timeoutButton_Logic = { &#8230; };</p>
<p>其中核心方法为状态机初始化函数（initTimeoutButtonMachine()成员函数），包含三个方面：</p>
<p>1）设置状态机环境变量，此处只设置数据模型Model，以便各个状态获取数据属性。</p>
<p>2）实例化各个子状态机、状态，并绑定到各自父状态机中。</p>
<p>3）配置状态转移规则，这里完成对UML状态图的描述翻译。</p></blockquote>
<p>5、实例化主逻辑状态机，并调用他的start()方法：</p>
<blockquote><p>var timeoutButton = timeoutButton_Logic.createNewInstance();</p>
<p>timeoutButton.start();</p></blockquote>
<p>6、绑定mouseover、mouseout事件，完成OnTimer()函数，将来的Kinect数据获取也是一个周期性事件，直接放在此处即可。</p>
<p>7、最后是界面的Html代码，其中包含一个多次激活标志checkbox、还有一个支持超时激活的按钮（DIV实现），如下图：</p>
<blockquote><p>其中Current State为状态机当前状态，可以实时看到状态转移过程。</p>
<p><a href="http://www.yuyuyouer.cn/blog/wp-content/uploads/2013/07/kinect_timeoutButton_UI.jpg"><img class="alignnone size-full wp-image-356" title="kinect_timeoutButton_UI" src="http://www.yuyuyouer.cn/blog/wp-content/uploads/2013/07/kinect_timeoutButton_UI.jpg" alt="" width="394" height="356" /></a></p></blockquote>
<p>实现DEMO展示Url：<a href="http://www.YuYuYouEr.cn/code/qfFSM_for_javascript_kinect_timeoutButton/timeoutButton_State_Machine_Test.html" target="_blank">qfFSM_for_javascript_kinect_timeoutButton</a></p>
<p>源代码右键查看即可。</p>
<p>qfFSM各版本源码下载：<a href="http://www.yuyuyouer.cn/blog/?p=290" target="_blank">http://www.YuYuYouEr.cn/blog/?p=290</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yuyuyouer.cn/blog/?feed=rss2&#038;p=347</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>有限状态自动机类库 &#8211; qfFSM</title>
		<link>http://www.yuyuyouer.cn/blog/?p=290</link>
		<comments>http://www.yuyuyouer.cn/blog/?p=290#comments</comments>
		<pubDate>Mon, 29 Apr 2013 15:18:44 +0000</pubDate>
		<dc:creator>rabbit5455</dc:creator>
				<category><![CDATA[qfFSM有限自动机]]></category>
		<category><![CDATA[Unity3D]]></category>
		<category><![CDATA[fsm]]></category>
		<category><![CDATA[有限状态自动机]]></category>
		<category><![CDATA[有限自动机]]></category>
		<category><![CDATA[状态机]]></category>

		<guid isPermaLink="false">http://www.yuyuyouer.cn/blog/?p=290</guid>
		<description><![CDATA[给自己开发了一套有限状态自动机类库，满足基本的状态转移需求，有需要的朋友拿去玩吧。 boost库中自动机还是比较强大的，不过确实比较大，而且我的项目要求可在运行时修改状态机的配置。 &#160; 源码下载地址： qfFSM 百度网盘 C++版本：qfFSM_for_cpp_v1.2.zip Java版本：qfFSM_for_java_v1.2.zip JavaScript版本：qfFSM_for_javascript_v1.2.zip C#版本：qfFSM_for_csharp_v1.2.zip Unity3D(C#)版本：qfFSM_for_unity3d_csharp_v1.2.zip 压缩包内含有一个简单的 StopWatch例程，UML状态图如下： 类库非常小，文件列表及说明如下： qfState.h/.cpp：状态 qfStateMachine.h/.cpp：状态机，由状态、事件、转移规则组成，继承自qfState，可作为另一个状态机的子状态 qfEvent.h：事件，状态机的激励 PropertyBag.h：属性包，每个qfEvent都有一个属性包 qfFSM.h/.cpp：qfFsmLogic类，对qfStateMachine进行封装，提供一个大粒度状态机基类，状态机开始、停止、重置，状态机子状态管理。 ================================ qfState状态有四个响应函数： entryAction：进入状态 doAction：执行本状态操作，目前的设计中，doAction会在entryAction执行后立即执行 exitAction：退出状态 onNotify：通知，如果本状态没有针对当前事件的转移规则，将会收到一个onNotify通知，完成一些特殊的事件处理需求 ================================ qfStateMachine状态机内可以设置状态转移规则、绑定状态实现、处理外部事件 状态机内的转移规则配置由源状态名称、事件名称、目标状态名称组成，支持自动转移规则，可选择性的为一个状态绑定自定义的qfState对象实例，完成相应功能，运行时可随时修改这些绑定，切换另一个qfState实现，改变状态行为，当然转移规则也是可以运行时修改的。 状态机还支持设置环境变量，状态机嵌套时，父子状态机环境变量相互独立。 setTransfer(srcStateName, eventName, destStateName)：设置转移规则 setAutoTransfer(srcStateName, destStateName)：设置一条自动转移规则 setState(stateName, qfState*)：绑定状态实现。 getRootENV()：得到根状态机环境变量，多层状态机嵌套时很有用。 processAllEvent(qfEvent&#38;)：处理事件堆栈中的事件，阻塞方式，直到队列为空，将一个外部事件传入，状态机将查找转移规则，如果当前状态没有设置此事件转移，将会收到onNotify通知调用，此事件将冒泡给上层状态处理。 postEvent(qfEvent&#38;)：将事件放入事件堆栈。 processSingleEvent（qfEvent&#38;)：处理单个事件。 关于事件堆栈：postEvent()将事件压栈，processAllEvent()每次从栈顶取出事件，交由processSingleEvent()处理。 ================================ qfEvent事件拥有事件名称、属性集合（由qfPropertyBag实现） qfPropertyBag继承自std::map，用于存放&#60;key, value&#62;，可通过定义SUPPORT_BOOST_ANY_PROPERTY宏使用boost::any来作为value，否则使用void *作为value。 ================================ qfFsmLogic是对状态机的封装，用于方便实现独立逻辑组件，提供start/stop/reset实现，qfState状态对象自动析构 setupStateMachine()：一般只需要重写这个函数，完成环境变量配置、转移规则配置、状态对象绑定。 start()：调用此函数后，状态机被初始化，可以执行processAllEvent()。 ================================ 发布历史： 2014年10月23日 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; 更新所有版本到v1.2； [...]]]></description>
			<content:encoded><![CDATA[<p>给自己开发了一套有限状态自动机类库，满足基本的状态转移需求，有需要的朋友拿去玩吧。</p>
<p>boost库中自动机还是比较强大的，不过确实比较大，而且我的项目要求可在运行时修改状态机的配置。</p>
<p>&nbsp;</p>
<p>源码下载地址：</p>
<p><a href="https://pan.baidu.com/s/1Oo1dudhuziljvJ6vkpHLfQ?pwd=vihb" target="_blank">qfFSM 百度网盘</a></p>
<p>C++版本：qfFSM_for_cpp_v1.2.zip</p>
<p>Java版本：qfFSM_for_java_v1.2.zip</p>
<p>JavaScript版本：qfFSM_for_javascript_v1.2.zip</p>
<p>C#版本：qfFSM_for_csharp_v1.2.zip</p>
<p>Unity3D(C#)版本：qfFSM_for_unity3d_csharp_v1.2.zip</p>
<p>压缩包内含有一个简单的 StopWatch例程，UML状态图如下：</p>
<p><a href="http://www.yuyuyouer.cn/blog/wp-content/uploads/2013/04/StopWatch_StatechartDiagram.jpg" target="_blank"><img class="alignnone size-full wp-image-293" title="StopWatch_StatechartDiagram" src="http://www.yuyuyouer.cn/blog/wp-content/uploads/2013/04/StopWatch_StatechartDiagram.jpg" alt="" width="476" height="209" /></a></p>
<p>类库非常小，文件列表及说明如下：</p>
<p>qfState.h/.cpp：状态</p>
<p>qfStateMachine.h/.cpp：状态机，由状态、事件、转移规则组成，继承自qfState，可作为另一个状态机的子状态</p>
<p>qfEvent.h：事件，状态机的激励</p>
<p>PropertyBag.h：属性包，每个qfEvent都有一个属性包</p>
<p>qfFSM.h/.cpp：qfFsmLogic类，对qfStateMachine进行封装，提供一个大粒度状态机基类，状态机开始、停止、重置，状态机子状态管理。</p>
<p>================================</p>
<p><span id="more-290"></span></p>
<p><strong>qfState状态有四个响应函数</strong>：</p>
<p>entryAction：进入状态<br />
doAction：执行本状态操作，目前的设计中，doAction会在entryAction执行后立即执行<br />
exitAction：退出状态<br />
onNotify：通知，如果本状态没有针对当前事件的转移规则，将会收到一个onNotify通知，完成一些特殊的事件处理需求</p>
<p>================================</p>
<p><strong>qfStateMachine状态机内可以设置状态转移规则、绑定状态实现、处理外部事件</strong></p>
<p>状态机内的转移规则配置由源状态名称、事件名称、目标状态名称组成，支持自动转移规则，可选择性的为一个状态绑定自定义的qfState对象实例，完成相应功能，运行时可随时修改这些绑定，切换另一个qfState实现，改变状态行为，当然转移规则也是可以运行时修改的。</p>
<p>状态机还支持设置环境变量，状态机嵌套时，父子状态机环境变量相互独立。</p>
<p>setTransfer(srcStateName, eventName, destStateName)：设置转移规则</p>
<p>setAutoTransfer(srcStateName, destStateName)：设置一条自动转移规则</p>
<p>setState(stateName, qfState*)：绑定状态实现。</p>
<p>getRootENV()：得到根状态机环境变量，多层状态机嵌套时很有用。</p>
<p>processAllEvent(qfEvent&amp;)：处理事件堆栈中的事件，阻塞方式，直到队列为空，将一个外部事件传入，状态机将查找转移规则，如果当前状态没有设置此事件转移，将会收到onNotify通知调用，此事件将冒泡给上层状态处理。</p>
<p>postEvent(qfEvent&amp;)：将事件放入事件堆栈。</p>
<p>processSingleEvent（qfEvent&amp;)：处理单个事件。</p>
<p>关于事件堆栈：postEvent()将事件压栈，processAllEvent()每次从栈顶取出事件，交由processSingleEvent()处理。</p>
<p>================================</p>
<p><strong>qfEvent事件拥有事件名称、属性集合（由qfPropertyBag实现）</strong></p>
<p>qfPropertyBag继承自std::map，用于存放&lt;key, value&gt;，可通过定义SUPPORT_BOOST_ANY_PROPERTY宏使用boost::any来作为value，否则使用void *作为value。</p>
<p>================================</p>
<p><strong>qfFsmLogic是对状态机的封装，用于方便实现独立逻辑组件，提供start/stop/reset实现，qfState状态对象自动析构</strong></p>
<p>setupStateMachine()：一般只需要重写这个函数，完成环境变量配置、转移规则配置、状态对象绑定。</p>
<p>start()：调用此函数后，状态机被初始化，可以执行processAllEvent()。</p>
<p>================================</p>
<p>发布历史：</p>
<p><strong>2014年10月23日</strong><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
更新所有版本到v1.2；<br />
允许bind一个qfFSMLogic示例给一个状态；<br />
在qfStateMachine中增加reset()成员；<br />
修复qfEvent中m_PropertyBag未实例化的bug；</p>
<p><strong>2013年07月27日</strong><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
更新C#版本，含WinForm示例；<br />
版本号定为v1.1；</p>
<p><strong>2013年06月06日<br />
</strong>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
更新所有版本；<br />
版本号定为v0.1；<br />
状态机中增加事件堆栈，避免用递归来处理循环事件；</p>
<p><strong>2013年05月19日</strong><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
发布qfFSM_for_unity3d_csharp版本；</p>
<p><strong>2013年05月09日</strong><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
发布qfFSM_for_javascript版本；</p>
<p><strong>2013年05月07日</strong><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
发布qfFSM_for_java版本；</p>
<p><strong>2013年05月05日</strong><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
发布qfFSM_for_cpp版本；</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.yuyuyouer.cn/blog/?feed=rss2&#038;p=290</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
