From d840b24857a1d54419953661f70716c449c11864 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 3 Mar 2016 10:54:01 +0100 Subject: Fix most of the system docs and emacs mode --- lib/sasl/doc/src/appup.xml | 5 +- lib/sasl/doc/src/error_logging.xml | 7 ++- lib/stdlib/doc/src/gen_statem.xml | 87 ++++++++++++++++++++------- lib/stdlib/doc/src/proc_lib.xml | 8 +-- lib/stdlib/doc/src/supervisor.xml | 10 ++-- lib/stdlib/doc/src/sys.xml | 31 ++++++---- lib/stdlib/src/gen_statem.erl | 93 ++++++++++++++++------------ lib/tools/doc/src/erlang_mode.xml | 3 +- lib/tools/emacs/erlang-skels.el | 120 ++++++++++++++++++++++++++++++++++++- 9 files changed, 281 insertions(+), 83 deletions(-) (limited to 'lib') diff --git a/lib/sasl/doc/src/appup.xml b/lib/sasl/doc/src/appup.xml index b54d2adb19..6fbdcb9f5b 100644 --- a/lib/sasl/doc/src/appup.xml +++ b/lib/sasl/doc/src/appup.xml @@ -4,7 +4,7 @@
- 19972014 + 19972016 Ericsson AB. All Rights Reserved. @@ -137,7 +137,8 @@ code change. If it is set to {advanced,Extra}, implemented processes using gen_server, - gen_fsm, or + gen_fsm, + gen_statem, or gen_event transform their internal state by calling the callback function code_change. Special processes call the callback diff --git a/lib/sasl/doc/src/error_logging.xml b/lib/sasl/doc/src/error_logging.xml index 46b12f3872..8464a41ff9 100644 --- a/lib/sasl/doc/src/error_logging.xml +++ b/lib/sasl/doc/src/error_logging.xml @@ -4,7 +4,7 @@
- 19972013 + 19972016 Ericsson AB. All Rights Reserved. @@ -90,8 +90,9 @@ a process terminates with an unexpected reason, which is any reason other than normal, shutdown, or {shutdown,Term}. Processes using behaviors - gen_server or - gen_fsm + gen_server, + gen_fsm or + gen_statem are examples of such processes. A crash report contains the following items:

Crasher diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index 01be3099c1..db6a4e03ea 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -407,7 +407,7 @@ ok

- After a state change (NewState =/= State) + After a state change (NextState =/= State) all postponed events are retried.

@@ -566,7 +566,7 @@ ok

If true postpone the current event and retry it when the state changes that is: - NewState =/= State. + NextState =/= State.

@@ -701,7 +701,47 @@ ok - + + + + next_state + + The gen_statem will do a state transition to + NextStateName + (which may be the same as the current state), + set NewData + and execute all Actions + + +

+ All these terms are tuples or atoms and this property + will hold in any future version of gen_statem, + just in case you need such a promise. +

+
+
+ + + + + next_state + + The gen_statem will do a state transition to + NextState + (which may be the same as the current state), + set NewData + and execute all Actions + + +

+ All these terms are tuples or atoms and this property + will hold in any future version of gen_statem, + just in case you need such a promise. +

+
+
+ + stop @@ -723,14 +763,6 @@ ok with Reason and NewData, if given. - next_state - - The gen_statem will do a state transition to - NewState - (which may be the same as the current state), - set NewData - and execute all Actions - keep_state The gen_statem will keep the current state, or @@ -1209,10 +1241,11 @@ ok - Module:StateName(EventType, EventContent, Data) -> Result + Module:StateName(EventType, EventContent, Data) -> + StateFunctionResult Module:handle_event(EventType, EventContent, - State, Data) -> Result + State, Data) -> HandleEventResult Handle an event @@ -1222,7 +1255,7 @@ ok EventContent = term() - State = NewState = + State = state() @@ -1230,9 +1263,15 @@ ok data() - Result = - - state_callback_result() + StateFunctionResult = + + state_function_result() + + + + HandleEventResult = + + handle_event_result() @@ -1260,9 +1299,15 @@ ok reply(Caller, Reply).

- If this function returns with a new state that + If this function returns with a next state that does not match equal (=/=) to the current state - all postponed events will be retried in the new state. + all postponed events will be retried in the next state. +

+

