diff --git a/src/ggs_api.js b/src/ggs_api.js index 21c3ddd..e3087c2 100644 --- a/src/ggs_api.js +++ b/src/ggs_api.js @@ -61,15 +61,15 @@ function _GGS(tableToken) { var tableToken = this.tableToken; this.__defineGetter__("tableToken", function() { return tableToken; - }) + }); } - +/* function _GGS.prototype.sendCommandToAll(command, args) { var message = "{" + command + "," + args + "}"; callErlang("ggs_table send_command_to_all " + escapeErlang([this.tableToken, message])); } - +*/ function _GGS.prototype.serverLog(message) { callErlang("error_logger info_msg " + escapeErlang([message])) } diff --git a/src/ggs_coordinator.erl b/src/ggs_coordinator.erl index 14a7048..b02f02d 100644 --- a/src/ggs_coordinator.erl +++ b/src/ggs_coordinator.erl @@ -1,8 +1,17 @@ -module(ggs_coordinator). %% API Exports --export([start_link/0, stop/1, join_table/1, create_table/1, join_lobby/0, - respawn_player/2, respawn_table/1, remove_player/2, get_all_players/0]). +-export([ start_link/0, + stop/1, + join_table/1, + create_table/1, + join_lobby/0, + respawn_player/2, + respawn_table/1, + remove_player/2, + get_all_players/0, + table_token_to_pid/1, + table_pid_to_token/1]). %% gen_server callback exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, @@ -56,6 +65,15 @@ remove_player(_From, _Player) -> get_all_players() -> gen_server:call(?SERVER, get_all_players). + +%% Conversion tools + +table_token_to_pid(Token) -> + gen_server:call(?SERVER, {table_token_to_pid, Token}). + +table_pid_to_token(Pid) -> + gen_server:call(?SERVER, {table_pid_to_token, Pid}). + %% Just to shorten the name back_up(State) -> ggs_coordinator_backup:back_up(State), @@ -91,20 +109,31 @@ handle_call({join_table, Table}, From, State) -> {reply, {error, no_such_table}, State} end; -handle_call({create_table, {force, TableID}}, From, State) -> +handle_call({create_table, {force, TableToken}}, From, State) -> TableIDMap = State#co_state.player_table_map, Tables = State#co_state.tables, - NewTableProc = ggs_table:start(), % With start_link, the table dies with the coordinator + NewTableProc = ggs_table:start(TableToken), % With start_link, the table dies with the coordinator NewState = State#co_state{ - player_table_map = [{From, TableID} | TableIDMap], - tables = [{TableID, NewTableProc} | Tables] + player_table_map = [{From, TableToken} | TableIDMap], + tables = [{TableToken, NewTableProc} | Tables] }, back_up(NewState), - {reply, {ok, TableID}, NewState}; + {reply, {ok, TableToken}, NewState}; handle_call(get_all_players, _From, State) -> {reply, State#co_state.players, State}; +%% Conversion tools +handle_call({table_token_to_pid, Token}, _From, State) -> + Tables = State#co_state.tables, + {_, Pid} = lists:keyfind(Token, 1, Tables), + {reply, Pid, State}; + +handle_call({table_pid_to_token, Pid}, _From, State) -> + Tables = State#co_state.tables, + {Token, _} = lists:keyfind(Pid, 2, Tables), + {reply, Token, State}; + handle_call(_Message, _From, State) -> {noreply, State}. diff --git a/src/ggs_gamevm.erl b/src/ggs_gamevm.erl index 354e7aa..a18a7f4 100644 --- a/src/ggs_gamevm.erl +++ b/src/ggs_gamevm.erl @@ -13,8 +13,6 @@ %% API -export([start_link/1, define/2, player_command/4, stop/1, call_js/2]). --include_lib("eunit/include/eunit.hrl"). - %% ---------------------------------------------------------------------- % API implementation @@ -56,8 +54,8 @@ stop(GameVM) -> init([Table]) -> process_flag(trap_exit, true), {ok, Port} = js_driver:new(), - %% @TODO: add here default JS API instead - {ok, JSAPISourceCode} = file:read_file("ggs_api.js"), +% %% @TODO: add here default JS API instead + {ok, JSAPISourceCode} = file:read_file("src/ggs_api.js"), ok = js:define(Port, JSAPISourceCode), {ok, #state { port = Port, table = Table }}. diff --git a/src/ggs_gamevm_e.erl b/src/ggs_gamevm_e.erl index 10dd74b..e523273 100644 --- a/src/ggs_gamevm_e.erl +++ b/src/ggs_gamevm_e.erl @@ -44,20 +44,20 @@ loop(Table) -> do_stuff(Command, Args, Player, Table) -> case Command of "greet" -> - ggs_player:notify(Player, server, "Hello there!\n"); + ggs_table:notify_player(Table, Player, server, "Hello there!\n"); "chat" -> Nick = ggs_db:getItem(Table, nicks, Player), ggs_table:notify_all_players(Table, "<"++Nick++"> "++ Args ++ "\n"); "uname" -> Uname = os:cmd("uname -a"), - ggs_player:notify(Player, server, Uname); + ggs_table:notify_player(Table, Player, server, Uname); "lusers" -> {ok, Players} = ggs_table:get_player_list(Table), Nicks = lists:map(fun (P) -> ggs_db:getItem(Table, nicks, P) end, Players), - ggs_player:notify(Player, server,io_lib:format("LUSERS ~p\n",[Nicks])); + ggs_table:notify_player(Table, Player, server,io_lib:format("LUSERS ~p\n",[Nicks])); "nick" -> ggs_db:setItem(Table,nicks,Player,Args), io:format("Changing nickname of ~p to ~p.", [Player, Args]); _Other -> - ggs_player:notify(Player, server, "I don't know that command..\n") + ggs_table:notify_player(Table, Player, server, "I don't know that command..\n") end. diff --git a/src/ggs_table.erl b/src/ggs_table.erl index d86abb5..c0bff36 100644 --- a/src/ggs_table.erl +++ b/src/ggs_table.erl @@ -10,22 +10,23 @@ -record(state, { players, game_vm } ). %% API --export([start/0, +-export([start/1, add_player/2, remove_player/2, stop/1, notify/3, notify_all_players/2, notify_game/3, - get_player_list/1]). + get_player_list/1, + notify_player/4]). %% ---------------------------------------------------------------------- % API implementation % @doc returns a new table -start() -> - {ok, Pid} = gen_server:start(?MODULE, [], []), +start(Token) -> + {ok, Pid} = gen_server:start(?MODULE, [Token], []), Pid. %% @private @@ -41,22 +42,32 @@ remove_player(Table, Player) -> call(Table, {remove_player, Player}). %% @doc Get a list of all player processes attached to this table -get_player_list(Table) -> - gen_server:call(Table, get_player_list). +get_player_list(TableToken) -> + TablePid = ggs_coordinator:table_token_to_pid(TableToken), + gen_server:call(TablePid, get_player_list). % @doc stops the table process stop(Table) -> gen_server:cast(Table, stop). % @doc notifies the table with a message from a player -notify(Table, Player, Message) -> - gen_server:cast(Table, {notify, Player, Message}). +notify(TablePid, Player, Message) -> + %TablePid = ggs_coordinator:table_token_to_pid(TableToken), + gen_server:cast(TablePid, {notify, Player, Message}). -notify_all_players(Table, Message) -> - gen_server:cast(Table, {notify_all_players, Message}). +notify_all_players(TableToken, Message) -> + TablePid = ggs_coordinator:table_token_to_pid(TableToken), + gen_server:cast(TablePid, {notify_all_players, Message}). -notify_game(Table, From, Message) -> - gen_server:cast(Table, {notify_game, Message, From}). +notify_game(TablePid, From, Message) -> + TableToken = ggs_coordinator:table_pid_to_token(TablePid), + gen_server:cast(TableToken, {notify_game, Message, From}). + +%% @doc Notify a player sitting at this table with the message supplied. +%% Player, Table and From are in token form. +notify_player(TableToken, Player, From, Message) -> + TablePid = ggs_coordinator:table_token_to_pid(TableToken), + gen_server:cast(TablePid, {notify_player, Player, From, Message}). send_command(TableToken, PlayerToken, Command, Args) -> gen_logger:not_implemented(). @@ -68,9 +79,9 @@ send_command_to_all(TableToken, Command, Args) -> %% ---------------------------------------------------------------------- %% @private -init([]) -> +init([TableToken]) -> process_flag(trap_exit, true), - GameVM = ggs_gamevm:start_link(self()), + GameVM = ggs_gamevm_e:start_link(TableToken), {ok, #state { game_vm = GameVM, players = [] }}. @@ -93,14 +104,14 @@ handle_call(Msg, _From, State) -> handle_cast({notify, Player, Message}, #state { game_vm = GameVM } = State) -> case Message of {server, define, Args} -> - ggs_gamevm:define(GameVM, Args); + ggs_gamevm_e:define(GameVM, Args); {game, Command, Args} -> - ggs_gamevm:player_command(GameVM, Player, Command, Args) + ggs_gamevm_e:player_command(GameVM, Player, Command, Args) end, {noreply, State}; handle_cast({notify_game, Message, From}, #state { game_vm = GameVM } = State) -> - ggs_gamevm:player_command(GameVM, From, Message, ""), + ggs_gamevm_e:player_command(GameVM, From, Message, ""), {noreply, State}; handle_cast({notify_all_players, Message}, #state{players = Players} = State) -> @@ -110,6 +121,10 @@ handle_cast({notify_all_players, Message}, #state{players = Players} = State) -> ), {noreply, State}; +handle_cast({notify_player, Player, From, Message}, State) -> + ggs_player:notify(Player, From, Message), + {noreply, State}; + handle_cast(stop, State) -> {stop, normal, State}; handle_cast(Msg, S) ->