-module(code_lock).
-behaviour(gen_fsm).
-export([start_link/1,button/1]).
-export([locked/2,open/2,stop/0,sync_button/1]).
-export([init/1,handle_event/3,handle_sync_event/4,handle_info/3,code_change/4,terminate/3]).
start_link(Code)->
io:format("srart_link Code=~p~n",[Code]),
gen_fsm:start_link({local,code_lock},code_lock,Code,[]).
button(Digit)->
gen_fsm:send_event(code_lock,{button,Digit}).
init(Code)->
io:format("init Code=~p~n",[Code]),
{ok,locked,{[],Code}}.%sofar=[],Code=Code
sync_button(Digit)->
gen_fsm:sync_send_event(code_lock, {button, Digit}).
locked({button, Digit}, {SoFar, Code}) ->
io:format("locked {button,Digit}={button,~p},{SoFar,Code}=~p~n",[Digit,{SoFar,Code}]),
io:format("[Digit|SoFar]=~p,Code=~p~n",[[Digit|SoFar],Code]),
case [Digit|SoFar] of
Code->
do_unlock(),
{next_state, open, {[], Code}, 3000};
Incomplete when length(Incomplete)
io:format("length(Incomplete)=~p < length(Code)=~p~n",[length(Incomplete),length(Code)]),
{next_state, locked, {Incomplete, Code}};
_Wrong ->
io:format("_Wrong~n"),
{next_state, locked, {[], Code}}
end.
open(timeout,State)->
do_lock(),
{next_state,locked,State}.
stop()->
gen_fsm:send_all_state_event(code_lock,stop).
handle_event(stop,_StateName,StateData)->
{stop,normal,StateData};
handle_event(_A,_B,_C)->
{next_state,ok,ok}.
handle_sync_event({button,_Digit}, _From, StateName, State) ->
{reply,reply,StateName,State}.
terminate(normal,_StateName,_StateData)->
ok.
handle_info(_A, _B, _C) ->
{next_state, ok, ok}.
code_change(_A, _B, _C, _D) ->
{ok, ok, ok}.
do_unlock()->
io:format("do_unlock~n").
do_lock()->
io:format("do_lock~n").
运行
2> c(code_lock).
{ok,code_lock}
3> code_lock:start_link([12]).
srart_link Code="\f"
init Code="\f"
{ok,<0.39.0>}
4> code_lock:button(3).
locked {button,Digit}={button,3},{SoFar,Code}={[],"\f"}
ok
[Digit|SoFar]=[3],Code="\f"
_Wrong
5> code_lock:button(12).
locked {button,Digit}={button,12},{SoFar,Code}={[],"\f"}
ok
[Digit|SoFar]="\f",Code="\f"
do_unlock
do_lock
6> code_lock:button(12).
locked {button,Digit}={button,12},{SoFar,Code}={[],"\f"}
ok
[Digit|SoFar]="\f",Code="\f"
do_unlock
do_lock
7>