主页

索引

模块索引

搜索页面

gen_statem模块

@todo [1]

design_principles

事件驱动状态机:

State(S) x Event(E) -> Actions(A), State(S')
在状态S时,发生事件E => 执行A事件,并把状态改为S'

实例:

 1-module(code_lock).
 2-behaviour(gen_statem).
 3-define(NAME, code_lock).
 4
 5-export([start_link/1]).
 6-export([button/1]).
 7-export([init/1,callback_mode/0,terminate/3]).
 8-export([locked/3,open/3]).
 9
10start_link(Code) ->
11    gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).
12
13button(Button) ->
14    gen_statem:cast(?NAME, {button,Button}).
15
16init(Code) ->
17    do_lock(),
18    Data = #{code => Code, length => length(Code), buttons => []},
19    {ok, locked, Data}.
20
21callback_mode() ->
22    state_functions.
23
24locked(cast, {button,Button}, #{code := Code, length := Length, buttons := Buttons} = Data) ->
25    NewButtons =
26        if
27            length(Buttons) < Length ->
28                Buttons;
29            true ->
30                tl(Buttons)
31        end ++ [Button],
32    if
33        NewButtons =:= Code -> % Correct
34            do_unlock(),
35            {next_state, open, Data#{buttons := []}, [{state_timeout,10000,lock}]}; % Time in milliseconds
36        true -> % Incomplete | Incorrect
37            {next_state, locked, Data#{buttons := NewButtons}}
38    end.
39
40open(state_timeout, lock,  Data) ->
41    do_lock(),
42    {next_state, locked, Data};
43open(cast, {button,_}, Data) ->
44    {next_state, open, Data}.
45
46do_lock() ->
47    io:format("Lock~n", []).
48do_unlock() ->
49    io:format("Unlock~n", []).
50
51terminate(_Reason, State, _Data) ->
52    State =/= locked andalso do_lock(),
53    ok.

什么时候用:

1.无论事件类型(call, cast, info),每个state共用回一回调代码.
    Co-located callback code for each state, regardless of Event Type (such as call, cast and info)
2.延迟事件(替代选择性receive)
    Postponing Events (a substitute for selective receive)
3.插入事件:从状态机到自身的事件(特别是纯内部事件)
    Inserted Events that is: events from the state machine to itself (in particular purely internal events)
4.State Enter Calls(state的回调入口与其他states的回调代码共用)
    State Enter Calls (callback on state entry co-located with the rest of each state's callback code)
5.超时使用简单(状态超时,事件超时,通用超时)
    Easy-to-use timeouts (State Time-Outs, Event Time-Outs and Generic Time-outs (named time-outs))

主页

索引

模块索引

搜索页面