fsm是指有限状态机,顾名思义,可以处理有限的几个状态的流转控制。按照官方的描述:
State(S) x Event(E) -> Actions(A), State(S’)
如果当前状态为S,并且发生了E事件,则进行A操作,并且修改状态为S’
比如游戏里怪物(npc)有静止,移动等状态,初始时npc处于静止状态,当有英雄进入(hero_join)怪物的视野时,npc开始移动;当英雄离开怪物的视野时,npc静止。采用gen_fsm行为可以很方便的控制状态的变化。
上面代码不需要解释,引入gen_fsm行为模式,导出方法而已。
start_link调用gen_fsm:start_link/4方法,启动一个新的gen_fsm进程并连接。
1.第一个参数{local, ?SERVER},在本地注册一个名为?SERVER的进程
2.第二个参数指回调模块
3.第三个参数指回调init方法的参数
4.第四个参数是状态机的选项
init/1中初始化了npc的状态为static,返回{ok, static, State}。
static/2方法会在当前状态为static时,等待接收事件。当有hero_join(英雄进入怪物视野)事件时,修改状态为moving。其他事件不处理。
类似static/2,当前状态为moving时,等待接收事件。当有hero_leave(英雄离开怪物视野)事件时,修改状态为static,其他类型事件不处理。
hero_join/0和hero_leave/0两个方法,提供给客户端调用,触发相应的事件。
handle_event/3函数用于处理gen_fsm:send_all_state_event发送给fsm的事件,无论fsm进程处于什么状态,都会调用handle_event/3来处理。
handle_sync_event/4函数作用未知,可能是异步的处理事件。
handle_info/3回调函数用于处理直接发给状态机的消息。
从一个状态转变到另一个状态是通过状态函数的返回值控制的,可以有如下几种形式:
{next_state,NextStateName,NewStateData}
{next_state,NextStateName,NewStateData,Timeout}
{next_state,NextStateName,NewStateData,hibernate}
{stop,Reason,NewStateData}
可以为状态设置超时,如下图红框部分:
3秒后FSM自动将状态转变为static。moving/2增加一个timeout分支既可