Browse Source

new N2O/BERT protocol

Maxim Sokhatsky 11 years ago
parent
commit
05102a281c
2 changed files with 74 additions and 119 deletions
  1. 7 7
      apps/face/src/index.erl
  2. 67 112
      apps/face/src/n2o_game.erl

+ 7 - 7
apps/face/src/index.erl

@@ -65,8 +65,8 @@ body() ->
 event(terminate) -> wf:info("terminate");
 event(init) ->
     {ok,GamePid} = game_session:start_link(self()),
-    event(attach),
-    event(join),
+%    event(attach),
+%    event(join),
     wf:info("INIT ~p",[GamePid]),
     put(game_session, GamePid);
 
@@ -77,7 +77,7 @@ event(take)   -> wf:wire(take("1000001", wf:q(ddtake)));
 
 event(discard) -> 
     TilesList = get(game_okey_tiles),
-    wf:info("dd ~p", [wf:q(dddiscard)]),
+%    wf:info("dd ~p", [wf:q(dddiscard)]),
     {_, {C, V}} = lists:keyfind(erlang:list_to_binary(wf:q(dddiscard)), 1, TilesList),
     wf:wire(discard("1000001", erlang:integer_to_list(C), erlang:integer_to_list(V)));
 
@@ -94,7 +94,7 @@ event({server, {game_event, _, okey_tile_discarded, Args}}) ->
     if
        Im == Player ->
             {_, {_, C, V}} = lists:keyfind(tile, 1, Args),
-            wf:info("c ~p v ~p", [C, V]),
+%            wf:info("c ~p v ~p", [C, V]),
             TilesListOld = get(game_okey_tiles),
             TilesList = lists:keydelete({C, V}, 2, TilesListOld),
             put(game_okey_tiles, TilesList),
@@ -127,7 +127,7 @@ event({server,{game_event, Game, okey_turn_timeout, Args}}) ->
 event({server, {game_event, _, okey_game_info, Args}}) ->
     wf:info("okay_game_info ~p", [Args]),
     {_, PlayersInfo} = lists:keyfind(players, 1, Args),
