123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- -module(n2o_nitrogen).
- -author('Maxim Sokhatsky').
- -include_lib("n2o/include/wf.hrl").
- -compile([export_all, nowarn_export_all]).
- % Nitrogen pickle handler
- info({init,Rest},Req,State) ->
- Module = State#cx.module,
- InitActionsReply = case Rest of
- <<>> -> try Elements = Module:main(),
- wf_render:render(Elements),
- {ok,[]}
- catch X:Y -> Stack = wf:stack(X,Y),
- wf:error(?MODULE,"Event Main: ~p:~p~n~p", Stack),
- {error,Stack} end;
- Binary -> Pid = wf:depickle(Binary),
- Pid ! {'N2O',self()},
- {ok,receive_actions(Req)} end,
- case InitActionsReply of
- {ok,InitActions} -> UserCx = try Module:event(init),
- case wf:config(n2o,auto_session) of
- disabled -> skip;
- _ -> n2o_session:ensure_sid([],?CTX,[]) end
- catch C:E -> Error = wf:stack(C,E),
- wf:error(?MODULE,"Event Init: ~p:~p~n~p",Error),
- {stack,Error} end,
- Actions = render_actions(wf:actions()),
- {reply,wf:format({io,iolist_to_binary([InitActions,Actions]),<<>>}),
- Req,wf:context(State,?MODULE,{init,UserCx})};
- {error,E} -> {reply,wf:format({io,<<>>,E}), Req, wf:context(State,?MODULE,{error,E})} end;
- info({pickle,_,_,_}=Event, Req, State) ->
- wf:actions([]),
- Result = try html_events(Event,State)
- catch E:R -> Stack = wf:stack(E,R),
- wf:error(?MODULE,"Catch: ~p:~p~n~p", Stack),
- {io,render_actions(wf:actions()),Stack} end,
- {reply,wf:format(Result),Req,wf:context(State,?MODULE,{pickle,Result})};
- info({flush,Actions}, Req, State) ->
- wf:actions([]),
- Render = iolist_to_binary(render_actions(Actions)),
- wf:info(?MODULE,"Flush Message: ~tp",[Render]),
- {reply,wf:format({io,Render,<<>>}),Req, State};
- info({direct,Message}, Req, State) ->
- wf:actions([]),
- Module = State#cx.module,
- Result = try Res = Module:event(Message), {direct,Res}
- catch E:R -> Stack = wf:stack(E, R),
- wf:error(?MODULE,"Catch: ~p:~p~n~p", Stack),
- {stack,Stack} end,
- {reply,wf:format({io,render_actions(wf:actions()),<<>>}),Req, wf:context(State,?MODULE,Result)};
- info(Message,Req,State) -> {unknown,Message,Req,State}.
- % double render: actions could generate actions
- render_actions(Actions) ->
- wf:actions([]),
- First = wf:render(Actions),
- Second = wf:render(wf:actions()),
- wf:actions([]),
- [First,Second].
- % N2O events
- html_events({pickle,Source,Pickled,Linked}=Pickle, State) ->
- wf:info(?MODULE,"Pickle: ~tp",[Pickle]),
- Ev = wf:depickle(Pickled),
- _Result = case Ev of
- #ev{} -> render_ev(Ev,Source,Linked,State);
- CustomEnvelop -> wf:error("Only #ev{} events for now: ~p",[CustomEnvelop]) end,
- {io,render_actions(wf:actions()),<<>>}.
- render_ev(#ev{module=M,name=F,msg=P,trigger=T},_Source,Linked,State) ->
- case F of
- api_event -> M:F(P,Linked,State);
- event -> lists:map(fun({K,V})-> put(K,wf:to_binary(V)) end,Linked), M:F(P);
- _UserCustomEvent -> M:F(P,T,State) end.
- receive_actions(Req) ->
- receive
- {actions,A} -> n2o_nitrogen:render_actions(A);
- _ -> receive_actions(Req)
- after 200 ->
- QS = element(14, Req),
- wf:redirect(case QS of <<>> -> ""; _ -> "?" ++ wf:to_list(QS) end),
- [] end.
|