game_observer.erl 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. %%%-------------------------------------------------------------------
  2. %%% @author Dayneko Roman <me@h0.org.ua>
  3. %%% @copyright (C) 2014, Dayneko Roman
  4. %%% @doc
  5. %%%
  6. %%% @end
  7. %%% Created : 22 Apr 2014 by Dayneko Roman <me@h0.org.ua>
  8. %%%-------------------------------------------------------------------
  9. -module(game_observer).
  10. -behaviour(gen_server).
  11. -include_lib("kvs/include/kvs.hrl").
  12. -include_lib("db/include/game_event_container.hrl").
  13. -include_lib("server/include/requests.hrl").
  14. %% API
  15. -export([start_link/0]).
  16. %% gen_server callbacks
  17. -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
  18. terminate/2, code_change/3]).
  19. %% api
  20. -export([mypid/0, clear_history/0, get_history/0, log_event/1]).
  21. -define(SERVER, ?MODULE).
  22. -record(state, {history = []}).
  23. %%%===================================================================
  24. %%% API
  25. %%%===================================================================
  26. %%--------------------------------------------------------------------
  27. %% @doc
  28. %% Starts the server
  29. %%
  30. %% @spec start_link() -> {ok, Pid} | ignore | {error, Error}
  31. %% @end
  32. %%--------------------------------------------------------------------
  33. start_link() ->
  34. gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
  35. mypid() ->
  36. gen_server:call(?SERVER, mypid).
  37. clear_history() ->
  38. gen_server:cast(?SERVER, clear_history).
  39. get_history() ->
  40. gen_server:call(?SERVER, get_history).
  41. log_event(Event) ->
  42. gen_server:cast(?SERVER, {log_event, Event}).
  43. %%%===================================================================
  44. %%% gen_server callbacks
  45. %%%===================================================================
  46. %%--------------------------------------------------------------------
  47. %% @private
  48. %% @doc
  49. %% Initializes the server
  50. %%
  51. %% @spec init(Args) -> {ok, State} |
  52. %% {ok, State, Timeout} |
  53. %% ignore |
  54. %% {stop, Reason}
  55. %% @end
  56. %%--------------------------------------------------------------------
  57. init([]) ->
  58. {ok, #state{}}.
  59. %%--------------------------------------------------------------------
  60. %% @private
  61. %% @doc
  62. %% Handling call messages
  63. %%
  64. %% @spec handle_call(Request, From, State) ->
  65. %% {reply, Reply, State} |
  66. %% {reply, Reply, State, Timeout} |
  67. %% {noreply, State} |
  68. %% {noreply, State, Timeout} |
  69. %% {stop, Reason, Reply, State} |
  70. %% {stop, Reason, State}
  71. %% @end
  72. %%--------------------------------------------------------------------
  73. handle_call(mypid, _From, State) ->
  74. {reply, {ok, self()}, State};
  75. handle_call(get_history, _From, #state{history = History} = State) ->
  76. {reply, {ok, lists:reverse(History)}, State};
  77. handle_call(_Request, _From, State) ->
  78. gas:info(?MODULE, ">>>>>>>>>>>>>>>>> call message ~p from ~p", [_Request, _From]),
  79. Reply = ok,
  80. {reply, Reply, State}.
  81. %%--------------------------------------------------------------------
  82. %% @private
  83. %% @doc
  84. %% Handling cast messages
  85. %%
  86. %% @spec handle_cast(Msg, State) -> {noreply, State} |
  87. %% {noreply, State, Timeout} |
  88. %% {stop, Reason, State}
  89. %% @end
  90. %%--------------------------------------------------------------------
  91. handle_cast({log_event, #game_event{game = GameId, event = EventName, args = Args} = Event}, #state{history = History} = State) ->
  92. PlayerId = case lists:keyfind(player, 1, Args) of {_, Id} -> Id; _ -> <<"unknow">> end,
  93. Container =
  94. #game_event_container{
  95. feed_id = {GameId, PlayerId},
  96. id = {timestamp(), GameId, PlayerId},
  97. game_id = GameId,
  98. event = EventName,
  99. timestamp = calendar:now_to_universal_time(erlang:now()), %% date in universal time
  100. game_event = Event},
  101. gas:info(?MODULE, ">>>>>>>>>>>>>>>>> Container ~p", [Container]),
  102. kvs:add(Container), %% will be spamming kvs
  103. {noreply, State#state{history = [Event | History]}};
  104. handle_cast(clear_history, State) ->
  105. {noreply, State#state{history = []}};
  106. handle_cast(_Msg, State) ->
  107. gas:info(?MODULE, ">>>>>>>>>>>>>>>>> cast message ~p", [_Msg]),
  108. {noreply, State}.
  109. %%--------------------------------------------------------------------
  110. %% @private
  111. %% @doc
  112. %% Handling all non call/cast messages
  113. %%
  114. %% @spec handle_info(Info, State) -> {noreply, State} |
  115. %% {noreply, State, Timeout} |
  116. %% {stop, Reason, State}
  117. %% @end
  118. %%--------------------------------------------------------------------
  119. %%handle_info({relay_event, _Ref, #game_event{game = GameId, event = Event, args = Args} = GameEvent},
  120. %% #state{history = History} = State) ->
  121. %%
  122. %% {_, PlayerId} = lists:keyfind(player, 1, Args),
  123. %%
  124. %% Container =
  125. %% #game_event_container{
  126. %% feed_id = {GameId, PlayerId},
  127. %% id = {timestamp(), GameId, PlayerId},
  128. %% game_id = GameId,
  129. %% event = Event,
  130. %% timestamp = calendar:now_to_universal_time(erlang:now()), %% date in universal time
  131. %% game_event = GameEvent},
  132. %%
  133. %% gas:info(?MODULE, ">>>>>>>>>>>>>>>>> Container ~p", [Container]),
  134. %%
  135. %% kvs:add(Container), %% will be spamming kvs
  136. %% {noreply, State#state{history = [Event | History]}};
  137. handle_info(_Info, State) ->
  138. gas:info(?MODULE, ">>>>>>>>>>>>>>>>> info message ~p", [_Info]),
  139. {noreply, State}.
  140. %%--------------------------------------------------------------------
  141. %% @private
  142. %% @doc
  143. %% This function is called by a gen_server when it is about to
  144. %% terminate. It should be the opposite of Module:init/1 and do any
  145. %% necessary cleaning up. When it returns, the gen_server terminates
  146. %% with Reason. The return value is ignored.
  147. %%
  148. %% @spec terminate(Reason, State) -> void()
  149. %% @end
  150. %%--------------------------------------------------------------------
  151. terminate(_Reason, _State) ->
  152. ok.
  153. %%--------------------------------------------------------------------
  154. %% @private
  155. %% @doc
  156. %% Convert process state when code is changed
  157. %%
  158. %% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
  159. %% @end
  160. %%--------------------------------------------------------------------
  161. code_change(_OldVsn, State, _Extra) ->
  162. {ok, State}.
  163. %%%===================================================================
  164. %%% Internal functions
  165. %%%===================================================================
  166. timestamp() ->
  167. {MegaSec, Sec, MiliSec} = erlang:now(),
  168. MegaSec * 1000 * 1000 * 1000 + Sec * 1000 + MiliSec.