erlang 实现多状态机

-module(code_lock).
-behaviour(gen_fsm).
-export([send_evt/2]).
-export([create/2]).
-export([init/1, state_open/2, state_close/2]).

-record
(
    cmd_data,
    {
        cmd = send_evt,
        digit = 0
    }
).

-record
(
    lock_data,
    {
        input_buf = [],
        code_buf = []
    }
).

%% 输入界面
send_evt(Obj, Digit) ->
    gen_fsm:send_event( Obj, #cmd_data{digit=Digit} ).

%% 初始化锁
create(Obj, Code) ->
    gen_fsm:start_link({local, Obj}, code_lock, #lock_data{code_buf=Code}, []).
init( LockData ) ->
    {ok, state_close, LockData }.

%% 开状态
state_open( Cmd, LockData ) ->
    case Cmd of
        timeout ->
            io:format("state_open ~p ~n", [LockData]),
            {next_state, state_close, LockData};
        Default ->
            TimeOut = 10000,
            io:format("state_close Default ~n"),
            {next_state, state_close, LockData}
    end.

% 关状态 %
state_close( Cmd, LockData ) ->
    Buf = LockData#lock_data.input_buf,
    Code = LockData#lock_data.code_buf,
    case Cmd of
        #cmd_data{ digit=CurDigit } ->
            TimeOut = 10000,
            case Buf ++ [CurDigit] of
                Code ->
                    io:format("Current Input: ~p ~nSucced in Unlock. ~n", [Code]),
                    {next_state, state_open, #lock_data{code_buf=Code}, TimeOut};
                CurNums when length(CurNums)<length(Code) ->
                    io:format("Current Input: ~p ~n", [CurNums]),
                    {next_state, state_close, #lock_data{input_buf = CurNums, code_buf=Code}, TimeOut};
                Default ->
                    io:format("Failed in Unlock. ~nCurrent Input: ~p ~n", [Default]),
                    {next_state, state_close, #lock_data{code_buf=Code}, TimeOut}
            end;
        timeout ->
            io:format("Input TimeOut. Clear! ~n"),
            {next_state, state_close, #lock_data{code_buf=Code}};
        Default ->
            TimeOut = 10000,
            io:format("state_close Default ~n"),
            {next_state, state_close, #lock_data{code_buf=Code}, TimeOut}
    end.


Eshell V5.10.4  (abort with ^G)
1> make:all().
Recompile: code_lock
code_lock.erl:2: Warning: undefined callback function code_change/4 (behaviour 'gen_fsm')
code_lock.erl:2: Warning: undefined callback function handle_event/3 (behaviour 'gen_fsm')
code_lock.erl:2: Warning: undefined callback function handle_info/3 (behaviour 'gen_fsm')
code_lock.erl:2: Warning: undefined callback function handle_sync_event/4 (behaviour 'gen_fsm')
code_lock.erl:2: Warning: undefined callback function terminate/3 (behaviour 'gen_fsm')
code_lock.erl:41: Warning: variable 'Default' is unused
code_lock.erl:42: Warning: variable 'TimeOut' is unused
code_lock.erl:68: Warning: variable 'Default' is unused
up_to_date
2> code_lock:create( t1, [1,2,3] ).
{ok,<0.42.0>}
3> code_lock:send_evt( t1, 1 ).
Current Input: [1] 
ok
4> Input TimeOut. Clear! 
4> code_lock:send_evt( t1,2 ).

Current Input: [2] 
ok
5> code_lock:send_evt( t1, 1 ).
Input TimeOut. Clear! 
Current Input: [1] 
ok
6> Input TimeOut. Clear! 
6> code_lock:send_evt( t1, 1 ).

Current Input: [1] 
ok
7> code_lock:send_evt( t1, 2).

Current Input: [1,2] 
ok
8> code_lock:send_evt( t1, 3).

Current Input: [1,2,3] 
Succed in Unlock. 
ok
9> 


你可能感兴趣的:(erlang 实现多状态机)