This repository has been archived by the owner on Feb 23, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patheircd_channels.erl
81 lines (72 loc) · 1.67 KB
/
eircd_channels.erl
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
-module(eircd_channels).
-export([create/1, find/1, save/1, delete/1, add_user/2, filter/1]).
-include("common.hrl").
create(Name) ->
case find(Name) of
none ->
Process = spawn(fun()-> run(empty) end),
State = #channel{
name = Name,
process = Process
},
save(State),
ets:insert(channels, [{Name, Process}]),
State;
State ->
State
end.
find(Name) ->
Matches = ets:lookup(channels, Name),
case Matches of
[{Name, Process}] ->
read(Process);
[] ->
none
end.
save(Channel) ->
Process = get_channel_process(Channel),
Process ! {self(), save, Channel},
receive ok -> ok end.
delete(Channel) ->
UserCount = sets:size(Channel#channel.users),
case UserCount of
0 ->
Process = get_channel_process(Channel),
Process ! {self(), delete},
receive
ok ->
ets:delete(channels, Channel#channel.name),
ok
end;
_ ->
not_empty
end.
add_user(Channel1, User) ->
UsersInChannel1 = Channel1#channel.users,
UsersInChannel2 = sets:add_element(User#user.socket, UsersInChannel1),
Channel2 = Channel1#channel{users=UsersInChannel2},
save(Channel2).
filter(Predicate) ->
%sequential scan, not efficient
AllProcesses = ets:match(channels, {'_', '$1'}),
All = lists:map(fun read/1, AllProcesses),
lists:filter(Predicate, All).
run(State) ->
receive
{Invoker, read} ->
Invoker ! State,
run(State);
{Invoker, save, NewState} ->
Invoker ! ok,
run(NewState);
{Invoker, delete} ->
Invoker ! ok
end.
read(Process) ->
Process ! {self(), read},
receive
Channel ->
Channel
end.
get_channel_process(Channel) ->
Channel#channel.process.