1gen_fsm(3)                 Erlang Module Definition                 gen_fsm(3)
2
3
4

NAME

6       gen_fsm - Deprecated and replaced by gen_statem
7

DESCRIPTION

9       Deprecated and replaced by gen_statem
10

MIGRATION TO GEN_STATEM

12       Here  follows  a simple example of turning a gen_fsm into a gen_statem.
13       The example comes from the previous Users Guide for gen_fsm
14
15       -module(code_lock).
16       -define(NAME, code_lock).
17       %-define(BEFORE_REWRITE, true).
18
19       -ifdef(BEFORE_REWRITE).
20       -behaviour(gen_fsm).
21       -else.
22       -behaviour(gen_statem).
23       -endif.
24
25       -export([start_link/1, button/1, stop/0]).
26
27       -ifdef(BEFORE_REWRITE).
28       -export([init/1, locked/2, open/2, handle_sync_event/4, handle_event/3,
29             handle_info/3, terminate/3, code_change/4]).
30       -else.
31       -export([init/1, callback_mode/0, locked/3, open/3, terminate/3, code_change/4]).
32       %% Add callback__mode/0
33       %% Change arity of the state functions
34       %% Remove handle_info/3
35       -endif.
36
37       -ifdef(BEFORE_REWRITE).
38       start_link(Code) ->
39           gen_fsm:start_link({local, ?NAME}, ?MODULE, Code, []).
40       -else.
41       start_link(Code) ->
42           gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).
43       -endif.
44
45       -ifdef(BEFORE_REWRITE).
46       button(Digit) ->
47           gen_fsm:send_event(?NAME, {button, Digit}).
48       -else.
49       button(Digit) ->
50           gen_statem:cast(?NAME, {button,Digit}).
51           %% send_event is asynchronous and becomes a cast
52       -endif.
53
54       -ifdef(BEFORE_REWRITE).
55       stop() ->
56           gen_fsm:sync_send_all_state_event(?NAME, stop).
57       -else.
58       stop() ->
59           gen_statem:call(?NAME, stop).
60           %% sync_send is synchronous and becomes call
61           %% all_state is handled by callback code in gen_statem
62       -endif.
63
64       init(Code) ->
65           do_lock(),
66           Data = #{code => Code, remaining => Code},
67           {ok, locked, Data}.
68
69       -ifdef(BEFORE_REWRITE).
70       -else.
71       callback_mode() ->
72           state_functions.
73       %% state_functions mode is the mode most similar to
74       %% gen_fsm. There is also handle_event mode which is
75       %% a fairly different concept.
76       -endif.
77
78       -ifdef(BEFORE_REWRITE).
79       locked({button, Digit}, Data0) ->
80           case analyze_lock(Digit, Data0) of
81            {open = StateName, Data} ->
82                {next_state, StateName, Data, 10000};
83            {StateName, Data} ->
84                {next_state, StateName, Data}
85           end.
86       -else.
87       locked(cast, {button,Digit}, Data0) ->
88           case analyze_lock(Digit, Data0) of
89            {open = StateName, Data} ->
90                {next_state, StateName, Data, 10000};
91            {StateName, Data} ->
92                {next_state, StateName, Data}
93           end;
94       locked({call, From}, Msg, Data) ->
95           handle_call(From, Msg, Data);
96       locked({info, Msg}, StateName, Data) ->
97           handle_info(Msg, StateName, Data).
98       %% Arity differs
99       %% All state events are dispatched to handle_call and handle_info help
100       %% functions. If you want to handle a call or cast event specifically
101       %% for this state you would add a special clause for it above.
102       -endif.
103
104       -ifdef(BEFORE_REWRITE).
105       open(timeout, State) ->
106            do_lock(),
107           {next_state, locked, State};
108       open({button,_}, Data) ->
109           {next_state, locked, Data}.
110       -else.
111       open(timeout, _, Data) ->
112           do_lock(),
113           {next_state, locked, Data};
114       open(cast, {button,_}, Data) ->
115           {next_state, locked, Data};
116       open({call, From}, Msg, Data) ->
117           handle_call(From, Msg, Data);
118       open(info, Msg, Data) ->
119           handle_info(Msg, open, Data).
120       %% Arity differs
121       %% All state events are dispatched to handle_call and handle_info help
122       %% functions. If you want to handle a call or cast event specifically
123       %% for this state you would add a special clause for it above.
124       -endif.
125
126       -ifdef(BEFORE_REWRITE).
127       handle_sync_event(stop, _From, _StateName, Data) ->
128           {stop, normal, ok, Data}.
129
130       handle_event(Event, StateName, Data) ->
131           {stop, {shutdown, {unexpected, Event, StateName}}, Data}.
132
133       handle_info(Info, StateName, Data) ->
134           {stop, {shutdown, {unexpected, Info, StateName}}, StateName, Data}.
135       -else.
136       -endif.
137
138       terminate(_Reason, State, _Data) ->
139           State =/= locked andalso do_lock(),
140           ok.
141       code_change(_Vsn, State, Data, _Extra) ->
142           {ok, State, Data}.
143
144       %% Internal functions
145       -ifdef(BEFORE_REWRITE).
146       -else.
147       handle_call(From, stop, Data) ->
148            {stop_and_reply, normal,  {reply, From, ok}, Data}.
149
150       handle_info(Info, StateName, Data) ->
151           {stop, {shutdown, {unexpected, Info, StateName}}, StateName, Data}.
152       %% These are internal functions for handling all state events
153       %% and not behaviour callbacks as in gen_fsm
154       -endif.
155
156       analyze_lock(Digit, #{code := Code, remaining := Remaining} = Data) ->
157            case Remaining of
158                [Digit] ->
159                 do_unlock(),
160                 {open,  Data#{remaining := Code}};
161                [Digit|Rest] -> % Incomplete
162                    {locked, Data#{remaining := Rest}};
163                _Wrong ->
164                    {locked, Data#{remaining := Code}}
165            end.
166
167       do_lock() ->
168           io:format("Lock~n", []).
169       do_unlock() ->
170           io:format("Unlock~n", []).
171
172
173
174
175Ericsson AB                      stdlib 3.12.1                      gen_fsm(3)
Impressum