From df197dab408e09910a6cb2aa09fe92990c7d6d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20P=C3=A5lsson?= Date: Mon, 14 Feb 2011 17:45:56 +0100 Subject: [PATCH 1/3] Switched over to new protocol module --- src/ggs_protocol.erl | 16 +++++++++++++--- src/ggs_server.erl | 40 ++++++++++++++++------------------------ 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/ggs_protocol.erl b/src/ggs_protocol.erl index 46c1ba1..35da585 100644 --- a/src/ggs_protocol.erl +++ b/src/ggs_protocol.erl @@ -1,10 +1,20 @@ -module(ggs_protocol). --export([parse/1]). +-export([parse/1, getToken/1]). +%% API Functions parse(Data) -> Parsed = do_parse(Data, []), prettify(Parsed). +getToken(Parsed) -> + case lists:keyfind(token, 1, Parsed) of + {_, Value} -> + Value; + false -> + false + end. + +%% Internal helpers do_parse(Data, ParsedMessage) -> NewLinePos = string:chr(Data, $\n), Line = string:substr(Data, 1, NewLinePos-1), @@ -15,7 +25,8 @@ do_parse(Data, ParsedMessage) -> {separator, data_next} -> {_, Value} = lists:keyfind(content_len, 1, ParsedMessage), {ContentLength, []} = string:to_integer(Value), - {ParsedMessage, handle_data(string:substr(Data, NewLinePos+1), ContentLength)} + {data, ArgumentData} = handle_data(string:substr(Data, NewLinePos+1), ContentLength), + {ParsedMessage, ArgumentData} end. handle([[]]) -> @@ -33,7 +44,6 @@ handle_data(Data, Length) -> {data, string:substr(Data,1,Length)}. -%% Helpers prettify({Args, Data}) -> case lists:keyfind(srv_cmd, 1, Args) of {_, Value} -> diff --git a/src/ggs_server.erl b/src/ggs_server.erl index 4a116fa..f8eae1e 100644 --- a/src/ggs_server.erl +++ b/src/ggs_server.erl @@ -1,10 +1,3 @@ -%%%---------------------------------------------------- -%%% @author Jonatan Pålsson -%%% @copyright 2010 Jonatan Pålsson -%%% @doc RPC over TCP server -%%% @end -%%%---------------------------------------------------- - -module(ggs_server). -behaviour(gen_server). @@ -95,37 +88,36 @@ handle_cast(stop, State) -> {stop, normal, State}; % Handle javascript defines -handle_cast({srv_cmd, "define", Args, Data}, State) -> - %JSVM = getJSVM(Token, State), - %js_runner:define(JSVM, Payload), +handle_cast({srv_cmd, "define", Headers, Data}, State) -> + Token = ggs_protocol:getToken(Headers), + JSVM = getJSVM(Token, State), + js_runner:define(JSVM, Data), send(State#state.lsock, "Token", "Okay, defined that for you!"), {noreply, State}; % Handle javascript calls -handle_cast({srv_cmd, "call", Args, Data}, State) -> - %io:format("Got call request: ~p~n", [Payload]), - %JSVM = getJSVM(Token, State), - %erlang:display(erlang:port_info(JSVM)), - %{ok, Ret} = js_runner:call(JSVM, Payload, []),%Payload, []), - %send(State#state.lsock, Token, "JS says:", binary_to_list(Ret)), +handle_cast({srv_cmd, "call", Headers, Data}, State) -> + Token = ggs_protocol:getToken(Headers), + io:format("Got call request: ~p~n", [Data]), + JSVM = getJSVM(Token, State), + erlang:display(erlang:port_info(JSVM)), + {ok, Ret} = js_runner:call(JSVM, Data, []),%Payload, []), + send(State#state.lsock, Token, "JS says:", binary_to_list(Ret)), {noreply, State}; % Set the new state to the reference generated, and JSVM associated handle_cast({srv_cmd, "hello", Headers, Data}, State) -> - %JSVM = js_runner:boot(), + JSVM = js_runner:boot(), Client = getRef(), send(State#state.lsock, Client, "This is your refID"), - %OldMap = State#state.client_vm_map, - %NewState = State#state{client_vm_map = OldMap ++ [{Client, JSVM}]}, - %gen_server:cast(ggs_backup, {set_backup, NewState}), - {noreply, State}. %NewState + OldMap = State#state.client_vm_map, + NewState = State#state{client_vm_map = OldMap ++ [{Client, JSVM}]}, + gen_server:cast(ggs_backup, {set_backup, NewState}), + {noreply, NewState}. %%----------------------------------------------------- %% Helpers %%----------------------------------------------------- getRef() -> - %{A1,A2,A3} = now(), - %#random:seed(A1, A2, A3), - %random:uniform(1000). string:strip(os:cmd("uuidgen"), right, $\n ). getJSVM(RefID, State) -> From bf98e1fee2c9338466ea58b2d08c9a277cf370ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20P=C3=A5lsson?= Date: Mon, 14 Feb 2011 19:32:46 +0100 Subject: [PATCH 2/3] Fixed ggs_vm_runner --- src/ggs_server.erl | 4 ++-- src/ggs_vm_runner.erl | 40 ++++++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/ggs_server.erl b/src/ggs_server.erl index 34d297f..c695fd6 100644 --- a/src/ggs_server.erl +++ b/src/ggs_server.erl @@ -104,8 +104,8 @@ handle_cast({define, Token, SourceCode}, State) -> % Handle javascript calls handle_cast({call, Token, Command}, State) -> GameVM = getJSVM(Token, State), - ggs_vm_runner:user_command(GameVM, "User", Command, []), - %send(State#state.lsock, Token, "JS says:", binary_to_list(Ret)), Unessecary + Ret = ggs_vm_runner:user_command(GameVM, "User", Command, []), + send(State#state.lsock, Token, "JS says:", binary_to_list(Ret)), {noreply, State}; % Set the new state to the reference generated, and JSVM associated diff --git a/src/ggs_vm_runner.erl b/src/ggs_vm_runner.erl index cf633f0..6c66378 100644 --- a/src/ggs_vm_runner.erl +++ b/src/ggs_vm_runner.erl @@ -4,25 +4,41 @@ %Mattias start_link() -> erlang_js:start(), - {ok, Port} = js_driver:new(), - js:define(Port, <<"function userCommand(user, command, args){}">>), - PortPid = spawn_link(fun() -> loop(Port) end ), + 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. loop(Port) -> -receive - {define, SourceCode} -> - ok = js:define(Port, list_to_binary(SourceCode)), - loop(Port); - {user_command, User, Command, Args} -> - {ok, Ret} = js:call(Port, <<"userCommand">>, list_to_binary([User,Command,Args])), - loop(Port) -end. + io:format("I am PID"), + erlang:display(self()), + 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. define(GameVM, SourceCode) -> GameVM ! {define,SourceCode}. user_command(GameVM, User, Command, Args) -> - GameVM ! {user_command, User, Command, Args}. + Ref = make_ref(), + GameVM ! {user_command, User, Command, Args, self(), Ref}, + receive + {Ref, RetVal} -> + RetVal; + Other -> Other + end. From 66aa7f4bf123e6157a0c6fa8679dde63ce397542 Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Tue, 15 Feb 2011 07:57:44 +0100 Subject: [PATCH 3/3] some more interface compatibility --- src/ggs_server.erl | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/ggs_server.erl b/src/ggs_server.erl index ab9b8f8..833feac 100644 --- a/src/ggs_server.erl +++ b/src/ggs_server.erl @@ -105,26 +105,33 @@ handle_cast({srv_cmd, "call", Headers, Data}, State) -> {noreply, State}; % Set the new state to the reference generated, and JSVM associated +%handle_cast({server, hello, Headers}, State) -> handle_cast({srv_cmd, "hello", Headers, Data}, State) -> - GameVM = ggs_vm_runner:start_link(), - Client = getRef(), - send(State#state.lsock, Client, "This is your refID"), + GameToken = case proplist:get_value(game_token, Headers) of -> + undefined -> getNewToken(); + GT -> GT; + end, + ClientToken = getNewToken(), OldMap = State#state.client_vm_map, - NewState = State#state{client_vm_map = OldMap ++ [{Client, GameVM}]}, + NewState = State#state{client_vm_map = OldMap ++ [{ClientToken, GameVM, GameToken}]}, gen_server:cast(ggs_backup, {set_backup, NewState}), {noreply, NewState}. + %%----------------------------------------------------- %% Helpers %%----------------------------------------------------- -getRef() -> +getNewToken() -> string:strip(os:cmd("uuidgen"), right, $\n ). -getJSVM(RefID, State) -> +getJSVM(ClientToken, State) -> VMs = State#state.client_vm_map, - erlang:display(RefID), - erlang:display(VMs), - {value, {_,VM}} = lists:keysearch(RefID, 1, VMs), + {value, {_,VM}} = lists:keysearch(ClientToken, 1, VMs), + VM. + +getGameVMByGameToken(GameToken, State) -> + VMs = State#state.client_vm_map, + {value, {_,VM}} = lists:keysearch(GameToken, 3, VMs), VM. send(Socket, RefID, String) ->