gen_fsm之门禁管理
昨天写了看了一下erlang gen_sfm 模式下一些应用,加上之前 Thomas 给我布置的任务
Erlang Programming一书中也有涉及,不过我草草看了一下
对于下面的状态改变写法的自己写的感觉还可以,呵呵...
任务描述如下:
实现一个门锁状态机,使用gen_fsm模式
初始状态为open,可以接受的event为lock,转为close状态
close状态,接受的event为unlock,转为open状态
在以上两个状态,如果有其它事件,不可崩溃,需要保持状态不变
下面是代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1-module(door_lock).
2-export([start/0, stop/0, unlock_or_lock/1]).
3-export([locked/2, open/2]).
4-export([init/1, handle_event/3, code_change/4, handle_sync_event/4, handle_info/3, terminate/3]).
5
6-include_lib("eunit/include/eunit.hrl").
7-behaviour(gen_fsm).
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1%%% 外部接口
2
3% 开始
4% start_link(FsmName, Module, Args, Options)
5% 利用 init 初始化状态
6start() ->
7 gen_fsm:start_link({local, ?MODULE}, ?MODULE, unlock, []).
8
9% 结束
10stop() ->
11 gen_fsm:send_all_state_event(?MODULE, stop). % 提交到Module:handle_event/3
12
13% 外部改变状态
14% State::lock | unlock -> 正则匹配
15unlock_or_lock(State) ->
16 case State == lock orelse State == unlock of
17 true ->
18 gen_fsm:send_event(?MODULE, State);
19 false ->
20 io:format('Input error,Door not Change!')
21 end.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1%%% 回调函数
2
3init(State) ->
4 {ok, locked, State}.
5
6% 锁住 door
7locked(Event, StateData) ->
8 % 判断发送过来的 Event 是不是和之前的状态一样
9 case Event /= StateData of
10 true ->
11 NextStateName = open, % 下一个状态(调用)
12 NewStateData = Event, % 下一个状态数据
13 outputMsg(Event);
14 %io:format("~p Success!~n", [Event]);
15 % {next_state, open, lock};
16 false ->
17 NextStateName = locked,
18 NewStateData = StateData,
19 outputError(StateData)
20 %io:format("Now the door is ~p~n Not thing to change~n",[StateData])
21 % {next_state, locked, StateData}
22 end,
23
24 {next_state, NextStateName, NewStateData}.
25
26% 打开 door
27open(Event, StateData) ->
28 case Event /= StateData of
29 true ->
30 NextStateName = locked,
31 NewStateData = Event,
32 outputMsg(Event);
33 %io:format("~p Success!~n", [Event]);
34 % {next_state, locked, StateData} ;
35 false ->
36 NextStateName = open,
37 NewStateData = StateData,
38 outputError(StateData)
39 %io:format("Now the door is ~p~n Not thing to change~n",[StateData])
40 %io:format("~p~n", [StateData]),
41 % {next_state, open, lock}
42 end,
43
44 {next_state, NextStateName, NewStateData}.
45
46% 信息的输出
47outputError(Msg) ->
48 io:format("Now the door is ~p~nNot thing to change~n",[Msg]).
49
50outputMsg(Msg) ->
51 io:format("~p Success!~n", [Msg]).
52
53% 匹配退出
54handle_event(stop, _StateName, StateData) ->
55 {stop, normal, StateData}.
56
57% 锁定事件
58% {reply,Reply,NextStateName,NewStateData}
59handle_sync_event(_Event, _From, StateName, StateData) ->
60 {reply,ok, StateName, StateData}.
61
62% 接收跟高级的信息
63% than a synchronous or asynchronous event (or a system message).
64handle_info(_Info, StateName, StateData) ->
65 {next_state,StateName,StateData}.
66
67% 热替换
68code_change(_OldVsn, StateName, StateData, _Extra) ->
69 {ok, StateName, StateData}.
70
71% 退出调用
72terminate(_Reason, _StateName, _StateData) ->
73 ok.
74