+ The only difference between StateFunctionResult and + HandleEventResult is that for StateFunctionResult + the next state has to be an atom but for HandleEventResult + there is no restriction on the next state.

See action() @@ -1272,7 +1317,7 @@ ok

These functions may use throw, - to return Result. + to return the result.

@@ -1401,7 +1446,7 @@ ok

If successful, the function shall return the updated internal state in an - {ok,{NewState,NewData}} tuple. + {ok,NewState,NewData} tuple.

If the function returns Reason, the ongoing diff --git a/lib/stdlib/doc/src/proc_lib.xml b/lib/stdlib/doc/src/proc_lib.xml index 85f0c0c908..245580b1ba 100644 --- a/lib/stdlib/doc/src/proc_lib.xml +++ b/lib/stdlib/doc/src/proc_lib.xml @@ -4,7 +4,7 @@

- 19962014 + 19962016 Ericsson AB. All Rights Reserved. @@ -34,9 +34,9 @@

This module is used to start processes adhering to the OTP Design Principles. Specifically, the functions in this module are used by the OTP standard behaviors (gen_server, - gen_fsm, ...) when starting new processes. The functions - can also be used to start special processes, user - defined processes which comply to the OTP design principles. See + gen_fsm, gen_statem, ...) when starting new processes. + The functions can also be used to start special processes, + user defined processes which comply to the OTP design principles. See Sys and Proc_Lib in OTP Design Principles for an example.

Some useful information is initialized when a process starts. The registered names, or the process identifiers, of the parent diff --git a/lib/stdlib/doc/src/supervisor.xml b/lib/stdlib/doc/src/supervisor.xml index 24ff251ce3..9d81fb0db7 100644 --- a/lib/stdlib/doc/src/supervisor.xml +++ b/lib/stdlib/doc/src/supervisor.xml @@ -4,7 +4,7 @@

- 19962014 + 19962016 Ericsson AB. All Rights Reserved. @@ -34,8 +34,8 @@

A behaviour module for implementing a supervisor, a process which supervises other processes called child processes. A child process can either be another supervisor or a worker process. - Worker processes are normally implemented using one of - the gen_event, gen_fsm, or gen_server + Worker processes are normally implemented using one of the + gen_event, gen_fsm, gen_statem or gen_server behaviours. A supervisor implemented using this module will have a standard set of interface functions and include functionality for tracing and error reporting. Supervisors are used to build a @@ -221,7 +221,8 @@

modules is used by the release handler during code replacement to determine which processes are using a certain module. As a rule of thumb, if the child process is a - supervisor, gen_server, or gen_fsm, + supervisor, gen_server, + gen_fsm or gen_statem this should be a list with one element [Module], where Module is the callback module. If the child process is an event manager (gen_event) with a @@ -633,6 +634,7 @@ SEE ALSO

gen_event(3), gen_fsm(3), + gen_statem(3), gen_server(3), sys(3)

diff --git a/lib/stdlib/doc/src/sys.xml b/lib/stdlib/doc/src/sys.xml index d400f72e1d..2255395f46 100644 --- a/lib/stdlib/doc/src/sys.xml +++ b/lib/stdlib/doc/src/sys.xml @@ -4,7 +4,7 @@
- 19962014 + 19962016 Ericsson AB. All Rights Reserved. @@ -217,14 +217,18 @@ processes. For example, a gen_server process returns the callback module's state, a gen_fsm process returns information such as its current state name and state data, - and a gen_event process returns information about each of its + a gen_statem process returns information about + its current state and data, and a gen_event process + returns information about each of its registered handlers. Callback modules for gen_server, - gen_fsm, and gen_event can also customise the value + gen_fsm, gen_statem and gen_event + can also customise the value of Misc by exporting a format_status/2 function that contributes module-specific information; - see gen_server:format_status/2, - gen_fsm:format_status/2, and - gen_event:format_status/2 + see gen_server format_status/2, + gen_fsm format_status/2, + gen_statem format_status/2, and + gen_event format_status/2 for more details.

@@ -245,6 +249,8 @@ processes. For a gen_server process, the returned State is simply the callback module's state. For a gen_fsm process, State is the tuple {CurrentStateName, CurrentStateData}. + For a gen_statem process State is + the tuple {CurrentState,CurrentData}. For a gen_event process, State a list of tuples, where each tuple corresponds to an event handler registered in the process and contains {Module, Id, HandlerState}, where Module is the event handler's module name, @@ -263,8 +269,9 @@ details of the exception.

