changed to a gen_server
This commit is contained in:
parent
e8db6fb211
commit
8a780adb2d
1 changed files with 92 additions and 40 deletions
|
@ -1,53 +1,105 @@
|
||||||
-module(ggs_table).
|
|
||||||
-export([
|
|
||||||
start_link/1,
|
|
||||||
add_player/2,
|
|
||||||
remove_player/2,
|
|
||||||
stop/2,
|
|
||||||
notify/3
|
|
||||||
]).
|
|
||||||
|
|
||||||
%% @doc This module represents a Player with a Socket and a Token
|
%% @doc This module represents a Player with a Socket and a Token
|
||||||
|
|
||||||
|
-module(ggs_table).
|
||||||
|
-behaviour(gen_server).
|
||||||
|
|
||||||
|
%% gen_server callbacks
|
||||||
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
|
terminate/2, code_change/3]).
|
||||||
|
|
||||||
|
-record(state, { token, players, socket, game_vm } ).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([start_link/2,
|
||||||
|
add_player/2,
|
||||||
|
remove_player/2,
|
||||||
|
stop/1,
|
||||||
|
notify/3]).
|
||||||
|
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
%% ----------------------------------------------------------------------
|
||||||
|
% API implementation
|
||||||
|
|
||||||
% @doc returns a new table
|
% @doc returns a new table
|
||||||
start_link(Token, Socket) ->
|
start_link(Token, Socket) ->
|
||||||
spawn_link(fun(Token, Socket) ->
|
GameVM = ggs_gamevm:start_link(),
|
||||||
GameVM = ggs_gamevm:start_link();
|
{ok, Pid} = gen_server:start_link(?MODULE, [Token, Socket, GameVM], []),
|
||||||
loop(Token, Socket, GameVM, [])
|
Pid.
|
||||||
).
|
|
||||||
|
%% @private
|
||||||
|
call(Pid, Msg) ->
|
||||||
|
gen_server:call(Pid, Msg, infinity).
|
||||||
|
|
||||||
% @doc adds a player to a table
|
% @doc adds a player to a table
|
||||||
add_player(Table, Player) ->
|
add_player(Table, Player) ->
|
||||||
ggs_logger:not_implemented().
|
call(Table, {add_player, Player}).
|
||||||
|
|
||||||
% @doc removes player form a table
|
% @doc removes player form a table
|
||||||
remove_player(Table, Player) ->
|
remove_player(Table, Player) ->
|
||||||
ggs_logger:not_implemented().
|
call(Table, {remove_player, Player}).
|
||||||
|
|
||||||
% @doc stops the table process
|
% @doc stops the table process
|
||||||
stop(Table) ->
|
stop(Table) ->
|
||||||
Table ! {'EXIT', self(), normal}
|
gen_server:cast(Table, stop).
|
||||||
|
|
||||||
% @doc notifies the table with a message from a player
|
% @doc notifies the table with a message from a player
|
||||||
notify(Table, Player, Message) ->
|
notify(Table, Player, Message) ->
|
||||||
Table ! {notify, Player, Message}.
|
gen_server:cast(Table, {notify, Player, Message}).
|
||||||
|
|
||||||
% loop
|
%% ----------------------------------------------------------------------
|
||||||
loop(Token, Socket, GameVM, PlayerList) ->
|
|
||||||
receive
|
%% @private
|
||||||
{add_player, Player} ->
|
init([Token, Socket, GameVM]) ->
|
||||||
NewPlayerList = list:append(PlayerList, [Player]),
|
{ok, #state { token = Token,
|
||||||
loop(Token, Socket, GameVM, NewPlayerList);
|
socket = Socket,
|
||||||
{remove_player, Player} ->
|
game_vm = GameVM,
|
||||||
NewPlayerList = list:delete(Player, PlayerList),
|
players = [] }}.
|
||||||
loop(Token, Socket, GameVM, NewPlayerList);
|
|
||||||
{notify, Player, Message} ->
|
%% @private
|
||||||
case Message of
|
handle_call({add_player, Player}, _From, #state { players = Players } = State) ->
|
||||||
{server, define, Args} ->
|
{reply, ok, State#state { players = [Player | Players] }};
|
||||||
ggs_gamevm:define(GameVM, Args),
|
handle_call({remove_player, Player}, _From, #state { players = Players } = State) ->
|
||||||
loop(Token, Socket, GameVM, PlayerList);
|
{reply, ok, State#state { players = Players -- [Player] }};
|
||||||
{game, Command, Args} ->
|
handle_call(Msg, _From, State) ->
|
||||||
ggs_gamevm:user_command(GameVM, Player, Command, Args),
|
error_logger:error_report([unknown_msg, Msg]),
|
||||||
loop(Token, Socket, GameVM, PlayerList);
|
{reply, ok, State}.
|
||||||
end
|
|
||||||
end.
|
%% @private
|
||||||
|
handle_cast({notify, Player, Message}, #state { game_vm = GameVM } = State) ->
|
||||||
|
case Message of
|
||||||
|
{server, define, Args} ->
|
||||||
|
ggs_gamevm:define(GameVM, Args);
|
||||||
|
{game, Command, Args} ->
|
||||||
|
ggs_gamevm:user_command(GameVM, Player, Command, Args)
|
||||||
|
end,
|
||||||
|
{noreply, State};
|
||||||
|
handle_cast(stop, State) ->
|
||||||
|
{stop, normal, State};
|
||||||
|
handle_cast(Msg, S) ->
|
||||||
|
error_logger:error_report([unknown_msg, Msg]),
|
||||||
|
{noreply, S}.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
handle_info(Msg, S) ->
|
||||||
|
error_logger:error_report([unknown_msg, Msg]),
|
||||||
|
{noreply, S}.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
terminate(_Reason, _State) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
|
{ok, State}.
|
||||||
|
|
||||||
|
|
||||||
|
%% ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
% Tests
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
start_link_test() ->
|
||||||
|
ClientToken = "123",
|
||||||
|
Pid = start_link(ClientToken, none),
|
||||||
|
?assertNot(Pid =:= undefined).
|
||||||
|
|
Reference in a new issue