Created
March 2, 2012 13:08
-
-
Save scartill/1958293 to your computer and use it in GitHub Desktop.
Very easy Erlang gen_server helper (GPROC enabled)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% Extends gen_server behaviour to support GProc | |
-module(easy_gen_server). | |
-export([behaviour_info/1, spec/1, spec/2, on_init/1, on_init/2]). | |
% Behaviour definition | |
behaviour_info(callbacks) -> | |
gen_server:behaviour_info(callbacks) | |
++ | |
[ | |
{procname, 1} | |
]; | |
behaviour_info(_Other) -> | |
undefined. | |
% Supervisor childspec | |
-spec spec(atom(), term()) -> supervisor:child_spec(). | |
spec(Module, Arg) -> | |
ProcName = Module:procname(Arg), | |
{ProcName, {gen_server, start_link, [Module, Arg, []]}, permanent, 5000, worker, [Module]}. | |
-spec spec(atom()) -> supervisor:child_spec(). | |
spec(Module) -> | |
spec(Module, none). | |
% Standard initialization helper | |
-spec on_init(atom()) -> term(). | |
on_init(Module) -> | |
process_flag(trap_exit, true), | |
gproc:add_local_name(Module:procname(none)). | |
-spec on_init(atom(), term()) -> term(). | |
on_init(Module, Arg) -> | |
process_flag(trap_exit, true), | |
gproc:add_local_name(Module:procname(Arg)). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% Fully standardized gen_server allowing autodispatch of the cast and calls | |
% Cast or call to it message like Handler or {Handler, Param} | |
% Handler is a private function of the module with prototypes: | |
% | |
% Handler(state()) -> stata() | |
% Handler(param(), state()) -> state() | |
% | |
% Macro GS_STD defines gen_server as one-liner | |
% | |
% Module which includes the file must have procname/1 as behaviour defines | |
% and procname/0 if GS_CAST is used without and process instance ID | |
% | |
% Note 1: calls are not supported at the moment | |
% Note 2: you can prepend any macro with your clause. | |
-behaviour(easy_gen_server). | |
-export([ | |
init/1, handle_call/3, handle_cast/2, terminate/2, | |
handle_info/2, code_change/3, | |
procname/1]). | |
-define(GS_INIT, | |
init(Arg) -> | |
easy_gen_server:on_init(?MODULE), | |
State = initialize(Arg), | |
{ok, State} | |
). | |
-define(GS_STD_CAST, | |
handle_cast(stop, State) -> | |
{stop, normal, State}; | |
handle_cast({Handler, Param}, State) -> | |
NewState = ?MODULE:Handler(Param, State), | |
{noreply, NewState}; | |
handle_cast(Handler, State) -> | |
NewState = ?MODULE:Handler(State), | |
{noreply, NewState} | |
). | |
-define(GS_STD_CALL, | |
handle_call(get_state, _, State) -> | |
{reply, State, State} | |
). | |
-define(GS_NO_INFO, | |
handle_info(_, State) -> | |
{noreply, State} | |
). | |
-define(GS_STD_CODE_CHANGE, | |
code_change(_Vsn, State, _Extra) -> | |
{ok, State} | |
). | |
-define(GS_STD_TERMINATE, | |
terminate(_, _) -> | |
ok | |
). | |
-define(GS_CAST(Name), | |
Name() -> | |
gen_server:cast(procname(), Name) | |
). | |
-define(GS_CAST(Name, Param), | |
Name(Param) -> | |
gen_server:cast(procname(), {Name, Param}) | |
). | |
-define(GS_CAST(Name, Param1, Param2), | |
Name(Param1, Param2) -> | |
gen_server:cast(procname(), {Name, {Param1, Param2}}) | |
). | |
-define(GS_CAST(Name, Param1, Param2, Param3), | |
Name(Param1, Param2, Param3) -> | |
gen_server:cast(procname(), {Name, {Param1, Param2, Param3}}) | |
). | |
-define(GS_CAST(Name, Param1, Param2, Param3, Param4), | |
Name(Param1, Param2, Param3, Param4) -> | |
gen_server:cast(procname(), {Name, {Param1, Param2, Param3, Param4}}) | |
). | |
-define(GS_CASTI(Name), | |
Name(ID) -> | |
gen_server:cast(procname(ID), Name) | |
). | |
-define(GS_CASTI(Name, Param), | |
Name(ID, Param) -> | |
gen_server:cast(procname(ID), {Name, Param}) | |
). | |
-define(GS_CASTI(Name, Param1, Param2), | |
Name(ID, Param1, Param2) -> | |
gen_server:cast(procname(ID), {Name, {Param1, Param2}}) | |
). | |
-define(GS_CASTI(Name, Param1, Param2, Param3), | |
Name(ID, Param1, Param2, Param3) -> | |
gen_server:cast(procname(ID), {Name, {Param1, Param2, Param3}}) | |
). | |
-define(GS_CASTI(Name, Param1, Param2, Param3, Param4), | |
Name(ID, Param1, Param2, Param3, Param4) -> | |
gen_server:cast(procname(ID), {Name, {Param1, Param2, Param3, Param4}}) | |
). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% Navigation satellites data processing process | |
-module(sample). | |
-include("easy_gen_server.hrl"). | |
-record(state, { | |
field | |
}). | |
% -= Interface | |
-export([test0/0, test1/1]). | |
-export([test0/1, test1/2]). | |
?GS_CAST(test0). | |
?GS_CAST(test1, Param). | |
% -= Genserver callbacks =- | |
% GProc and supervisor identifier | |
-spec procname(any()) -> navsats_dispatch. | |
procname(_) -> | |
my_genserver. | |
procname() -> | |
procname(none). | |
?GS_INIT. | |
?GS_STD_CAST. | |
?GS_STD_CALL. | |
?GS_NO_INFO. | |
?GS_STD_CODE_CHANGE. | |
?GS_STD_TERMINATE. | |
% -= Handlers | |
% Initialize the state | |
create_state(_) -> | |
#state{ }. | |
test0(State) -> | |
State. | |
test1(Param, State) -> | |
State. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment