From 0361558f4bd4be9c907959d2c4fbc0c4c4d88ff2 Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Sun, 6 Feb 2011 19:25:36 +0100 Subject: [PATCH 01/15] added js_helper module --- src/js_helper.erl | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/js_helper.erl diff --git a/src/js_helper.erl b/src/js_helper.erl new file mode 100644 index 0000000..efb38f4 --- /dev/null +++ b/src/js_helper.erl @@ -0,0 +1,8 @@ +-module(js_helper). +-export([test/0, echo/1]). + +test() -> + {ok, test}. + +echo(String) -> + {ok, String}. \ No newline at end of file From 654aa837ddacc2623b418173a48072f6b22873de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20P=C3=A5lsson?= Date: Thu, 17 Feb 2011 09:35:39 +0100 Subject: [PATCH 02/15] Added some tests for coordinator --- src/ggs_coordinator.erl | 7 +++++-- tests/ggs_coordinator_test.erl | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 tests/ggs_coordinator_test.erl diff --git a/src/ggs_coordinator.erl b/src/ggs_coordinator.erl index 4e6b623..a28fc2a 100644 --- a/src/ggs_coordinator.erl +++ b/src/ggs_coordinator.erl @@ -16,8 +16,8 @@ start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). %% @doc Terminates the coordinator process. -stop(_Reason) -> - ggs_logger:not_implemented(). +stop(Reason) -> + gen_server:cast(ggs_coordinator, {stop, Reason}). %% @doc Joins table with specified token join_table(_Token) -> @@ -52,6 +52,9 @@ init([]) -> handle_call(_Message, _From, State) -> {noreply, State}. +handle_cast({stop, Reason}, State) -> + {stop, normal, state}; + handle_cast(_Message, State) -> {noreply, State}. diff --git a/tests/ggs_coordinator_test.erl b/tests/ggs_coordinator_test.erl new file mode 100644 index 0000000..03b5389 --- /dev/null +++ b/tests/ggs_coordinator_test.erl @@ -0,0 +1,16 @@ +-module(ggs_coordinator_test). +-include_lib("eunit/include/eunit.hrl"). + +start_link_test() -> + {ok, Coord} = ggs_coordinator:start_link(), % Start + PInfo = erlang:process_info(Coord), % Check process info + ggs_coordinator:stop(""), % Clean up + timer:sleep(100), % Wait for cleaning.. + ?assert((PInfo /= undefined)). % Did the server start? + +stop_test() -> + ok = ggs_coordinator:stop(""), % Extra cleaning + {ok, Coord} = ggs_coordinator:start_link(), % Start server + ggs_coordinator:stop("Terminate now"), % Send stop message + timer:sleep(100), % Wait for cleaning.. + ?assert((erlang:process_info(Coord) == undefined)). % Did it stop? From 391af1a96af8b2f603459181bedcd1e191668a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20P=C3=A5lsson?= Date: Thu, 17 Feb 2011 10:04:54 +0100 Subject: [PATCH 03/15] Added more tests & functionality. (failing join table, create_table_test with force) --- src/ggs_coordinator.erl | 21 ++++++++++++++------- tests/ggs_coordinator_test.erl | 17 +++++++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/ggs_coordinator.erl b/src/ggs_coordinator.erl index a28fc2a..2a5d509 100644 --- a/src/ggs_coordinator.erl +++ b/src/ggs_coordinator.erl @@ -1,7 +1,7 @@ -module(ggs_coordinator). %% API Exports --export([start_link/0, stop/1]). +-export([start_link/0, stop/1, join_table/1, create_table/1]). %% gen_server callback exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, @@ -19,13 +19,14 @@ start_link() -> stop(Reason) -> gen_server:cast(ggs_coordinator, {stop, Reason}). -%% @doc Joins table with specified token -join_table(_Token) -> - ggs_logger:not_implemented(). +%% @doc Joins table with specified token, returns {error, no_such_table} +%% if the specified table token does not exist +join_table(Token) -> + gen_server:call(ggs_coordinator, {join_table, Token}). -%% @doc Create a new table -create_table(_Params) -> - ggs_logger:not_implemented(). +%% @doc Create a new table, return {error, Reason} or {ok, TableToken} +create_table(Params) -> + gen_server:call(ggs_coordinator, {create_table, Params}). %% @doc This is the first function run by a newly created players. %% Generates a unique token that we use to identify the player. @@ -49,6 +50,12 @@ remove_player(_From, _Player) -> init([]) -> {ok, ok}. +handle_call({join_table, Table}, From, State) -> + {reply, {error, no_such_table}, State}; + +handle_call({create_table, {force, TID}}, From, State) -> + {reply, {ok, TID}, State}; + handle_call(_Message, _From, State) -> {noreply, State}. diff --git a/tests/ggs_coordinator_test.erl b/tests/ggs_coordinator_test.erl index 03b5389..ba05c95 100644 --- a/tests/ggs_coordinator_test.erl +++ b/tests/ggs_coordinator_test.erl @@ -14,3 +14,20 @@ stop_test() -> ggs_coordinator:stop("Terminate now"), % Send stop message timer:sleep(100), % Wait for cleaning.. ?assert((erlang:process_info(Coord) == undefined)). % Did it stop? + +join_bad_table_test() -> + {ok, _Coord} = ggs_coordinator:start_link(), + Response = ggs_coordinator:join_table("Nonexistant table"), + ggs_coordinator:stop(""), + timer:sleep(100), + ?assert(Response == {error, no_such_table}). + + +create_table_test() -> + {ok, _Coord} = ggs_coordinator:start_link(), + % Forcibly create a table. This functionality should be disabled + % in the production system, but is pretty nice for testing. + Response = ggs_coordinator:create_table({force, 1337}), + ggs_coordinator:stop(""), + timer:sleep(100), + ?assert(Response == {ok, 1337}). From 818205e19b505580ee66c2836e97617c12455f5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20P=C3=A5lsson?= Date: Thu, 17 Feb 2011 12:12:12 +0100 Subject: [PATCH 04/15] Now we store the tables when they are created --- src/ggs_coordinator.erl | 10 ++++++-- start_test | 2 +- tests/ggs_coordinator_test.erl | 47 ++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/ggs_coordinator.erl b/src/ggs_coordinator.erl index 2a5d509..c6e01d6 100644 --- a/src/ggs_coordinator.erl +++ b/src/ggs_coordinator.erl @@ -8,6 +8,11 @@ code_change/3]). -define(SERVER, ?MODULE). +-record(co_state, + {players = [], % List of all player processes + player_table_map = [], % Players <-> Table map + table_state_map = []}). % Table <-> Table state map + %% @doc This module act as "the man in the middle". %% Creates the starting connection between table and players. @@ -48,13 +53,14 @@ remove_player(_From, _Player) -> %% gen_server callbacks init([]) -> - {ok, ok}. + {ok, #co_state{}}. handle_call({join_table, Table}, From, State) -> {reply, {error, no_such_table}, State}; handle_call({create_table, {force, TID}}, From, State) -> - {reply, {ok, TID}, State}; + TIDs = State#co_state.player_table_map, + {reply, {ok, TID}, State#co_state{player_table_map = [TID | TIDs]}}; handle_call(_Message, _From, State) -> {noreply, State}. diff --git a/start_test b/start_test index 5920151..76050c1 100755 --- a/start_test +++ b/start_test @@ -1,3 +1,3 @@ #!/usr/bin/env bash -erl -boot start_sasl -pa ebin_test -pa erlang_js/ebin/ -pa erlv8/ebin -pa ebin -pa src -eval 'ggs_protocol_test:test_parse().' +erl -boot start_sasl -pa ebin_test -pa erlang_js/ebin/ -pa ebin -pa src -eval 'ggs_coordinator_test:test().' diff --git a/tests/ggs_coordinator_test.erl b/tests/ggs_coordinator_test.erl index ba05c95..ccc9256 100644 --- a/tests/ggs_coordinator_test.erl +++ b/tests/ggs_coordinator_test.erl @@ -1,33 +1,42 @@ -module(ggs_coordinator_test). -include_lib("eunit/include/eunit.hrl"). -start_link_test() -> - {ok, Coord} = ggs_coordinator:start_link(), % Start - PInfo = erlang:process_info(Coord), % Check process info - ggs_coordinator:stop(""), % Clean up - timer:sleep(100), % Wait for cleaning.. - ?assert((PInfo /= undefined)). % Did the server start? +coordinator_test_() -> + {foreach, + fun() -> + {ok, _Coord} = ggs_coordinator:start_link(), + timer:sleep(100) + end, + fun(_X) -> + ggs_coordinator:stop("End of test"), + timer:sleep(100) + end, + [ + fun test_start_link/0, + fun test_stop/0, + fun test_join_bad_table/0, + fun test_create_table/0 + ] + }. -stop_test() -> +test_start_link() -> + % Check process info + PInfo = whereis(ggs_coordinator), + ?assert((PInfo /= undefined)). % Did the server start? + +test_stop() -> ok = ggs_coordinator:stop(""), % Extra cleaning - {ok, Coord} = ggs_coordinator:start_link(), % Start server - ggs_coordinator:stop("Terminate now"), % Send stop message - timer:sleep(100), % Wait for cleaning.. - ?assert((erlang:process_info(Coord) == undefined)). % Did it stop? + timer:sleep(100), + % Did it stop? + ?assert((whereis(ggs_coordinator)) == undefined). -join_bad_table_test() -> - {ok, _Coord} = ggs_coordinator:start_link(), +test_join_bad_table() -> Response = ggs_coordinator:join_table("Nonexistant table"), - ggs_coordinator:stop(""), - timer:sleep(100), ?assert(Response == {error, no_such_table}). -create_table_test() -> - {ok, _Coord} = ggs_coordinator:start_link(), +test_create_table() -> % Forcibly create a table. This functionality should be disabled % in the production system, but is pretty nice for testing. Response = ggs_coordinator:create_table({force, 1337}), - ggs_coordinator:stop(""), - timer:sleep(100), ?assert(Response == {ok, 1337}). From 3f417692339b7d727b0ec37295bf10e489fc4f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20P=C3=A5lsson?= Date: Thu, 17 Feb 2011 12:57:41 +0100 Subject: [PATCH 05/15] Now we have join_table, create_table and join_lobby + test cases --- src/ggs_coordinator.erl | 30 +++++++++++++++++++++++------- src/helpers.erl | 4 ++++ tests/ggs_coordinator_test.erl | 15 +++++++++++++-- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/ggs_coordinator.erl b/src/ggs_coordinator.erl index c6e01d6..756bb2c 100644 --- a/src/ggs_coordinator.erl +++ b/src/ggs_coordinator.erl @@ -1,7 +1,8 @@ -module(ggs_coordinator). %% API Exports --export([start_link/0, stop/1, join_table/1, create_table/1]). +-export([start_link/0, stop/1, join_table/1, create_table/1, join_lobby/0, + respawn_player/2, respawn_table/1, remove_player/2]). %% gen_server callback exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, @@ -11,7 +12,8 @@ -record(co_state, {players = [], % List of all player processes player_table_map = [], % Players <-> Table map - table_state_map = []}). % Table <-> Table state map + table_state_map = [], + tables = []}). % Table <-> Table state map %% @doc This module act as "the man in the middle". %% Creates the starting connection between table and players. @@ -36,7 +38,7 @@ create_table(Params) -> %% @doc This is the first function run by a newly created players. %% Generates a unique token that we use to identify the player. join_lobby() -> - ggs_logger:not_implemented(). + gen_server:call(ggs_coordinator, join_lobby). %% @doc Act as a supervisor to player and respawns player when it gets bad data. respawn_player(_Player, _Socket) -> @@ -55,12 +57,26 @@ remove_player(_From, _Player) -> init([]) -> {ok, #co_state{}}. -handle_call({join_table, Table}, From, State) -> - {reply, {error, no_such_table}, State}; +handle_call(join_lobby, _From, State) -> + Token = helpers:get_new_token(), + {reply, {ok, Token}, State}; + +handle_call({join_table, Table}, _From, State) -> + Tables = State#co_state.tables, + case lists:keyfind(Table, 1, Tables) of + {Table} -> + {reply, {ok, Table}, State}; %% @TODO: Also add player to table + false -> + {reply, {error, no_such_table}, State} + end; handle_call({create_table, {force, TID}}, From, State) -> - TIDs = State#co_state.player_table_map, - {reply, {ok, TID}, State#co_state{player_table_map = [TID | TIDs]}}; + TIDMap = State#co_state.player_table_map, + Tables = State#co_state.tables, + {reply, {ok, TID}, State#co_state{ + player_table_map = [{From, TID} | TIDMap], + tables = [{TID} | TID] + }}; handle_call(_Message, _From, State) -> {noreply, State}. diff --git a/src/helpers.erl b/src/helpers.erl index 1bf7825..3a42fbf 100644 --- a/src/helpers.erl +++ b/src/helpers.erl @@ -1,4 +1,8 @@ -module(helpers). +-export([not_implemented/0, get_new_token/0]). not_implemented() -> exit("Not implemented"). + +get_new_token() -> + string:strip(os:cmd("uuidgen"), right, $\n ). diff --git a/tests/ggs_coordinator_test.erl b/tests/ggs_coordinator_test.erl index ccc9256..6ec41c6 100644 --- a/tests/ggs_coordinator_test.erl +++ b/tests/ggs_coordinator_test.erl @@ -15,7 +15,7 @@ coordinator_test_() -> fun test_start_link/0, fun test_stop/0, fun test_join_bad_table/0, - fun test_create_table/0 + fun test_join_lobby/0 ] }. @@ -34,9 +34,20 @@ test_join_bad_table() -> Response = ggs_coordinator:join_table("Nonexistant table"), ?assert(Response == {error, no_such_table}). +test_join_lobby() -> + {Response, _} = ggs_coordinator:join_lobby(), + ?assert(Response /= error). -test_create_table() -> +%% 'Manual' tests + +create_table_test() -> + {ok, _Coord} = ggs_coordinator:start_link(), + timer:sleep(100), % Forcibly create a table. This functionality should be disabled % in the production system, but is pretty nice for testing. Response = ggs_coordinator:create_table({force, 1337}), ?assert(Response == {ok, 1337}). + +join_good_table_test() -> + Response = ggs_coordinator:join_table(1337), + ?assert(Response == {ok, 1337}). From 041fee24419644398c9841ebd2b6450076053891 Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Thu, 17 Feb 2011 14:14:32 +0100 Subject: [PATCH 06/15] removed Token and Socket --- src/ggs_table.erl | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/ggs_table.erl b/src/ggs_table.erl index 1e4f323..3c0237d 100644 --- a/src/ggs_table.erl +++ b/src/ggs_table.erl @@ -1,4 +1,4 @@ -%% @doc This module represents a Player with a Socket and a Token +%% @doc This module represents a table with players -module(ggs_table). -behaviour(gen_server). @@ -7,10 +7,10 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). --record(state, { token, players, socket, game_vm } ). +-record(state, { players, game_vm } ). %% API --export([start_link/2, +-export([start_link/0, add_player/2, remove_player/2, stop/1, @@ -22,9 +22,9 @@ % API implementation % @doc returns a new table -start_link(Token, Socket) -> +start_link() -> GameVM = ggs_gamevm:start_link(), - {ok, Pid} = gen_server:start_link(?MODULE, [Token, Socket, GameVM], []), + {ok, Pid} = gen_server:start_link(?MODULE, [GameVM], []), Pid. %% @private @@ -50,11 +50,8 @@ notify(Table, Player, Message) -> %% ---------------------------------------------------------------------- %% @private -init([Token, Socket, GameVM]) -> - {ok, #state { token = Token, - socket = Socket, - game_vm = GameVM, - players = [] }}. +init([GameVM]) -> + {ok, #state { game_vm = GameVM, players = [] }}. %% @private handle_call({add_player, Player}, _From, #state { players = Players } = State) -> @@ -97,21 +94,20 @@ code_change(_OldVsn, State, _Extra) -> %% ---------------------------------------------------------------------- - % Tests start_link_test() -> - Table = start_link("123", none), + Table = start_link(), ?assertNot(Table =:= undefined). add_player_test() -> - Table = start_link("123", none), + Table = start_link(), Player = test_player, add_player(Table, Player), {ok, [Player]} = gen_server:call(Table, get_player_list). remove_player_test() -> - Table = start_link("123", none), + Table = start_link(), Player = test_player, Player2 = test_player2, add_player(Table, Player), @@ -124,12 +120,12 @@ remove_player_test() -> {ok, []} = gen_server:call(Table, get_player_list). stop_test() -> - Table = start_link("123", none), + Table = start_link(), ok = stop(Table). % @private notify_test() -> - Table = start_link("123", none), + Table = start_link(), Player = test_player, Message = {server, define, "function helloWorld(x) { }"}, ok = notify(Table, Player, Message). From 44d26278ccc34a0c9a2d2718c063bd496d43bee1 Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Thu, 17 Feb 2011 20:05:12 +0100 Subject: [PATCH 07/15] rewrite to gen_server and added tests --- src/ggs_gamevm.erl | 126 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 97 insertions(+), 29 deletions(-) diff --git a/src/ggs_gamevm.erl b/src/ggs_gamevm.erl index 1a8f547..15cbb64 100644 --- a/src/ggs_gamevm.erl +++ b/src/ggs_gamevm.erl @@ -1,24 +1,34 @@ --module(ggs_gamevm). --export([start_link/0, define/2, user_command/4]). %% @doc This module is responsible for running the game VM:s. You can issue %% commands to a vm using this module. +-module(ggs_gamevm). +-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, { port, table } ). + +%% API +-export([start_link/1, define/2, user_command/4, stop/1, call_js/2]). + +-include_lib("eunit/include/eunit.hrl"). + + +%% ---------------------------------------------------------------------- +% API implementation + %% @doc Create a new VM process. The process ID is returned and can be used %% with for example the define method of this module. -start_link() -> +start_link(Table) -> erlang_js:start(), %% @TODO: should only be done once - PortPid = spawn_link( fun() -> - process_flag(trap_exit, true), - {ok, Port} = js_driver:new(), - js:define(Port, <<"function userCommand(user, command, args){return 'Hello world';}">>), - loop(Port) - end ), - PortPid. + {ok, Pid} = gen_server:start_link(?MODULE, [Table], []), + Pid. %% @doc Define some new code on the specified VM, returns the atom ok. define(GameVM, SourceCode) -> - GameVM ! {define,SourceCode}, - ok. + gen_server:cast(GameVM, {define, SourceCode}). %% @doc Execute a user command on the specified VM. This function is %% asynchronous, and returns ok. @@ -28,23 +38,81 @@ define(GameVM, SourceCode) -> %% Command = a game command to run %% Args = arguments for the Command parameter user_command(GameVM, Player, Command, Args) -> - Ref = make_ref(), - GameVM ! {user_command, Player, Command, Args, self(), Ref}, + gen_server:cast(GameVM, {user_command, Player, Command, Args}). + +%% @private +% only for tests +call_js(GameVM, SourceCode) -> + gen_server:call(GameVM, {eval, SourceCode}). + +% @doc stops the gamevm process +stop(GameVM) -> + gen_server:cast(GameVM, stop). + + +%% ---------------------------------------------------------------------- + +%% @private +init([Table]) -> + process_flag(trap_exit, true), + {ok, Port} = js_driver:new(), + %% @TODO: add here default JS API instead + {ok, #state { port = Port, table = Table }}. + +%% private +% only needed for the tests +handle_call({eval, SourceCode}, _From, #state { port = Port } = State) -> + {ok, Ret} = js:eval(Port, list_to_binary(SourceCode)), + {reply, Ret, State}. + +%% @private +handle_cast({define, SourceCode}, #state { port = Port } = State) -> + ok = js:define(Port, list_to_binary(SourceCode)), + {noreply, State}; +handle_cast({user_command, Player, Command, Args}, #state { port = Port } = State) -> + Arguments = string:sub(string:join([Player, Command, Args], ","), "'", "\'"), + Js = list_to_binary(string:concat(string:concat("userCommand(", Arguments), ");")), + js_driver:define_js(Port, Js), + {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. -%% Helper functions +%% @private +code_change(_OldVsn, State, _Extra) -> + {ok, State}. -loop(Port) -> - receive - {define, SourceCode} -> - ok = js:define(Port, list_to_binary(SourceCode)), - loop(Port); - {user_command, User, Command, Args, From, Ref} -> - {ok, Ret} = js:call(Port, <<"userCommand">>, - [ list_to_binary(User), - list_to_binary(Command), - list_to_binary(Args) - ]), - From ! {Ref, Ret}, - loop(Port) - end. +%% ---------------------------------------------------------------------- +% Tests + +start_link_test() -> + erlang_js:start(), %% @TODO: should only be done once + GameVM = start_link(test_table), + ?assertNot(GameVM =:= undefined). + +define_test() -> + GameVM = start_link(test_table), + define(GameVM, "function hello(test) { return test; }"), + ?assertMatch(<<"jeena">>, gen_server:call(GameVM, {eval, "hello('jeena')"})). + +stop_test() -> + GameVM = start_link(test_table), + ok = stop(GameVM). + +user_command_test() -> + GameVM = start_link(test_table), + define(GameVM, "var t = '';\nfunction userCommand(user, command, args) { t = user + command + args; }\n"), + user_command(GameVM, "'jeena'", "'thecommand'", "'theargs'"), + ?assertMatch(<<"jeenathecommandtheargs">>, gen_server:call(GameVM, {eval, "t;"})). + From dd9b92bf43b7969d896209b2aad98371c9d31b33 Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Thu, 17 Feb 2011 20:14:45 +0100 Subject: [PATCH 08/15] fixed escaping problem --- src/ggs_gamevm.erl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ggs_gamevm.erl b/src/ggs_gamevm.erl index 15cbb64..6493c9f 100644 --- a/src/ggs_gamevm.erl +++ b/src/ggs_gamevm.erl @@ -70,7 +70,8 @@ handle_cast({define, SourceCode}, #state { port = Port } = State) -> ok = js:define(Port, list_to_binary(SourceCode)), {noreply, State}; handle_cast({user_command, Player, Command, Args}, #state { port = Port } = State) -> - Arguments = string:sub(string:join([Player, Command, Args], ","), "'", "\'"), + Arguments = string:concat("'", string:concat( + string:join([js_escape(Player), js_escape(Command), js_escape(Args)], "','"), "'")), Js = list_to_binary(string:concat(string:concat("userCommand(", Arguments), ");")), js_driver:define_js(Port, Js), {noreply, State}; @@ -93,6 +94,9 @@ terminate(_Reason, _State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. +js_escape(S) -> + lists:flatmap(fun($\') -> [$\\, $\']; (X) -> [X] end, S). + %% ---------------------------------------------------------------------- % Tests @@ -113,6 +117,6 @@ stop_test() -> user_command_test() -> GameVM = start_link(test_table), define(GameVM, "var t = '';\nfunction userCommand(user, command, args) { t = user + command + args; }\n"), - user_command(GameVM, "'jeena'", "'thecommand'", "'theargs'"), - ?assertMatch(<<"jeenathecommandtheargs">>, gen_server:call(GameVM, {eval, "t;"})). + user_command(GameVM, "'jeena", "thecommand", "theargs'"), + ?assertMatch(<<"'jeenathecommandtheargs'">>, gen_server:call(GameVM, {eval, "t;"})). From 883cf9e9d714a79645df9b67068e2b5ec13e56a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20P=C3=A5lsson?= Date: Thu, 17 Feb 2011 23:17:04 +0100 Subject: [PATCH 09/15] Now we have some myltiplayer action! --- src/ggs_coordinator.erl | 21 ++++---- src/ggs_gamevm_e.erl | 41 +++++++++++++++ src/ggs_player.erl | 40 ++++++++++---- src/ggs_table.erl | 112 +++++++++++++++++++++++++--------------- 4 files changed, 151 insertions(+), 63 deletions(-) create mode 100644 src/ggs_gamevm_e.erl diff --git a/src/ggs_coordinator.erl b/src/ggs_coordinator.erl index 756bb2c..733ff8d 100644 --- a/src/ggs_coordinator.erl +++ b/src/ggs_coordinator.erl @@ -61,21 +61,24 @@ handle_call(join_lobby, _From, State) -> Token = helpers:get_new_token(), {reply, {ok, Token}, State}; -handle_call({join_table, Table}, _From, State) -> +handle_call({join_table, Table}, From, State) -> + {FromPlayer, _Ref} = From, Tables = State#co_state.tables, case lists:keyfind(Table, 1, Tables) of - {Table} -> - {reply, {ok, Table}, State}; %% @TODO: Also add player to table + {TableID, TablePID} -> + ggs_table:add_player(TablePID, FromPlayer), + {reply, {ok, TablePID}, State}; false -> {reply, {error, no_such_table}, State} end; -handle_call({create_table, {force, TID}}, From, State) -> - TIDMap = State#co_state.player_table_map, - Tables = State#co_state.tables, - {reply, {ok, TID}, State#co_state{ - player_table_map = [{From, TID} | TIDMap], - tables = [{TID} | TID] +handle_call({create_table, {force, TableID}}, From, State) -> + TableIDMap = State#co_state.player_table_map, + Tables = State#co_state.tables, + NewTableProc = ggs_table:start_link(), + {reply, {ok, TableID}, State#co_state{ + player_table_map = [{From, TableID} | TableIDMap], + tables = [{TableID, NewTableProc} | Tables] }}; handle_call(_Message, _From, State) -> diff --git a/src/ggs_gamevm_e.erl b/src/ggs_gamevm_e.erl new file mode 100644 index 0000000..76b9350 --- /dev/null +++ b/src/ggs_gamevm_e.erl @@ -0,0 +1,41 @@ +-module(ggs_gamevm_e). +-export([start_link/1, define/2, user_command/4]). +%% @doc This module is responsible for running the game VM:s. You can issue +%% commands to a vm using this module. + +%% @doc Create a new VM process. The process ID is returned and can be used +%% with for example the define method of this module. +start_link(Table) -> + PortPid = spawn( fun() -> + loop(Table) + end ), + PortPid. + +%% @doc Define some new code on the specified VM, returns the atom ok. +define(GameVM, SourceCode) -> + GameVM ! {define,SourceCode}, + ok. + +%% @doc Execute a user command on the specified VM. This function is +%% asynchronous, and returns ok. +%% @spec user_command(GameVM, User, Command, Args) -> ok +%% GameVM = process IS of VM +%% Player = the player running the command +%% Command = a game command to run +%% Args = arguments for the Command parameter +user_command(GameVM, Player, Command, Args) -> + Ref = make_ref(), + GameVM ! {user_command, Player, Command, Args, self(), Ref}, + ok. + +%% Helper functions + +loop(Table) -> + receive + {define, SourceCode} -> + loop(Table); + {user_command, _User, Command, _Args, _From, _Ref} -> + io:format("GameVM received a message~n"), + ggs_table:notify_all_players(Table, Command), + loop(Table) + end. diff --git a/src/ggs_player.erl b/src/ggs_player.erl index 37c8496..af92ad9 100644 --- a/src/ggs_player.erl +++ b/src/ggs_player.erl @@ -1,5 +1,9 @@ -module(ggs_player). -export([start_link/1, notify/3, get_token/1, stop/2]). +-record(pl_state, + {token, % Player's token + socket, % Player's socket + table}). % Player's table %% @doc This module handles communication between a player and GGS. This module is %%responsible for: @@ -13,14 +17,28 @@ %% identifying the player. %% @spec start_link(Socket::socket()) -> {ok, Pid} | {error, Reason} start_link(Socket) -> - loop(Socket). + % The socket is in 'active' mode, and that means we are pushed any data + % that arrives on it, we do not need to recv() manually. Since the socket + % was opened in our parent process, we need to change the owner of it to + % us, otherwise these messages end up in our parent. + erlang:port_connect(Socket, self()), + {ok, Token} = ggs_coordinator:join_lobby(), + TableStatus = ggs_coordinator:join_table(1337), + case TableStatus of + {ok, Table} -> + loop(#pl_state{socket = Socket, token = Token, table = Table}); + {error, no_such_table} -> + ggs_coordinator:create_table({force, 1337}), + {ok, Table} = ggs_coordinator:join_table(1337), + loop(#pl_state{socket = Socket, token = Token, table = Table}) + end. %% @doc Handles incoming messages from the GGS and forwards them through the player %% socket to the player. %% @spec notify(Player::Pid(), From::Pid(), %% {Command::String(), Message::string()}) -> ok notify(Player, From, Message) -> - ggs_logger:not_implemented(). + Player ! {notify, From, Message}. %% @doc Get the player token uniquely representing the player. %% @spec get_token() -> string() @@ -36,13 +54,13 @@ stop(_Player,_Table) -> %% Internals -loop(Socket) -> - % The socket is in 'active' mode, and that means we are pushed any data - % that arrives on it, we do not need to recv() manually. Since the socket - % was opened in our parent process, we need to change the owner of it to - % us, otherwise these messages end up in our parent. - erlang:port_connect(Socket, self()), - receive {tcp, Socket, Data} -> % Just echo for now.. - gen_tcp:send(Socket,Data), - loop(Socket) +loop(#pl_state{token = Token, socket = Socket, table = Table} = State) -> + receive + {tcp, Socket, Data} -> % Just echo for now.. + io:format("Notifying table..~n"), + ggs_table:notify_game(Table, Token, Data), + loop(State); + {notify, From, Message} -> + gen_tcp:send(Socket, Message), + loop(State) end. diff --git a/src/ggs_table.erl b/src/ggs_table.erl index 1e4f323..53c27e9 100644 --- a/src/ggs_table.erl +++ b/src/ggs_table.erl @@ -5,12 +5,13 @@ %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). + terminate/2, code_change/3, notify_all_players/2, notify_game/3, + add_player/2]). -record(state, { token, players, socket, game_vm } ). %% API --export([start_link/2, +-export([start_link/0, add_player/2, remove_player/2, stop/1, @@ -22,9 +23,8 @@ % API implementation % @doc returns a new table -start_link(Token, Socket) -> - GameVM = ggs_gamevm:start_link(), - {ok, Pid} = gen_server:start_link(?MODULE, [Token, Socket, GameVM], []), +start_link() -> + {ok, Pid} = gen_server:start_link(?MODULE, [], []), Pid. %% @private @@ -47,22 +47,34 @@ stop(Table) -> notify(Table, Player, Message) -> gen_server:cast(Table, {notify, Player, Message}). +notify_all_players(Table, Message) -> + gen_server:cast(Table, {notify_all_players, Message}). + +notify_game(Table, From, Message) -> + io:format("Notify game called on"), + erlang:display(Table), + io:format("~n"), + gen_server:cast(Table, {notify_game, Message, From}). + %% ---------------------------------------------------------------------- %% @private -init([Token, Socket, GameVM]) -> - {ok, #state { token = Token, - socket = Socket, +init([]) -> + GameVM = ggs_gamevm_e:start_link(self()), + {ok, #state { game_vm = GameVM, players = [] }}. %% @private handle_call({add_player, Player}, _From, #state { players = Players } = State) -> {reply, ok, State#state { players = [Player | Players] }}; + handle_call({remove_player, Player}, _From, #state { players = Players } = State) -> {reply, ok, State#state { players = Players -- [Player] }}; + handle_call(get_player_list, _From, #state { players = Players } = State) -> {reply, {ok, Players}, State}; + handle_call(Msg, _From, State) -> error_logger:error_report([unknown_msg, Msg]), {reply, ok, State}. @@ -71,11 +83,25 @@ 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:user_command(GameVM, Player, Command, Args) + ggs_gamevm_e:user_command(GameVM, Player, Command, Args) end, {noreply, State}; + +handle_cast({notify_game, Message, From}, #state { game_vm = GameVM } = State) -> + io:format("notify_game message received~n"), + ggs_gamevm_e:user_command(GameVM, From, Message, ""), + {noreply, State}; + +handle_cast({notify_all_players, Message}, #state{players = Players} = State) -> + io:format("Notifying all players... ~p~n", [Players]), + lists:foreach(fun(P) -> + io:format("Notifying ~p~n", [P]), + ggs_player:notify(P, "Server", Message) + end, Players), + {noreply, State}; + handle_cast(stop, State) -> {stop, normal, State}; handle_cast(Msg, S) -> @@ -100,39 +126,39 @@ code_change(_OldVsn, State, _Extra) -> % Tests -start_link_test() -> - Table = start_link("123", none), - ?assertNot(Table =:= undefined). +%start_link_test() -> +% Table = start_link("123", none), +% ?assertNot(Table =:= undefined). +% +%add_player_test() -> +% Table = start_link("123", none), +% Player = test_player, +% add_player(Table, Player), +% {ok, [Player]} = gen_server:call(Table, get_player_list). -add_player_test() -> - Table = start_link("123", none), - Player = test_player, - add_player(Table, Player), - {ok, [Player]} = gen_server:call(Table, get_player_list). - -remove_player_test() -> - Table = start_link("123", none), - Player = test_player, - Player2 = test_player2, - add_player(Table, Player), - {ok, [Player]} = gen_server:call(Table, get_player_list), - add_player(Table, Player2), - {ok, [Player2, Player]} = gen_server:call(Table, get_player_list), - remove_player(Table, Player), - {ok, [Player2]} = gen_server:call(Table, get_player_list), - remove_player(Table, Player2), - {ok, []} = gen_server:call(Table, get_player_list). - -stop_test() -> - Table = start_link("123", none), - ok = stop(Table). - -% @private -notify_test() -> - Table = start_link("123", none), - Player = test_player, - Message = {server, define, "function helloWorld(x) { }"}, - ok = notify(Table, Player, Message). +%remove_player_test() -> +% Table = start_link("123", none), +% Player = test_player, +% Player2 = test_player2, +% add_player(Table, Player), +% {ok, [Player]} = gen_server:call(Table, get_player_list), +% add_player(Table, Player2), +% {ok, [Player2, Player]} = gen_server:call(Table, get_player_list), +% remove_player(Table, Player), +% {ok, [Player2]} = gen_server:call(Table, get_player_list), +% remove_player(Table, Player2), +% {ok, []} = gen_server:call(Table, get_player_list). +% +%stop_test() -> +% Table = start_link("123", none), +% ok = stop(Table). +% +%% @private +%notify_test() -> +% Table = start_link("123", none), +% Player = test_player, +% Message = {server, define, "function helloWorld(x) { }"}, +% ok = notify(Table, Player, Message). %Message2 = {game, "helloWorld", "test"}, %ok = notify(Table, Player, Message2). - \ No newline at end of file + From b3d8c5ba991192f1cd50fe57abb93466bc8d18bc Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Mon, 21 Feb 2011 15:43:39 +0100 Subject: [PATCH 10/15] added more test --- src/ggs_gamevm.erl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ggs_gamevm.erl b/src/ggs_gamevm.erl index 6493c9f..acfe2fb 100644 --- a/src/ggs_gamevm.erl +++ b/src/ggs_gamevm.erl @@ -120,3 +120,9 @@ user_command_test() -> user_command(GameVM, "'jeena", "thecommand", "theargs'"), ?assertMatch(<<"'jeenathecommandtheargs'">>, gen_server:call(GameVM, {eval, "t;"})). +user_command2_test() -> + GameVM = start_link(test_table), + define(GameVM, "var t = '';\nfunction userCommand(user, command, args) { t = callErlang('erlang time') + ''; }\n"), + user_command(GameVM, "jeena", "test", ""), + io:format("test ~p~n", [binary_to_list(gen_server:call(GameVM, {eval, "t;"}))]), + ?assertMatch(<<"rt">>, gen_server:call(GameVM, {eval, "t;"})). From 08e0be70e2c15446ebac33aba64d66b95093cfe2 Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Mon, 21 Feb 2011 20:54:43 +0100 Subject: [PATCH 11/15] fixed test with js callback --- erlang_js | 2 +- src/ggs_gamevm.erl | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/erlang_js b/erlang_js index 5350ed2..2f2785f 160000 --- a/erlang_js +++ b/erlang_js @@ -1 +1 @@ -Subproject commit 5350ed21606606dbee5ecb07e974f2abb9106270 +Subproject commit 2f2785fafb0da6db75810eb6fa97d09c58257588 diff --git a/src/ggs_gamevm.erl b/src/ggs_gamevm.erl index acfe2fb..294eb10 100644 --- a/src/ggs_gamevm.erl +++ b/src/ggs_gamevm.erl @@ -119,10 +119,15 @@ user_command_test() -> define(GameVM, "var t = '';\nfunction userCommand(user, command, args) { t = user + command + args; }\n"), user_command(GameVM, "'jeena", "thecommand", "theargs'"), ?assertMatch(<<"'jeenathecommandtheargs'">>, gen_server:call(GameVM, {eval, "t;"})). + +to_string({A, B, C}) -> + "{" ++ integer_to_list(A) ++ ", " ++ integer_to_list(B) ++ ", " ++ integer_to_list(C) ++ "}". user_command2_test() -> GameVM = start_link(test_table), define(GameVM, "var t = '';\nfunction userCommand(user, command, args) { t = callErlang('erlang time') + ''; }\n"), - user_command(GameVM, "jeena", "test", ""), - io:format("test ~p~n", [binary_to_list(gen_server:call(GameVM, {eval, "t;"}))]), - ?assertMatch(<<"rt">>, gen_server:call(GameVM, {eval, "t;"})). + user_command(GameVM, "", "", ""), + T = to_string(erlang:time()), + io:format("test ~p~n", [T]), + ?assertMatch(T, binary_to_list(gen_server:call(GameVM, {eval, "t;"}))). + From e03f3cf69d475b2aa90a133cdd39835dcc3c1781 Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Tue, 22 Feb 2011 00:15:21 +0100 Subject: [PATCH 12/15] better js_erlang_test --- src/ggs_gamevm.erl | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/ggs_gamevm.erl b/src/ggs_gamevm.erl index 294eb10..6dd19a7 100644 --- a/src/ggs_gamevm.erl +++ b/src/ggs_gamevm.erl @@ -120,14 +120,11 @@ user_command_test() -> user_command(GameVM, "'jeena", "thecommand", "theargs'"), ?assertMatch(<<"'jeenathecommandtheargs'">>, gen_server:call(GameVM, {eval, "t;"})). -to_string({A, B, C}) -> - "{" ++ integer_to_list(A) ++ ", " ++ integer_to_list(B) ++ ", " ++ integer_to_list(C) ++ "}". - -user_command2_test() -> +js_erlang_test() -> GameVM = start_link(test_table), define(GameVM, "var t = '';\nfunction userCommand(user, command, args) { t = callErlang('erlang time') + ''; }\n"), user_command(GameVM, "", "", ""), - T = to_string(erlang:time()), - io:format("test ~p~n", [T]), - ?assertMatch(T, binary_to_list(gen_server:call(GameVM, {eval, "t;"}))). + {A, B, C} = erlang:time(), + T = "{" ++ integer_to_list(A) ++ ", " ++ integer_to_list(B) ++ ", " ++ integer_to_list(C) ++ "}", + ?assertMatch(T, binary_to_list(gen_server:call(GameVM, {eval, "t;"}))). From 073c4d49b01b057094ce47e5b8ffaf4a12e9c923 Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Tue, 22 Feb 2011 00:35:54 +0100 Subject: [PATCH 13/15] merged rewrite and master --- .gitignore | 1 + mnesia/gamedb.erl | 50 ----------------------- src/.ggs_connection.erl.swp | Bin 12288 -> 0 bytes src/.ggs_server.erl.swo | Bin 12288 -> 0 bytes src/ggs_table.erl | 78 ------------------------------------ src/js_helper.erl | 8 ---- tests/ggs_table_test.erl | 44 ++++++++++++++++++++ 7 files changed, 45 insertions(+), 136 deletions(-) delete mode 100644 mnesia/gamedb.erl delete mode 100644 src/.ggs_connection.erl.swp delete mode 100644 src/.ggs_server.erl.swo delete mode 100644 src/js_helper.erl create mode 100644 tests/ggs_table_test.erl diff --git a/.gitignore b/.gitignore index d176978..f6b93e9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.dump *.beam Mnesia.* +*.swo diff --git a/mnesia/gamedb.erl b/mnesia/gamedb.erl deleted file mode 100644 index 751eb92..0000000 --- a/mnesia/gamedb.erl +++ /dev/null @@ -1,50 +0,0 @@ -%%%%---------------------------------------------------- -%%% @author Mattias Pettersson -%%% @copyright 2011 Mattias Pettersson -%%% @doc Database for runtime game variable storage. -%%% @end - - Test Mnesia --module(gamedb). --import(mnesia). --export([init/0,insert_player/1,example_player/0,read_player/1,test_player/0]). --include("gamedb.hrl"). - -%%----------------------------------------------------- -%% Creation -%%----------------------------------------------------- -init() -> - mnesia:create_table(player, [{attributes, record_info(fields, player)}]). - -%%----------------------------------------------------- -%% Test -%%----------------------------------------------------- -test_player() -> - insert_player(example_player()), - read_player(0001). - -example_player() -> - #player{id = 0001, - name = "Tux"}. - -%%----------------------------------------------------- -%% Insertions -%%----------------------------------------------------- -insert_player(Player) -> - Fun = fun() -> - mnesia:write(Player) - end, - mnesia:transaction(Fun). - - -%%----------------------------------------------------- -%% Querries -%%----------------------------------------------------- -read_player(Player_Key) -> - Fun = fun() -> - [P] = mnesia:read(player, Player_Key), - Name = P#player.name, - io:format("Player name: ~s~n",[Name]) - end, - mnesia:transaction(Fun). - diff --git a/src/.ggs_connection.erl.swp b/src/.ggs_connection.erl.swp deleted file mode 100644 index 0c009f8287377d2e3763a3fb7610231c3237d3fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2O>Z1E7{^^+M0qKoqMo?8TdkN?XJ3-EAceGwl!%h3+pLndm(^7W&e$W5 zH=){YkdU|{!I^9M0Eiwz;sQv$@CmqagL`?A;O}|aYywf~wg)QN%3m`c+m9drp2wC} z@pkLxTARMpSRg2`6LRL$wf0X-7s$022}!jSJV-*tG&jx1l^q@@QXbcO@O^*UU^7v2 zpjaG-V$kF&Vt8D+veitL-y955&zC}QUx!jO(0X9RzF7j6z#|igm=49FN1 zorLbcO2}R4b0~m(Xd7xnSD`;o5%LH0JMre&y z^<_eSfqsPUL0>^0^cM8jON4v_-GN5XD)c7wJoFs&EOa0D7QTi)hWbziItx9(`pg>d znswS@30MM_fF)oFSOWih0yHZFE521sA2M4uN3~j?rI2cs zUSH|Z6&6J)MQs)%b%ft6aU`VTNp#y_!hO$iBmXLIxzsbX$Mn(!1M_{JXy>Z=UUSI~ z6G6niQ1qpv!-Ta5CfkPGeY#$L=44BCi-HeSx3 zr`>COFEh~_kKfH)4CP{9s+eh~f^HN87EKbA{Y)i~N^ZoRwDjOQ7G4@JT+2OZ9P%LV zS6YNWf%Mk54E9MPZnC{qrddI+=F;l*jn$1qXhz6hv=^CM3>cRqkZZ;nT1^;k#d6J6 zN_}Z=$I`x%amGI7YL}}bUbsvPbBJ2ZqJy9nvG7@{oxI0U;6;>2CbC)Ezpc1*3u!R1 zh}90b#>L#BKzzOT;MJ7#Gp8St`28$_R64T_V#sAHDiSD>N+V7kJY0G>2VL4KlG_Y= zSQ#lkOgRez)c+ z8=X?jj*O5x|G;o^y2h_24#=rcH|M9Ssh+BuZEmXO1Z^%9&kH@AsiYpuU>I@7+}}3) zo@?_JF3xl^nQ?R(v*a&<^vhu7dx++>|;O?y@+$5Y|N|GrN0mvvzuVYG#`0>1wNM zU}2o~fQcOR;J={Zju(~aNfTmXVvHeC4|?;UCW?f_tKaJG`2{LumV+eK$%mfmu6p(A z`(C~74PDNz9zQ{!OHUIVdkNWgb@s%Su?yshR|q-9eaY1I+Z?a5K=Rx4QMWfEgPD02 zHY5)+d0t_eW5-IFP&k=dEwn-=PBW2a!n*@wx{FpoD{$uuv}85){2p>}dMc|19T?wF zAA5A=&d2MXS^=$qRzNGD70?Q31+)TM0jsbJEl&t$KgIFiH1lr&ncn##iOW<*E;{ighfD7PlPykPXePA!RzLSt&!7t!* z@FBPaHb5CX4JN_E;5WqJYw!V3@i-4w!9MWU{r6yUX_vJE|1$+>|2QIQVVbCRn>S3V znjJc$+W&F~A0}CWEkc%y{UHeSjyX;*YhnhOjEOjOiZLk zIWUeM$9H7Hw>?^I`HpnCAC7E|C>0~2OVXCClO_&6BeR^k?bn!Lo%AZJp>NXYrb(@Z z4Jqu&$bU7EH_}8!&Gj+Xu!_tMIeJ@B_kOpw&jky-vxyx{q6SB^S}JHNO}de^9S5Jk z8B6Lq6oelYk6Er?<%V>djJFV-1EKP@?S<%rp;2FDqN#N-WKt88IFWW zvx6b-g{K>0&kZH>lbyEKwvoc8nMtK+v5wj`uJ1}?O<7)#71_d8QFF%MK~e|%uxvYx zEpC>+#atAJ!=;7d>O#?^Dj+B?>SRQIZ^7+3)HAiy=fZ$FYP0mLV$Vf4Dm=Q5oaaGE zWu4LFbI+}nf}zzRCwi;vB?p$+`+e8eN#pG|LtT`%8WYB(TI88J6KqI^;hEzS5)JJP ziE@-lr_N$o{8qEf1m#tlY}=4F?FyrkLp3){WZRl*s7FHLq2o7$TZNOw z8fW>~8cVDr#Kxq)_{l4ix#!G>TdGsi+zQkJQXT6~PqSP)-?Zs?=qs z%G{3VS9SKdq8p-ON;%doJ}8 z5{{{vRV+xV% code_change(_OldVsn, State, _Extra) -> {ok, State}. -%% @TODO: Please put these tests in a separate file. We can't compile this file if -%% they contain errors from switching vms -%% ---------------------------------------------------------------------- -% Tests - -%<<<<<<< HEAD -%start_link_test() -> -% Table = start_link(), -% ?assertNot(Table =:= undefined). - -%add_player_test() -> -% Table = start_link(), -% Player = test_player, -% add_player(Table, Player), -% {ok, [Player]} = gen_server:call(Table, get_player_list). - -%remove_player_test() -> -% Table = start_link(), -% Player = test_player, -% Player2 = test_player2, -% add_player(Table, Player), -% {ok, [Player]} = gen_server:call(Table, get_player_list), -% add_player(Table, Player2), -% {ok, [Player2, Player]} = gen_server:call(Table, get_player_list), -% remove_player(Table, Player), -% {ok, [Player2]} = gen_server:call(Table, get_player_list), -% remove_player(Table, Player2), -% {ok, []} = gen_server:call(Table, get_player_list). -% -%stop_test() -> -% Table = start_link(), -% ok = stop(Table). - -% @private -%notify_test() -> -% Table = start_link(), -% Player = test_player, -% Message = {server, define, "function helloWorld(x) { }"}, -% ok = notify(Table, Player, Message). -%======= -%%start_link_test() -> -% Table = start_link("123", none), -% ?assertNot(Table =:= undefined). -% -%add_player_test() -> -% Table = start_link("123", none), -% Player = test_player, -% add_player(Table, Player), -% {ok, [Player]} = gen_server:call(Table, get_player_list). - -%remove_player_test() -> -% Table = start_link("123", none), -% Player = test_player, -% Player2 = test_player2, -% add_player(Table, Player), -% {ok, [Player]} = gen_server:call(Table, get_player_list), -% add_player(Table, Player2), -% {ok, [Player2, Player]} = gen_server:call(Table, get_player_list), -% remove_player(Table, Player), -% {ok, [Player2]} = gen_server:call(Table, get_player_list), -% remove_player(Table, Player2), -% {ok, []} = gen_server:call(Table, get_player_list). -% -%stop_test() -> -% Table = start_link("123", none), -% ok = stop(Table). -% -%% @private -%notify_test() -> -% Table = start_link("123", none), -% Player = test_player, -% Message = {server, define, "function helloWorld(x) { }"}, -% ok = notify(Table, Player, Message). -%>>>>>>> jonte_rewrite - %Message2 = {game, "helloWorld", "test"}, - %ok = notify(Table, Player, Message2). - diff --git a/src/js_helper.erl b/src/js_helper.erl deleted file mode 100644 index efb38f4..0000000 --- a/src/js_helper.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(js_helper). --export([test/0, echo/1]). - -test() -> - {ok, test}. - -echo(String) -> - {ok, String}. \ No newline at end of file diff --git a/tests/ggs_table_test.erl b/tests/ggs_table_test.erl new file mode 100644 index 0000000..5757456 --- /dev/null +++ b/tests/ggs_table_test.erl @@ -0,0 +1,44 @@ +-include_lib("eunit/include/eunit.hrl"). +-import(ggs_table). + + +% @private +start_link_test() -> + Table = start_link(), + ?assertNot(Table =:= undefined). + +% @private +add_player_test() -> + Table = start_link(), + Player = test_player, + add_player(Table, Player), + {ok, [Player]} = gen_server:call(Table, get_player_list). + +% @private +remove_player_test() -> + Table = start_link(), + Player = test_player, + Player2 = test_player2, + add_player(Table, Player), + {ok, [Player]} = gen_server:call(Table, get_player_list), + add_player(Table, Player2), + {ok, [Player2, Player]} = gen_server:call(Table, get_player_list), + remove_player(Table, Player), + {ok, [Player2]} = gen_server:call(Table, get_player_list), + remove_player(Table, Player2), + {ok, []} = gen_server:call(Table, get_player_list). + +% @private +stop_test() -> + Table = start_link(), + ok = stop(Table). + +% @private +notify_test() -> + Table = start_link(), + Player = test_player, + Message = {server, define, "function helloWorld(x) { }"}, + ok = notify(Table, Player, Message). + Message2 = {game, "helloWorld", "test"}, + ok = notify(Table, Player, Message2). + From eb3925bebdd99f6eee8402688ea7dbceed2e9549 Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Tue, 22 Feb 2011 00:39:15 +0100 Subject: [PATCH 14/15] fixed issues with tests --- tests/ggs_player_test.erl | 1 + tests/ggs_table_test.erl | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/ggs_player_test.erl b/tests/ggs_player_test.erl index be38135..66900d6 100644 --- a/tests/ggs_player_test.erl +++ b/tests/ggs_player_test.erl @@ -1,3 +1,4 @@ +-module(ggs_player_test). -include_lib("eunit/include/eunit.hrl"). -import(ggs_player). diff --git a/tests/ggs_table_test.erl b/tests/ggs_table_test.erl index 5757456..7a270ed 100644 --- a/tests/ggs_table_test.erl +++ b/tests/ggs_table_test.erl @@ -1,3 +1,4 @@ +-module(ggs_table_test). -include_lib("eunit/include/eunit.hrl"). -import(ggs_table). From e4753b2c074c01ac2f08e981cbbed88c5e0e64dc Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Tue, 22 Feb 2011 00:49:43 +0100 Subject: [PATCH 15/15] minor changes --- erlang_js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erlang_js b/erlang_js index 2f2785f..709b568 160000 --- a/erlang_js +++ b/erlang_js @@ -1 +1 @@ -Subproject commit 2f2785fafb0da6db75810eb6fa97d09c58257588 +Subproject commit 709b568efbc99c954507d1593bc5633f900bc5dc