%%%===================================================================%%% This event handler is to be attached once per user.%%% Its role is to log messages routed through a user and%%% message them back to a client on demand.%%%===================================================================-module(chut_user_history_handler).-compile(export_all).-behaviour(gen_event).-export([init/1,handle_event/2,handle_call/2,handle_info/2,terminate/2,code_change/3]).%%====================================================================%% gen_event callbacks%%====================================================================%%--------------------------------------------------------------------%% Function: init({UserId, Limit}) -> {ok, {UserId, Limit, []}}%% Description: Whenever a new event handler is added to an event manager,%% this function is called to initialize the event handler. The state%% is constituted of the User's Id (to couple it to messages) and%% a limit (how many messages need to be kept in history).%%--------------------------------------------------------------------init({UserId,Limit})->{ok,{UserId,Limit,queue:new()}}.%%--------------------------------------------------------------------%% Function:%% handle_event(Event, State) -> {ok, State} |%% {swap_handler, Args1, State1, Mod2, Args2} |%% remove_handler%% Description:Whenever an event manager receives an event sent using%% gen_event:notify/2 or gen_event:sync_notify/2, this function is called for%% each installed event handler to handle the event.%%%% Handles two kind of messages: received and sent messages. It wraps%% them with a tuple containing the handler's id and the user's id%% so many clients can be within a single process.%%--------------------------------------------------------------------handle_event(Event={received,_,_},{UserId,Limit,History})->{ok,{UserId,Limit,add_to_history(Event,History,Limit)}};handle_event({send,To,Msg},{UserId,Limit,History})->Event={sent,To,Msg},{ok,{UserId,Limit,add_to_history(Event,History,Limit)}};handle_event({From,history},S={UserId,_,History})->From!{UserId,{history,queue:to_list(History)}},{ok,S};handle_event(_Event,State)->{ok,State}.%%--------------------------------------------------------------------%% Function:%% handle_call(Request, State) -> {ok, Reply, State} |%% {swap_handler, Reply, Args1, State1,%% Mod2, Args2} |%% {remove_handler, Reply}%% Description: Whenever an event manager receives a request sent using%% gen_event:call/3,4, this function is called for the specified event%% handler to handle the request.%%--------------------------------------------------------------------handle_call(_Request,State)->Reply=ok,{ok,Reply,State}.%%--------------------------------------------------------------------%% Function:%% handle_info(Info, State) -> {ok, State} |%% {swap_handler, Args1, State1, Mod2, Args2} |%% remove_handler%% Description: This function is called for each installed event handler when%% an event manager receives any other message than an event or a synchronous%% request (or a system message).%%--------------------------------------------------------------------handle_info(_Info,State)->{ok,State}.%%--------------------------------------------------------------------%% Function: terminate(Reason, State) -> void()%% Description:Whenever an event handler is deleted from an event manager,%% this function is called. It should be the opposite of Module:init/1 and%% do any necessary cleaning up.%%--------------------------------------------------------------------terminate(_Reason,_State)->ok.%%--------------------------------------------------------------------%% Function: code_change(OldVsn, State, Extra) -> {ok, NewState}%% Description: Convert process state when code is changed%%--------------------------------------------------------------------code_change(_OldVsn,State,_Extra)->{ok,State}.%%===================================================================%% Internal functions%%===================================================================%%-------------------------------------------------------------------%% Function: add_to_history(Event, History, Limit) -> NewHistory%% Description: prepends a new event to the history (a list of%% events). If the list gets larger than the given limit, it is%% truncated.%%-------------------------------------------------------------------add_to_history(_,_,0)->queue:new();add_to_history(Event,History,Limit)->casequeue:len(History)ofLimit->queue:in(Event,queue:drop(History));_->queue:in(Event,History)end.