The system_get_state/1 function is primarily useful for user-defined behaviours and modules that implement OTP special - processes. The gen_server, gen_fsm, and gen_event OTP - behaviour modules export this function, and so callback modules for those behaviours + processes. The gen_server, gen_fsm, + gen_statem and gen_event OTP + behaviour modules export this function, so callback modules for those behaviours need not supply their own.

To obtain more information about a process, including its state, see get_status/1 and @@ -290,6 +297,8 @@ gen_fsm process, State is the tuple {CurrentStateName, CurrentStateData}, and NewState is a similar tuple that may contain a new state name, new state data, or both. + The same applies for a gen_statem process but + it names the tuple fields {CurrentState,CurrentData}. For a gen_event process, State is the tuple {Module, Id, HandlerState} where Module is the event handler's module name, Id is the handler's ID (which is the value false if it was registered without @@ -304,7 +313,8 @@ state, then regardless of process type, it may simply return its State argument.

If a StateFun function crashes or throws an exception, then - for gen_server and gen_fsm processes, the original state of the process is + for gen_server, gen_fsm or gen_statem processes, + the original state of the process is unchanged. For gen_event processes, a crashing or failing StateFun function means that only the state of the particular event handler it was working on when it failed or crashed is unchanged; it can still succeed in changing the states of other event @@ -329,7 +339,8 @@ {callback_failed, StateFun, {Class, Reason}}.

The system_replace_state/2 function is primarily useful for user-defined behaviours and modules that implement OTP special processes. The - gen_server, gen_fsm, and gen_event OTP behaviour modules export this function, + gen_server, gen_fsm, gen_statem and + gen_event OTP behaviour modules export this function, and so callback modules for those behaviours need not supply their own.

diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl index cc09efc140..438c366f8e 100644 --- a/lib/stdlib/src/gen_statem.erl +++ b/lib/stdlib/src/gen_statem.erl @@ -44,8 +44,16 @@ -export( [wakeup_from_hibernate/3]). +%% Type exports for templates +-export_type( + [event_type/0, + callback_mode/0, + state_function_result/0, + handle_event_result/0, + action/0]). + %% Fix problem for doc build --export_type([transition_option/0,state_callback_result/0]). +-export_type([transition_option/0]). %%%========================================================================== %%% Interface functions. @@ -84,7 +92,7 @@ -type action() :: %% During a state change: - %% * NewState and NewData are set. + %% * NextState and NewData are set. %% * All action()s are executed in order of apperance. %% * Postponing the current event is performed %% iff 'postpone' is 'true'. @@ -119,7 +127,25 @@ {'reply', % Reply to a caller Caller :: caller(), Reply :: term()}. --type state_callback_result() :: +-type state_function_result() :: + {'next_state', % {next_state,NextStateName,NewData,[]} + NextStateName :: state_name(), + NewData :: data()} | + {'next_state', % State transition, maybe to the same state + NextStateName :: state_name(), + NewData :: data(), + Actions :: [action()] | action()} | + common_state_callback_result(). +-type handle_event_result() :: + {'next_state', % {next_state,NextState,NewData,[]} + NextState :: state(), + NewData :: data()} | + {'next_state', % State transition, maybe to the same state + NextState :: state(), + NewData :: data(), + Actions :: [action()] | action()} | + common_state_callback_result(). +-type common_state_callback_result() :: 'stop' | % {stop,normal} {'stop', % Stop the server Reason :: term()} | @@ -133,13 +159,6 @@ Reason :: term(), Replies :: [reply_action()] | reply_action(), NewData :: data()} | - {'next_state', % {next_state,NewState,NewData,[]} - NewState :: state(), - NewData :: data()} | - {'next_state', % State transition, maybe to the same state - NewState :: state(), - NewData :: data(), - Actions :: [action()] | action()} | {'keep_state', % {keep_state,NewData,[]} NewData :: data()} | {'keep_state', % Keep state, change data @@ -171,7 +190,7 @@ event_type(), EventContent :: term(), Data :: data()) -> - state_callback_result(). + state_function_result(). %% %% State callback for callback_mode() =:= handle_event_function. %% @@ -182,7 +201,7 @@ EventContent :: term(), State :: state(), % Current state Data :: data()) -> - state_callback_result(). + handle_event_result(). %% Clean up before the server terminates. -callback terminate( @@ -514,7 +533,7 @@ enter(Module, Opts, CallbackMode, State, Data, Server, Actions, Parent) -> %% The values should already have been type checked Name = gen:get_proc_name(Server), Debug = gen:debug_options(Name, Opts), - OldState = make_ref(), % Will be discarded by loop_event_actions/9 + PrevState = make_ref(), % Will be discarded by loop_event_actions/9 NewActions = if is_list(Actions) -> @@ -526,7 +545,7 @@ enter(Module, Opts, CallbackMode, State, Data, Server, Actions, Parent) -> callback_mode => CallbackMode, module => Module, name => Name, - state => OldState, + state => PrevState, data => Data, timer => undefined, postponed => [], @@ -534,7 +553,7 @@ enter(Module, Opts, CallbackMode, State, Data, Server, Actions, Parent) -> loop_event_actions( Parent, Debug, S, [], {event,undefined}, % Will be discarded thanks to {postpone,false} - OldState, State, Data, NewActions). + PrevState, State, Data, NewActions). %%%========================================================================== %%% gen callbacks @@ -868,18 +887,18 @@ loop_event_result( exit, Reason, ?STACKTRACE(), Debug, NewS, Q, Replies), %% Since we got back here Replies was bad terminate(Class, NewReason, Stacktrace, NewDebug, NewS, Q); - {next_state,NewState,NewData} - when CallbackMode =:= state_functions, is_atom(NewState); + {next_state,NextState,NewData} + when CallbackMode =:= state_functions, is_atom(NextState); CallbackMode =/= state_functions -> loop_event_actions( Parent, Debug, S, Events, Event, - State, NewState, NewData, []); - {next_state,NewState,NewData,Actions} - when CallbackMode =:= state_functions, is_atom(NewState); + State, NextState, NewData, []); + {next_state,NextState,NewData,Actions} + when CallbackMode =:= state_functions, is_atom(NextState); CallbackMode =/= state_functions -> loop_event_actions( Parent, Debug, S, Events, Event, - State, NewState, NewData, Actions); + State, NextState, NewData, Actions); {keep_state,NewData} -> loop_event_actions( Parent, Debug, S, Events, Event, @@ -902,13 +921,13 @@ loop_event_result( end. loop_event_actions( - Parent, Debug, S, Events, Event, State, NewState, NewData, Actions) -> + Parent, Debug, S, Events, Event, State, NextState, NewData, Actions) -> Postpone = false, % Shall we postpone this event, true or false Hibernate = false, Timeout = undefined, NextEvents = [], loop_event_actions( - Parent, Debug, S, Events, Event, State, NewState, NewData, + Parent, Debug, S, Events, Event, State, NextState, NewData, if is_list(Actions) -> Actions; @@ -920,19 +939,19 @@ loop_event_actions( %% Process all action()s loop_event_actions( Parent, Debug, S, Events, Event, - State, NewState, NewData, [Action|Actions], + State, NextState, NewData, [Action|Actions], Postpone, Hibernate, Timeout, NextEvents) -> case Action of %% Actions that set options postpone -> loop_event_actions( Parent, Debug, S, Events, Event, - State, NewState, NewData, Actions, + State, NextState, NewData, Actions, true, Hibernate, Timeout, NextEvents); {postpone,NewPostpone} when is_boolean(NewPostpone) -> loop_event_actions( Parent, Debug, S, Events, Event, - State, NewState, NewData, Actions, + State, NextState, NewData, Actions, NewPostpone, Hibernate, Timeout, NextEvents); {postpone,_} -> ?TERMINATE( @@ -940,12 +959,12 @@ loop_event_actions( hibernate -> loop_event_actions( Parent, Debug, S, Events, Event, - State, NewState, NewData, Actions, + State, NextState, NewData, Actions, Postpone, true, Timeout, NextEvents); {hibernate,NewHibernate} when is_boolean(NewHibernate) -> loop_event_actions( Parent, Debug, S, Events, Event, - State, NewState, NewData, Actions, + State, NextState, NewData, Actions, Postpone, NewHibernate, Timeout, NextEvents); {hibernate,_} -> ?TERMINATE( @@ -953,12 +972,12 @@ loop_event_actions( {timeout,infinity,_} -> % Clear timer - it will never trigger loop_event_actions( Parent, Debug, S, Events, Event, - State, NewState, NewData, Actions, + State, NextState, NewData, Actions, Postpone, Hibernate, undefined, NextEvents); {timeout,Time,_} = NewTimeout when is_integer(Time), Time >= 0 -> loop_event_actions( Parent, Debug, S, Events, Event, - State, NewState, NewData, Actions, + State, NextState, NewData, Actions, Postpone, Hibernate, NewTimeout, NextEvents); {timeout,_,_} -> ?TERMINATE( @@ -970,7 +989,7 @@ loop_event_actions( NewDebug = do_reply(Debug, S, Caller, Reply), loop_event_actions( Parent, NewDebug, S, Events, Event, - State, NewState, NewData, Actions, + State, NextState, NewData, Actions, Postpone, Hibernate, Timeout, NextEvents); false -> ?TERMINATE( @@ -981,7 +1000,7 @@ loop_event_actions( true -> loop_event_actions( Parent, Debug, S, Events, Event, - State, NewState, NewData, Actions, + State, NextState, NewData, Actions, Postpone, Hibernate, Timeout, [{Type,Content}|NextEvents]); false -> @@ -996,7 +1015,7 @@ loop_event_actions( %% End of actions list loop_event_actions( Parent, Debug, #{postponed := P0} = S, Events, Event, - State, NewState, NewData, [], + State, NextState, NewData, [], Postpone, Hibernate, Timeout, NextEvents) -> %% %% All options have been collected and next_events are buffered. @@ -1011,7 +1030,7 @@ loop_event_actions( end, {Q2,P} = % Move all postponed events to queue if state change if - NewState =:= State -> + NextState =:= State -> {Events,P1}; true -> {lists:reverse(P1, Events),[]} @@ -1024,9 +1043,9 @@ loop_event_actions( Debug, S, case Postpone of true -> - {postpone,Event,NewState}; + {postpone,Event,NextState}; false -> - {consume,Event,NewState} + {consume,Event,NextState} end), %% Have a peek on the event queue so we can avoid starting %% the state timer unless we have to @@ -1057,7 +1076,7 @@ loop_event_actions( loop_events( Parent, NewDebug, S#{ - state := NewState, + state := NextState, data := NewData, timer := Timer, postponed := P, diff --git a/lib/tools/doc/src/erlang_mode.xml b/lib/tools/doc/src/erlang_mode.xml index 4ecb8feadd..00cf5196b4 100644 --- a/lib/tools/doc/src/erlang_mode.xml +++ b/lib/tools/doc/src/erlang_mode.xml @@ -4,7 +4,7 @@
- 20032013 + 20032016 Ericsson AB. All Rights Reserved. @@ -252,6 +252,7 @@ behavior gen_event - skeleton for the OTP gen_event behavior gen_fsm - skeleton for the OTP gen_fsm behavior + gen_statem - skeleton for the OTP gen_statem behavior Library module - skeleton for a module that does not implement a process. Corba callback - skeleton for a Corba callback module. diff --git a/lib/tools/emacs/erlang-skels.el b/lib/tools/emacs/erlang-skels.el index 6880ec733c..cdf09ad502 100644 --- a/lib/tools/emacs/erlang-skels.el +++ b/lib/tools/emacs/erlang-skels.el @@ -1,7 +1,7 @@ ;; ;; %CopyrightBegin% ;; -;; Copyright Ericsson AB 2010-2014. All Rights Reserved. +;; Copyright Ericsson AB 2010-2016. All Rights Reserved. ;; ;; Licensed under the Apache License, Version 2.0 (the "License"); ;; you may not use this file except in compliance with the License. @@ -56,6 +56,8 @@ erlang-skel-gen-event erlang-skel-header) ("gen_fsm" "gen-fsm" erlang-skel-gen-fsm erlang-skel-header) + ("gen_statem" "gen-statem" + erlang-skel-gen-statem erlang-skel-header) ("wx_object" "wx-object" erlang-skel-wx-object erlang-skel-header) ("Library module" "gen-lib" @@ -858,6 +860,122 @@ Please see the function `tempo-define-template'.") "*The template of a gen_fsm. Please see the function `tempo-define-template'.") +(defvar erlang-skel-gen-statem + '((erlang-skel-include erlang-skel-large-header) + "-behaviour(gen_statem)." n n + + "%% API" n + "-export([start_link/0])." n + n + "%% gen_statem callbacks" n + "-export([init/1, terminate/3, code_change/4])." n + "-export([state_name/3])." n + "-export([handle_event/4])." n + n + "-define(SERVER, ?MODULE)." n + n + "-record(data, {})." n + n + (erlang-skel-double-separator-start 3) + "%%% API" n + (erlang-skel-double-separator-end 3) n + (erlang-skel-separator-start 2) + "%% @doc" n + "%% Creates a gen_statem process which calls Module:init/1 to" n + "%% initialize. To ensure a synchronized start-up procedure, this" n + "%% function does not return until Module:init/1 has returned." n + "%%" n + (erlang-skel-separator-end 2) + "-spec start_link() ->" n> + "{ok, Pid :: pid()} |" n> + "ignore |" n> + "{error, Error :: term()}." n + "start_link() ->" n> + "gen_statem:start_link({local, ?SERVER}, ?MODULE, [], [])." n + n + (erlang-skel-double-separator-start 3) + "%%% gen_statem callbacks" n + (erlang-skel-double-separator-end 3) n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% Whenever a gen_statem is started using gen_statem:start/[3,4] or" n + "%% gen_statem:start_link/[3,4], this function is called by the new" n + "%% process to initialize." n + (erlang-skel-separator-end 2) + "-spec init(Args :: term()) -> " n> + "{gen_statem:callback_mode()," n> + "State :: term(), Data :: term()} |" n> + "{gen_statem:callback_mode()," n> + "State :: term(), Data :: term()," n> + "[gen_statem:action()] | gen_statem:action()} |" n> + "ignore |" n> + "{stop, Reason :: term()}." n + "init([]) ->" n> + "{state_functions, state_name, #data{}}." n + n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% If the gen_statem runs with CallbackMode =:= state_functions" n + "%% there should be one instance of this function for each possible" n + "%% state name. Whenever a gen_statem receives an event," n + "%% the instance of this function with the same name" n + "%% as the current state name StateName is called to" n + "%% handle the event." n + (erlang-skel-separator-end 2) + "-spec state_name(" n> + "gen_statem:event_type(), Msg :: term()," n> + "Data :: term()) ->" n> + "gen_statem:state_function_result(). " n + "state_name({call,Caller}, _Msg, Data) ->" n> + "{next_state, state_name, Data, [{reply,Caller,ok}]}." n + n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% If the gen_statem runs with CallbackMode =:= handle_event_function" n + "%% this function is called for every event a gen_statem receives." n + (erlang-skel-separator-end 2) + "-spec handle_event(" n> + "gen_statem:event_type(), Msg :: term()," n> + "State :: term(), Data :: term()) ->" n> + "gen_statem:handle_event_result(). " n + "handle_event({call,From}, _Msg, State, Data) ->" n> + "{next_state, State, Data, [{reply,From,ok}]}." n + n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% This function is called by a gen_statem when it is about to" n + "%% terminate. It should be the opposite of Module:init/1 and do any" n + "%% necessary cleaning up. When it returns, the gen_statem terminates with" n + "%% Reason. The return value is ignored." n + (erlang-skel-separator-end 2) + "-spec terminate(Reason :: term(), State :: term(), Data :: term()) ->" n> + "any()." n + "terminate(_Reason, _State, _Data) ->" n> + "void." n + n + (erlang-skel-separator-start 2) + "%% @private" n + "%% @doc" n + "%% Convert process state when code is changed" n + (erlang-skel-separator-end 2) + "-spec code_change(" n> + "OldVsn :: term() | {down,term()}," n> + "State :: term(), Data :: term(), Extra :: term()) ->" n> + "{ok, NewState :: term(), NewData :: term()}." n + "code_change(_OldVsn, State, Data, _Extra) ->" n> + "{ok, State, Data}." n + n + (erlang-skel-double-separator-start 3) + "%%% Internal functions" n + (erlang-skel-double-separator-end 3) + ) + "*The template of a gen_statem. +Please see the function `tempo-define-template'.") + (defvar erlang-skel-wx-object '((erlang-skel-include erlang-skel-large-header) "-behaviour(wx_object)." n n -- cgit v1.2.3