From 259c8c7bde51f0b25707f0101195aff22650e952 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 27 Jul 2016 14:41:45 +0200 Subject: Rewrite gen_statem docs for M:callback_mode/0 --- system/doc/design_principles/statem.xml | 79 +++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 34 deletions(-) (limited to 'system/doc') diff --git a/system/doc/design_principles/statem.xml b/system/doc/design_principles/statem.xml index aea623851a..1351997bc1 100644 --- a/system/doc/design_principles/statem.xml +++ b/system/doc/design_principles/statem.xml @@ -52,7 +52,7 @@
Event-Driven State Machines

- Established Automata theory does not deal much with + Established Automata Theory does not deal much with how a state transition is triggered, but assumes that the output is a function of the input (and the state) and that they are @@ -226,11 +226,10 @@ handle_event(EventType, EventContent, State, Data) -> -module(code_lock). -behaviour(gen_statem). -define(NAME, code_lock). --define(CALLBACK_MODE, state_functions). -export([start_link/1]). -export([button/1]). --export([init/1,terminate/3,code_change/4]). +-export([init/1,callback_mode/0,terminate/3,code_change/4]). -export([locked/3,open/3]). start_link(Code) -> @@ -242,7 +241,10 @@ button(Digit) -> init(Code) -> do_lock(), Data = #{code => Code, remaining => Code}, - {?CALLBACK_MODE,locked,Data}. + {ok,locked,Data}. + +callback_mode() -> + state_functions. locked( cast, {button,Digit}, @@ -273,7 +275,7 @@ terminate(_Reason, State, _Data) -> State =/= locked andalso do_lock(), ok. code_change(_Vsn, State, Data, _Extra) -> - {?CALLBACK_MODE,State,Data}. + {ok,State,Data}. ]]>

The code is explained in the next sections.

@@ -343,14 +345,8 @@ start_link(Code) ->

If name registration succeeds, the new gen_statem process calls callback function code_lock:init(Code). - This function is expected to return {CallbackMode,State,Data}, - where - CallbackMode - selects callback module state function mode, in this case - state_functions - through macro ?CALLBACK_MODE. That is, each state - has got its own handler function. - State is the initial state of the gen_statem, + This function is expected to return {ok,State,Data}, + where State is the initial state of the gen_statem, in this case locked; assuming that the door is locked to begin with. Data is the internal server data of the gen_statem. Here the server data is a map @@ -359,11 +355,12 @@ start_link(Code) -> that stores the remaining correct button sequence (the same as the code to begin with).

+ do_lock(), Data = #{code => Code, remaining => Code}, - {?CALLBACK_MODE,locked,Data}. + {ok,locked,Data}. ]]>

Function gen_statem:start_link @@ -380,6 +377,21 @@ init(Code) -> can be used to start a standalone gen_statem, that is, a gen_statem that is not part of a supervision tree.

+ + + state_functions. + ]]> +

+ Function + Module:callback_mode/0 + selects the + CallbackMode + for the callback module, in this case + state_functions. + That is, each state has got its own handler function. +

+ @@ -532,13 +544,12 @@ handle_event({call,From}, code_length, #{code := Code} = Data) -> and then depending on state:

+ handle_event_function. handle_event(cast, {button,Digit}, State, #{code := Code} = Data) -> case State of @@ -962,16 +973,13 @@ do_unlock() ->

process_flag(trap_exit, true), Data = #{code => Code}, - enter(?CALLBACK_MODE, locked, Data). + enter(ok, locked, Data). -... +callback_mode() -> + state_functions. locked(internal, enter, _Data) -> do_lock(), @@ -1027,11 +1035,10 @@ enter(Tag, State, Data) -> -module(code_lock). -behaviour(gen_statem). -define(NAME, code_lock_2). --define(CALLBACK_MODE, state_functions). -export([start_link/1,stop/0]). -export([button/1,code_length/0]). --export([init/1,terminate/3,code_change/4]). +-export([init/1,callback_mode/0,terminate/3,code_change/4]). -export([locked/3,open/3]). start_link(Code) -> @@ -1047,7 +1054,10 @@ code_length() -> init(Code) -> process_flag(trap_exit, true), Data = #{code => Code}, - enter(?CALLBACK_MODE, locked, Data). + enter(ok, locked, Data). + +callback_mode() -> + state_functions. locked(internal, enter, #{code := Code} = Data) -> do_lock(), @@ -1091,7 +1101,7 @@ terminate(_Reason, State, _Data) -> State =/= locked andalso do_lock(), ok. code_change(_Vsn, State, Data, _Extra) -> - {?CALLBACK_MODE,State,Data}. + {ok,State,Data}. ]]> @@ -1105,13 +1115,12 @@ code_change(_Vsn, State, Data, _Extra) -> entry actions, so this example first branches depending on state:

+ handle_event_function. %% State: locked handle_event(internal, enter, locked, #{code := Code} = Data) -> @@ -1273,11 +1282,10 @@ format_status(Opt, [_PDict,State,Data]) -> -module(code_lock). -behaviour(gen_statem). -define(NAME, code_lock_3). --define(CALLBACK_MODE, handle_event_function). -export([start_link/2,stop/0]). -export([button/1,code_length/0,set_lock_button/1]). --export([init/1,terminate/3,code_change/4,format_status/2]). +-export([init/1,callback_mode/0,terminate/3,code_change/4,format_status/2]). -export([handle_event/4]). start_link(Code, LockButton) -> @@ -1296,7 +1304,10 @@ set_lock_button(LockButton) -> init({Code,LockButton}) -> process_flag(trap_exit, true), Data = #{code => Code, remaining => undefined, timer => undefined}, - enter(?CALLBACK_MODE, {locked,LockButton}, Data, []). + enter(ok, {locked,LockButton}, Data, []). + +callback_mode() -> + handle_event_function. handle_event( {call,From}, {set_lock_button,NewLockButton}, @@ -1366,7 +1377,7 @@ terminate(_Reason, State, _Data) -> State =/= locked andalso do_lock(), ok. code_change(_Vsn, State, Data, _Extra) -> - {?CALLBACK_MODE,State,Data}. + {ok,State,Data}. format_status(Opt, [_PDict,State,Data]) -> StateData = {State, -- cgit v1.2.3 From 3a60545091d3075e23c4a7af8c18b3641bb084e2 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 9 Aug 2016 08:59:51 +0200 Subject: Doc fixes --- system/doc/design_principles/statem.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'system/doc') diff --git a/system/doc/design_principles/statem.xml b/system/doc/design_principles/statem.xml index 1351997bc1..f785ca9650 100644 --- a/system/doc/design_principles/statem.xml +++ b/system/doc/design_principles/statem.xml @@ -608,7 +608,7 @@ init(Args) -> callback function terminate(shutdown, State, Data).

- In the following example, function terminate/3 + In this example, function terminate/3 locks the door if it is open, so we do not accidentally leave the door open when the supervision tree terminates:

@@ -1217,7 +1217,8 @@ format_status(Opt, [_PDict,State,Data]) -> Module:format_status/2 function. If you do not, a default implementation is used that does the same as this example function without filtering - the Data term, that is, StateData = {State,Data}. + the Data term, that is, StateData = {State,Data}, + in this example containing sensitive information.

-- cgit v1.2.3