Erlang OTP设计原则Gen_Fsm行为[转]
转自: http://www.cnblogs.com/yourihua/archive/2012/05/13/2497776.html
1. Fsm 称为 有限状态机,举个例子,游戏中的怪物称为NPC,NPC一般有几种状态,比如:静止,移动,死亡,被攻击,攻击英雄等等几个有限的状态,那么我们就可以有限状态机实现NPC的状态变更。
一个有限状态机可以用一个关系式来描述,State(静止状态S1) x Event(英雄进入视野范围事件E) -> Actions(开始移动动作A), State(移动状态S2)
解释如下:当一个NPC处于静止状态S1,有一个英雄进入NPC视野范围时E,会触发NPC开始移动动作A,并且NPC转变状态为移动状态S2。
对于一个用 gen_fsm 行为实现的FSM来说,状态转换规则被写为符合如下约定的一系列Erlang函数:
StateName( Event, StateData ) ->
.. 这里放动作的代码 ...
{ next_state, StateName', StateData' }
2. 接下来我们来看个例子,游戏中NPC状态变化,当然我做了很大的简化,真正游戏中的逻辑比这复杂的多。这里我只是为了说明,erlang OTP设计原则中的gen_fsm如何使用,代码如下:
-module(npc). -behaviour(gen_fsm). %% API
-export([start_link/0]). %% gen_fsm callbacks
-export([init/1, static/2, moving/2, handle_event/3,
handle_sync_event/4, handle_info/3, terminate/3, code_change/4]). -export([hero_join/0, hero_leave/0]). -define(SERVER, ?MODULE). -record(npc, {state}). start_link() ->
gen_fsm:start_link({local, ?SERVER}, ?MODULE, [], []). %% 初始化NPC为静止状态
init([]) ->
io:format("init...~n"),
State = #npc{state = static},
io:format("init State: ~p~n", [State]),
{ok, static, State}. %% 英雄进入视野
hero_join() ->
gen_fsm:send_event(?SERVER, hero_join). %% 英雄离开视野
hero_leave() ->
gen_fsm:send_event(?SERVER, hero_leave). %% 静止状态下,接受来自客户端的事件
static(Event, State) ->
case Event of
hero_join -> %% 英雄进入视野
do_moving(), %% 执行动作
NewState = State#npc{state = moving},
io:format("npc set state: ~p~n", [NewState]),
{next_state, moving, NewState}
end. %% 移动状态下,接受来自客户端的事件
moving(Event, State) ->
case Event of
hero_leave -> %% 英雄离开视野
do_static(), %% 执行动作
NewState = State#npc{state = static},
io:format("npc set state: ~p~n", [NewState]),
{next_state, static, NewState}
end. handle_event(_Event, StateName, State) ->
{next_state, StateName, State}. handle_sync_event(_Event, _From, StateName, State) ->
Reply = ok,
{reply, Reply, StateName, State}. handle_info(_Info, StateName, State) ->
{next_state, StateName, State}. terminate(_Reason, _StateName, _State) ->
ok. code_change(_OldVsn, StateName, State, _Extra) ->
{ok, StateName, State}. %% NPC 开始移动,进入移动状态
do_moving() ->
io:format("npc beigin moving...~n"). %% NPC 停止移动,进入静止状态
do_static() ->
io:format("npc stop moving, join static...~n").
代码注释比较详细,接下来可以通过运行代码,来好好理解下这个例子,
1. 首先,调用 npc:start_link(). 来初始化NPC服务;这个时候NPC处于静止状态 static;
2. 当npc处于静止状态时,我们通过调用 npc:hero_join().来表示有一个侠客进入NPC的视野,那么这个时候gen_fsm会默认调用当前gen_fsm处于的状态,也就是static的处理方法,也就是 static(Event, State) 这个函数,这边可能比较绕,我已经尽量去用直白的语言来表达,能力有限,大家多思考下,呵呵;
3. 当处理 static 函数时,Event 这个变量,就是 gen_fsm:send_event(?SERVER, hero_join). hero_join,紧接着执行对应的动作,在这里也就是 do_moving(),开始移动;
4. 最后,我们需要返回 {next_state, moving, NewState} 让gen_fsm进入下一个状态,也就是 moving 状态;
5. 当npc处于移动时,我们通过调用 npc:hero_leave(). 来表示 该侠客移动NPC的视野,那么对应的 moving(Event, State) 函数就会被调用,其他的处理与 static 时的处理是类似的,这里就不重复表述了。
这个例子还有一些函数,我没有讲到,希望在以后的教程来跟大家分享,谢谢。
Erlang OTP设计原则Gen_Fsm行为[转]的更多相关文章
- Erlang/OTP设计原则(文档翻译)
http://erlang.org/doc/design_principles/des_princ.html 图和代码皆源自以上链接中Erlang官方文档,翻译时的版本为20.1. 这个设计原则,其实 ...
- 欢迎阅读 Erlang OTP 设计原理文档
http://erldoc.com/doc/otp-design-principles/index.html 原文: OTP Design Principles 翻译: ShiningRay 有任何问 ...
- 理解Erlang/OTP - Application
http://www.cnblogs.com/me-sa/archive/2011/12/27/erlang0025.html 1>application:start(log4erl). 我们就 ...
- Erlang/OTP 中文手册
http://erldoc.com/ Open Telecom Platform application array asn1rt base64 binary calendar code dbg di ...
- [Erlang 0119] Erlang OTP 源码阅读指引
上周Erlang讨论群里面提到lists的++实现,争论大多基于猜测,其实打开代码看一下就都明了.贴出代码截图后有同学问这代码是哪里找的? "代码去哪里找?",关于Erla ...
- CentOS 6.5安装Erlang/OTP 17.0
CentOS 6.5安装Erlang/OTP 17.0 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs Erlang眼下已经是Fedora和Debian/ ...
- 理解Erlang/OTP Supervisor
http://www.cnblogs.com/me-sa/archive/2012/01/10/erlang0030.html Supervisors are used to build an hie ...
- [Erlang 0127] Term sharing in Erlang/OTP 上篇
之前,在 [Erlang 0126] 我们读过的Erlang论文 提到过下面这篇论文: On Preserving Term Sharing in the Erlang Virtual Machine ...
- Erlang OTP gen_event
转自:http://www.myexception.cn/program/1569725.html Erlang OTP gen_event (0) 原英文文档:http://www.erlang.o ...
随机推荐
- HTML5开发,背后的事情你知道吗?
现在的H5越来越受到企业或者是开发者的一个大力的追捧,已经成为网络推广必不可少的一个使用的工具,相信还有很多朋友现在都不知道H5是个什么东西,本文将为大家讲的是关于H5一些分类的问题,让你进一步的去学 ...
- SQL Server 2008数据备份与还原的原理是什么?
为什么SqlServer有完整备份.差异备份和事务日志备份三种备份方式,以及为什么数据库又有简单模式.完整模式和大容量日志模式这三种恢复模式.本文内容适用于2005以上所有版本的SqlServer数据 ...
- 笨办法学Python(七)
习题 7: 更多打印 现在我们将做一批练习,在练习的过程中你需要键入代码,并且让它们运行起来.我不会解释太多,因为这节的内容都是以前熟悉过的.这节练习的目的是巩固你学到的东西.我们几个练习后再见.不要 ...
- 笨办法学Python(四)
习题 4: 变量(variable)和命名 你已经学会了 print 和算术运算.下一步你要学的是“变量”.在编程中,变量只不过是用来指代某个东西的名字.程序员通过使用变量名可以让他们的程序读起来更像 ...
- OpenGL学习 Our First OpenGL Program
This shows you how to create the main window with the book’s application framework and how to render ...
- IOS xcode 离线帮助文档安装和安装路径
将想要安装的xcode 帮助文档 版本,将 ‘帮助文档包’ 放入‘xcode 帮助文档安装路径’.再将Xcode软件重启. xcode 帮助文档安装路径: 在‘应用程序’->Xcode软件 右击 ...
- 请教Nutzwk项目,在beetl页面怎么用shiro标签呢?
请教Nutzwk项目,在beetl页面怎么用shiro标签呢? 发布于 381天前 作者 WenTao-Love 195 次浏览 复制 上一个帖子 下一个帖子 标签: nutzwk 如题 ...
- UVA 11983 Weird Advertisement
题意:求矩形覆盖k次以上的区域总面积. 因为k≤10,可以在线段树上维护覆盖次数为0,...,k, ≥k的长度数量. 然后就是一个离散化以后扫描线的问题了. 离散化用的是半开半闭区间,以方便表示没有被 ...
- 【BZOJ3622】已经没有什么好害怕的了(动态规划+广义容斥)
点此看题面 大致题意: 有\(n\)个糖果和\(n\)个药片,各有自己的能量.将其两两配对,求糖果比药片能量大的组数恰好比药片比糖果能量大的组数多\(k\)组的方案数. 什么是广义容斥(二项式反演) ...
- 最终类object 和内部类
Object 类 性质:[1]是所有类的根类. [2]如果一个类没有显示继承另外一个类,那么该类一定继承于Object toString() 返回对象的字符串表示形式 特殊:[ ...