summaryrefslogtreecommitdiffstats
path: root/src/core/ephraim.erl
blob: bd361188b9da75bdd08c7aee5e8d1f2d81f151b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
-module(ephraim).
-compile([debug_info, export_all]).

-record(state, {
	  conn   :: pid(),
	  roster :: pid(),
	  event  :: pid(),
	  convs  :: dict(),
	  uis    :: set()
	 }).

-spec start() -> ok.
start() ->
    spawn(?MODULE, init, []),
    ok.

-spec stop() -> ok.
stop() ->
    ephraim ! stop,
    ok.

-spec init() -> ok.
init() ->
    register(ephraim, self()),
    open_port({spawn_executable, "ephraim-gtk"}, [stream, use_stdio, out]),

    Conn = spawn(ephraim_conn, init, []),
    Roster = spawn(ephraim_roster, init, []),
    Event = spawn(ephraim_event, init, []),
    loop(#state{conn=Conn,roster=Roster,event=Event,convs=dict:new(),uis=sets:new()}),
    init:stop().

-spec get_conv(#state{},exmpp_jid:jid()) -> {#state{},pid()|undefined}.
get_conv(State, JID) ->
    Key = exmpp_jid:to_lower(JID),
    case Key of
	{_,_,undefined} ->
	    {State, undefined};
	_ ->
	    case dict:find(Key, State#state.convs) of
		{ok, Conv} ->
		    {State, Conv};
		error ->
		    Conv = spawn(ephraim_conv, init, [Key]),
		    Dict = dict:store(Key, Conv, State#state.convs),
		    {State#state{convs=Dict}, Conv}
	    end
    end.

-spec loop(#state{}) -> ok.
loop(State) ->
    receive
	stop ->
	    ephraim_util:send_all_values(State#state.convs, stop),
	    State#state.conn ! stop,
	    State#state.roster ! stop,
	    State#state.event ! stop,
	    ok;
	
	{register_ui, Pid} ->
	    io:format("Registered UI ~p~n", [Pid]),
	    UIs = State#state.uis,
	    State2 = State#state{uis=sets:add_element(Pid,UIs)},
	    loop(State2);
	
	{unregister_ui, Pid} ->
	    io:format("Unregistered UI ~p~n", [Pid]),
	    UIs = State#state.uis,
	    State2 = State#state{uis=sets:del_element(Pid,UIs)},
	    Size = sets:size(State2#state.uis),
	    if Size =:= 0 ->
		    self() ! stop;
	       true ->
		    ok
	    end,
	    loop(State2);
	
	{ui_update, Msg} ->
	    ephraim_util:send_all(sets:to_list(State#state.uis), Msg),
	    loop(State);
	
	{roster, Packet} ->
	    State#state.roster ! Packet,
	    loop(State);
	
	{receive_message, From, Packet} ->
	    {State2, Conv} = get_conv(State, From),
	    case Conv of
		undefined ->
		    io:format("~p~n", [Packet]);
		_ ->
		    Conv ! {receive_message, Packet}
	    end,
	    loop(State2);
	
	{receive_event, From, Packet} ->
	    State#state.event ! {receive_event, From, Packet},
	    loop(State);
	
	{receive_iq, IQ} ->
	    case IQ of
		{iq, response, result, _, 'jabber:iq:roster', Payload, _, _, 'jabber:client'} ->
		    State#state.roster ! {roster_iq, Payload};
		_ ->
		    io:format("ephraim: IQ: ~p~n", [IQ])
	    end,
	    loop(State);
	    
	Msg ->
	    io:format("ephraim: ~p~n", [Msg]),
	    loop(State)
    end.