165 lines
4.3 KiB
Erlang
165 lines
4.3 KiB
Erlang
% vim: ts=4 sw=4 et
|
|
% Copyright (c) 2013 Jesse Gumm
|
|
% See LICENSE for licensing information.
|
|
|
|
-module(qdate_srv).
|
|
-behaviour(gen_server).
|
|
|
|
-define(SRV, ?MODULE).
|
|
|
|
-export([
|
|
start_link/0,
|
|
init/1,
|
|
handle_call/3,
|
|
handle_cast/2,
|
|
handle_info/2,
|
|
code_change/3,
|
|
terminate/2
|
|
]).
|
|
|
|
-export([
|
|
set_timezone/1,
|
|
set_timezone/2,
|
|
get_timezone/0,
|
|
get_timezone/1,
|
|
clear_timezone/0,
|
|
clear_timezone/1,
|
|
|
|
register_parser/1,
|
|
register_parser/2,
|
|
get_parsers/0,
|
|
deregister_parsers/0,
|
|
deregister_parser/1,
|
|
|
|
register_format/2,
|
|
get_format/1,
|
|
deregister_format/1
|
|
]).
|
|
|
|
%% PUBLIC API FUNCTIONS
|
|
|
|
start_link() ->
|
|
gen_server:start_link({local, ?SRV}, ?MODULE, [], []).
|
|
|
|
set_timezone(TZ) ->
|
|
set_timezone(self(),TZ).
|
|
|
|
set_timezone(Key,TZ) ->
|
|
ok = gen_server:call(?SRV,{set_timezone,Key,TZ}).
|
|
|
|
get_timezone() ->
|
|
get_timezone(self()).
|
|
|
|
get_timezone(Key) ->
|
|
gen_server:call(?SRV,{get_timezone,Key}).
|
|
|
|
clear_timezone() ->
|
|
clear_timezone(self()).
|
|
|
|
clear_timezone(Key) ->
|
|
ok = gen_server:call(?SRV, {clear_timezone, Key}).
|
|
|
|
register_parser(Parser) when is_function(Parser,1) ->
|
|
register_parser(erlang:make_ref(),Parser).
|
|
|
|
register_parser(Key,Parser) when is_function(Parser,1) ->
|
|
Key = gen_server:call(?SRV,{register_parser,Key,Parser}).
|
|
|
|
deregister_parser(Key) ->
|
|
ok = gen_server:call(?SRV,{deregister_parser,Key}).
|
|
|
|
deregister_parsers() ->
|
|
ok = gen_server:call(?SRV,{deregister_parsers}).
|
|
|
|
get_parsers() ->
|
|
gen_server:call(?SRV,{get_parsers}).
|
|
|
|
register_format(Key,Format) ->
|
|
ok = gen_server:call(?SRV,{register_format,Key,Format}).
|
|
|
|
get_format(Key) ->
|
|
gen_server:call(?SRV,{get_format,Key}).
|
|
|
|
deregister_format(Key) ->
|
|
ok = gen_server:call(?SRV,{deregister_format,Key}).
|
|
|
|
|
|
%% SERVER FUNCTIONS
|
|
|
|
-record(state, {tz, parsers, formats}).
|
|
|
|
init(_) ->
|
|
State = #state{tz=dict:new(),parsers=dict:new(),formats=dict:new()},
|
|
{ok, State}.
|
|
|
|
handle_cast(_,State) ->
|
|
{noreply, State}.
|
|
|
|
handle_info({'DOWN', MonitorRef, process, Pid, _Reason}, State) ->
|
|
erlang:demonitor(MonitorRef),
|
|
NewTZ = dict:erase(Pid, State#state.tz),
|
|
NewParsers = dict:erase(Pid, State#state.parsers),
|
|
NewFormats = dict:erase(Pid, State#state.formats),
|
|
NewState = State#state{tz=NewTZ, parsers=NewParsers, formats=NewFormats},
|
|
{noreply, NewState };
|
|
handle_info(_, State) ->
|
|
{noreply, State}.
|
|
|
|
handle_call({set_timezone,Key,TZ}, _From, State) ->
|
|
monitor_if_pid(Key),
|
|
NewTZ = dict:store(Key, TZ, State#state.tz),
|
|
NewState = State#state{tz=NewTZ},
|
|
{reply, ok, NewState};
|
|
handle_call({clear_timezone,Key},_From, State) ->
|
|
NewTZ = dict:erase(Key, State#state.tz),
|
|
NewState = State#state{tz=NewTZ},
|
|
{reply, ok, NewState};
|
|
handle_call({get_timezone,Key},_From, State) ->
|
|
Reply = case dict:find(Key, State#state.tz) of
|
|
error -> undefined;
|
|
{ok,TZ} -> TZ
|
|
end,
|
|
{reply, Reply, State};
|
|
|
|
handle_call({register_parser,Key,Parser},_From,State) ->
|
|
NewParsers = dict:store(Key, Parser, State#state.parsers),
|
|
NewState = State#state{parsers=NewParsers},
|
|
{reply, Key, NewState};
|
|
handle_call({get_parsers},_From,State) ->
|
|
Reply = dict:to_list(State#state.parsers),
|
|
{reply, Reply, State};
|
|
handle_call({deregister_parser,Key},_From,State) ->
|
|
NewParsers = dict:erase(Key, State#state.parsers),
|
|
NewState = State#state{parsers=NewParsers},
|
|
{reply, ok, NewState};
|
|
handle_call({deregister_parsers},_From,State) ->
|
|
NewState = State#state{parsers=dict:new()},
|
|
{reply, ok, NewState};
|
|
|
|
handle_call({register_format,Key,Format},_From,State) ->
|
|
NewFormats = dict:store(Key, Format, State#state.formats),
|
|
NewState = State#state{formats=NewFormats},
|
|
{reply, ok, NewState};
|
|
handle_call({get_format,Key},_From,State) ->
|
|
Reply = case dict:find(Key, State#state.formats) of
|
|
error -> undefined;
|
|
{ok, Format} -> Format
|
|
end,
|
|
{reply, Reply,State};
|
|
handle_call({deregister_format,Key},_From,State) ->
|
|
NewFormats = dict:erase(Key, State#state.formats),
|
|
NewState = State#state{formats=NewFormats},
|
|
{reply, ok, NewState}.
|
|
|
|
terminate(_Reason, _State) ->
|
|
ok.
|
|
|
|
code_change(_OldVersion, State, _Extra) ->
|
|
{ok, State}.
|
|
|
|
%% PRIVATE TOOLS
|
|
|
|
monitor_if_pid(Key) when is_pid(Key) ->
|
|
erlang:monitor(process,Key);
|
|
monitor_if_pid(_) ->
|
|
do_nothing.
|