diff options
author | Joe Zhao <ztuowen@gmail.com> | 2014-05-16 20:16:33 +0800 |
---|---|---|
committer | Joe Zhao <ztuowen@gmail.com> | 2014-05-16 20:16:33 +0800 |
commit | 859179718904a1824082fdbbf77192bd1ce762e7 (patch) | |
tree | 2869db33b8c21416676d6fc01eb65a079c318f83 /eventserv.erl | |
download | local-859179718904a1824082fdbbf77192bd1ce762e7.tar.gz local-859179718904a1824082fdbbf77192bd1ce762e7.tar.bz2 local-859179718904a1824082fdbbf77192bd1ce762e7.zip |
First commit
Diffstat (limited to 'eventserv.erl')
-rw-r--r-- | eventserv.erl | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/eventserv.erl b/eventserv.erl new file mode 100644 index 0000000..dc4dcde --- /dev/null +++ b/eventserv.erl @@ -0,0 +1,98 @@ +%%%------------------------------------------------------------------- +%%% @author Joe Zhao +%%% @copyright (C) 2014, <COMPANY> +%%% @doc +%%% This module serves the purpose of registering and monitoring different events +%%% Whether they are periodic or oneshot. +%%% Events are happening in a sense that none should be depending on those that happend before. +%%% Spawning one with mutable state is thus not recommended and not supported in such modules. +%%% Thus, the events are defined so that none of them would have states change during different invocations. +%%% @end +%%% Created : 27. 四月 2014 19:11 +%%%------------------------------------------------------------------- +-module(eventserv). +-author("Joe Zhao"). + +-include("eventserv.hrl"). +-compile([debug_info,export_all]). + +%% API +%%-export([]). + +event(Pid,S) -> + receive + {_PPid,shutdown} -> + io:format("I, ~p, am killed.\n",[S#event.name]) + after S#event.period -> + Pid ! {self(),run,S}, + if + S#event.spawn -> spawn(S#event.call,[self()]); + true -> (S#event.call)(self()) + end, + case S#event.type of + oneshot -> ok; + periodic -> event(Pid,S); + _Else -> ok + end + end. + +recloop(Events) -> + receive + {Pid,shutdown} -> [ Proc ! {self(),shutdown} || Proc<- orddict:fetch_keys(Events)]; + {PPid,reg,S} -> + Pid = spawn(?MODULE,event,[self(),S]), + link(Pid), + recloop(orddict:store(Pid,S,Events)); + {Pid,run,S} -> + io:format("Event run, type ~p: ~p\n",[S#event.type,S#event.name]), + recloop(Events); + {'EXIT',Pid,Cond} when Cond==normal;Cond==shutdown -> + io:format("Event died naturally, pid: ~p\n.",[Pid]), + recloop(orddict:erase(Pid,Events)); + {'EXIT',Pid,Cause} -> + S=orddict:fetch(Pid,Events), + io:format("Event died abruptly(~p), pid: ~p ; name: ~p\n.",[Cause,Pid,S#event.name]), + if + S#event.type == periodic -> + io:format("Event(periodic) will restart, name: ~p\n.",[S#event.name]), + self() ! {self(),reg,S} + end, + recloop(orddict:erase(Pid,Events)) + end. + +evemon(Events) -> + process_flag(trap_exit,true), + register(?MODULE,self()), + recloop(Events). + +start() -> + spawn(?MODULE,evemon,[orddict:new()]). + +reg_future(Name,Call,T) -> + eventserv ! {self(),reg,#event{name=Name,server=eventserv, + call=Call,period=T,type=oneshot}}. + +reg_future(Call,T) -> + eventserv ! {self(),reg,#event{name="Unamed",server=eventserv, + call=Call,period=T,type=oneshot}}. + +reg_periodic(Name,Call,T) -> + eventserv ! {self(),reg,#event{name=Name,server=eventserv, + call=Call,period=T}}. + +reg_periodic(Call,T) -> + eventserv ! {self(),reg,#event{name="Unamed",server=eventserv, + call=Call,period=T}}. + +regevent(Pid,S) -> + Pid ! {self(),reg,S}. + +test() -> + Pid=start(), + Pid ! {self(),reg,#event{name="test1",server=Pid, + call=fun (PPid) -> io:format("HAHA im here!!!!\n") end,period=1000}}, + timer:sleep(500), + Pid ! {self(),reg,#event{name="test2",server=Pid, + call=fun (PPid) -> io:format("HAHA im away and buggy!!!!\n"),exit("I just love to die") end,period=1000}}, + timer:sleep(10000), + Pid ! {self(),shutdown}.
\ No newline at end of file |