-    wf:info("pi ~p", [PlayersInfo]),
+%    wf:info("pi ~p", [PlayersInfo]),
     Players = 
         lists:zipwith(
           fun(ListId, {PlayerId, PlayerLabel}) ->
@@ -137,10 +137,10 @@ event({server, {game_event, _, okey_game_info, Args}}) ->
           lists:map(
             fun
                 (#'PlayerInfo'{id = Id, robot = true} = P) ->
-                    wf:info("pp ~p", [P]),
+%                    wf:info("pp ~p", [P]),
                     {Id, <<Id/binary, <<" R ">>/binary>>};
                 (#'PlayerInfo'{id = Id, robot = false} = P) ->
-                    wf:info("pr ~p", [P]),
+%                    wf:info("pr ~p", [P]),
                     put(okey_im, Id),
                     {Id, <<Id/binary, <<" M ">>/binary>>}
             end,

+ 67 - 112
apps/face/src/n2o_game.erl

@@ -5,13 +5,12 @@
 -include("../../server/include/game_okey.hrl").
 -include("../../server/include/game_tavla.hrl").
 
-
 -export([init/4]).
 -export([stream/3]).
 -export([info/3]).
 -export([terminate/2]).
 
--define(PERIOD, 1000).
+% process spawn
 
 init(_Transport, Req, _Opts, _Active) ->
     put(actions,[]),
@@ -24,132 +23,88 @@ init(_Transport, Req, _Opts, _Active) ->
     Req1 = wf:header(<<"Access-Control-Allow-Origin">>, <<"*">>, NewCtx#context.req),
     {ok, Req1, NewCtx}.
 
-html_events(Pro, State) ->
-    Pickled = proplists:get_value(pickle,Pro),
-    Linked = proplists:get_value(linked,Pro),
-    Depickled = wf:depickle(Pickled),
-    wf:info("Depickled: ~p",[Depickled]),
-    case Depickled of
-        #ev{module=Module,name=Function,payload=Parameter,trigger=Trigger} ->
-            case Function of 
-                control_event   -> lists:map(fun({K,V})-> put(K,V) end,Linked),
-                                   Module:Function(Trigger, Parameter);
-                api_event       -> Module:Function(Parameter,Linked,State);
-                event           -> lists:map(fun({K,V})-> put(K,V) end,Linked),
-                                   Module:Function(Parameter);
-                UserCustomEvent -> Module:Function(Parameter,Trigger,State) end;
-        _Ev -> wf:error("N2O allows only #ev{} events") end,
-    Actions = get(actions),
-    wf_context:clear_actions(),
-    Render = wf:render(Actions),
-    GenActions = get(actions),
-    RenderGenActions = wf:render(GenActions),
-    wf_context:clear_actions(),
-    JS = iolist_to_binary([Render,RenderGenActions]),
-    wf:info("JS: ~p",[JS]),
-    wf:json([{eval,JS}]).
-
-stream(<<"ping">>, Req, State) ->
-    {reply, <<"pong">>, Req, State};
-stream({text,Data}, Req, State) ->
-%    wf:info("Text: ~p",[Data]),
-    info(Data,Req,State);
-stream({binary,Info}, Req, State) ->
-    Pro = binary_to_term(Info,[safe]),
-    wf:info("Binary: ~p",[Pro]),
-    case Pro of
-        {client,M} -> info({client,M},Req,State);
-        _ -> {reply,html_events(Pro,State),Req,State} end;
-
-stream(<<"N2O",Rest/binary>> = Data, Req, State) ->
-    info(Data,Req,State);
-
-stream(Data, Req, State) ->
-    wf:info("Binary: ~p",[Data]),
-    info(binary_to_term(Data),Req,State).
-
-render_actions(InitActions) ->
-    RenderInit = wf:render(InitActions),
-    InitGenActions = get(actions),
-    RenderInitGenActions = wf:render(InitGenActions),
-    wf_context:clear_actions(),
-    [RenderInit,RenderInitGenActions].
+% websocket handler
+
+stream(<<"ping">>, Req, State) -> info(<<"PING">>, Req, State);
+stream(<<"N2O",Rest/binary>> = Data, Req, State) -> info(Data,Req,State);
+stream({text,Data}, Req, State) -> info(Data,Req,State);
+stream({binary,Info}, Req, State) -> info(binary_to_term(Info,[safe]),Req,State);
+stream(Data, Req, State) when is_binary(Data) -> info(binary_to_term(Data,[safe]),Req,State);
+stream(Data, Req, State) -> info(Data,Req,State).
+
+% WebSocketPid ! Message
 
 info({client,Message}, Req, State) ->
+    wf:info("Client Message: ~p",[Message]),
     GamePid = get(game_session),
-    wf:info("GameSessionPid: ~p",[GamePid]),
     game_session:process_request(GamePid, Message), 
     Module = State#context.module,
     try Module:event({client,Message}) catch E:R -> wf:info("Catch: ~p:~p", [E,R]) end,
-    Actions = get(actions),
-    wf_context:clear_actions(),
-    Render = wf:render(Actions),
-    GenActions = get(actions),
-    RenderGenActions = wf:render(GenActions),
-    wf_context:clear_actions(),
-    {reply,wf:json([{eval,iolist_to_binary([Render,RenderGenActions])},
+    {reply,wf:json([{eval,iolist_to_binary(render_actions(get(actions)))},
                     {data,binary_to_list(term_to_binary(Message))}]),Req,State};
 
 info({send_message,Message}, Req, State) ->
+    wf:info("Server Message: ~p",[Message]),
     Module = State#context.module,
     try Module:event({server,Message}) catch E:R -> wf:info("Catch: ~p:~p", [E,R]) end,
-    Actions = get(actions),
-    wf_context:clear_actions(),
-    Render = wf:render(Actions),
-    GenActions = get(actions),
-    RenderGenActions = wf:render(GenActions),
-    wf_context:clear_actions(),
-    {reply,wf:json([{eval,iolist_to_binary([Render,RenderGenActions])},
+    {reply,wf:json([{eval,iolist_to_binary(render_actions(get(actions)))},
                     {data,binary_to_list(term_to_binary(Message))}]),Req,State};
 
+info({wf_event,_,_,_}=Event, Req, State) ->
+    wf:info("N2O Message: ~p",[Event]),
+    {reply,html_events(Event,State),Req,State};
+
+info({flush,Actions}, Req, State) ->
+    wf:info("Flush Message: ~p",[Actions]),
+    wf:render(Actions),
+    {reply, wf:json([{eval,iolist_to_binary(render_actions(get(actions)))}]), Req, State};
+
+info(<<"PING">> = Ping, Req, State) ->
+%    wf:info("Ping Message: ~p",[Ping]),
+    {reply,<<>>,Req,State};
+
+info(<<"N2O,",Rest/binary>> = InitMarker, Req, State) ->
+    wf:info("N2O INIT: ~p",[InitMarker]),
+    Module = State#context.module,
+%    InitActions = get(actions),
+    Elements = try Module:main() catch X:Y -> wf:error_page(X,Y) end,
+    wf_core:render(Elements),
+    try Module:event(init) catch C:E -> wf:error_page(C,E) end,
+    {reply, wf:json([{eval,iolist_to_binary(render_actions(get(actions)))}]), Req, State};
+
+info(Unknown, Req, State) ->
+    wf:info("Unknown Message: ~p",[Unknown]),
+    Module = State#context.module,
+    try Module:event(Unknown) catch C:E -> wf:error_page(C,E) end,
+    {reply, wf:json([{eval,iolist_to_binary(render_actions(get(actions)))}]), Req, State}.
+
+% double render: actions could generate actions
 
-info(Pro, Req, State) when is_list(Pro) ->
-    {reply,html_events(Pro,State),Req,State};
-
-info(Pro, Req, State) ->
-    Render = 
-        case Pro of
-            {flush,Actions} ->
-                                                % wf:info("Comet Actions: ~p",[Actions]),
-                wf:render(Actions);
-            <<"N2O,",Rest/binary>> ->
-                Module = State#context.module, Module:event(init),
-                InitActions = get(actions),
-                wf_context:clear_actions(),
-                Pid = wf:depickle(Rest),
-                                                %wf:info("Transition Pid: ~p",[Pid]),
-                case Pid of
-                    undefined -> 
-                                                %wf:info("Path: ~p",[wf:path(Req)]),
-                                                %wf:info("Module: ~p",[Module]),
-                        Elements = try Module:main() catch C:E -> wf:error_page(C,E) end,
-                        wf_core:render(Elements),
-                        render_actions(InitActions);
-
-                    Transition ->
-                        X = Pid ! {'N2O',self()},
-                        R = receive Actions -> [ render_actions(InitActions) | wf:render(Actions) ]
-                            after 100 ->
-                                    QS = element(14, Req),
-                                    wf:redirect(case QS of <<>> -> ""; _ -> "" ++ "?" ++ wf:to_list(QS) end),
-                                    []
-                            end,
-                        R
-                end;
-            <<"PING">> -> [];
-            Unknown ->
-%                wf:info("Unknown WS Info Message ~p", [Unknown]),
-                M = State#context.module,
-                catch M:event(Unknown),
-                Actions = get(actions),
-                wf_context:clear_actions(),
-                wf:render(Actions) end,
-    GenActions = get(actions),
+render_actions(Actions) ->
     wf_context:clear_actions(),
-    RenderGenActions = wf:render(GenActions),
+    First  = wf:render(Actions),
+    Second = wf:render(get(actions)),
     wf_context:clear_actions(),
-    JS = iolist_to_binary([Render,RenderGenActions]),
-    {reply, wf:json([{eval,JS}]), Req, State}.
+    [First,Second].
+
+% N2O events
+
+html_events({wf_event,Source,Pickled,Linked}, State) ->
+    Ev = wf:depickle(Pickled),
+    wf:info("Depickled: ~p",[Ev]),
+    case Ev of
+        #ev{} -> render_ev(Ev,Source,Linked,State);
+        CustomEnvelop -> wf:error("Only #ev{} events for now: ~p",[CustomEnvelop]) end,
+    wf:json([{eval,iolist_to_binary(render_actions(get(actions)))}]).
+
+render_ev(#ev{module=M,name=F,payload=P,trigger=T},Source,Linked,State) ->
+    case F of 
+        control_event -> lists:map(fun({K,V})-> put(K,V) end,Linked), M:F(T,P);
+        api_event -> M:F(P,Linked,State);
+        event -> lists:map(fun({K,V})-> put(K,V) end,Linked), M:F(P);
+        UserCustomEvent -> M:F(P,T,State) end.
+
+% process down
 
 terminate(_Req, _State=#context{module=Module}) ->
     Res = ets:update_counter(globals,onlineusers,{2,-1}),