-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfacein.erl
105 lines (91 loc) · 2.92 KB
/
facein.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
%Author: Tudor Dragan
-module(facein).
-export([start/1,name/1,add_friend/2,friends/1,broadcast/3,received_messages/1]).
start(Person) -> spawn(fun () ->
loop(dict:store(messageRefs,[],
dict:store(messages,[],
dict:store(friend_list,[],
dict:store(name, Person,
dict:new()))))) end).
rpc(Pid,Request) ->
Pid ! {self(), Request},
receive
{Pid, Response} -> Response
end.
rpc_no_response(Pid,Request) ->
Pid ! {self(), Request}.
% get the name of a Pid
name(Pid) ->
rpc(Pid, get_name).
%get friend list
friends(P) ->
rpc(P, get_friends).
% add a pid (F) to a pid's (P) firend list
add_friend(P,F) ->
F ! {self(), get_name},
receive
{F, {ok,Name}} ->
P ! {self(),{add_friend,{Name,F}}},
receive
{P, ok} -> "friend added";
{P, {error,Reason2}} -> Reason2
end;
{F, {error,Reason1}} -> Reason1
end.
%broadcast a message (M) to all of (P) friends within radius (R)
broadcast(P, M, R) ->
MessageRef = make_ref(),
{ok, Name} = name(P),
rpc_no_response(P, {broadcast_msg, {Name,MessageRef, M, R}}).
received_messages(P) ->
rpc(P, get_messages).
loop(PersonDatabase) ->
receive
{From, get_name} ->
From ! {self(), dict:find(name, PersonDatabase)},
loop(PersonDatabase);
{From, get_friends} ->
{ok, FriendList} = dict:find(friend_list, PersonDatabase),
From ! {self(), FriendList},
loop(PersonDatabase);
{From, {add_friend,{Name,F}}} ->
{ok,FriendList} = dict:find(friend_list, PersonDatabase),
NewFriendList = [{Name,F} | FriendList],
NewPersonDatabase = dict:store(friend_list,NewFriendList, PersonDatabase),
From ! {self(), ok},
loop(NewPersonDatabase);
{From, {broadcast_msg, MessagePackage}} ->
{P, MessageRef, M, R} = MessagePackage,
% io:format("MessageRef: ~p~n", [MessageRef]),
{ok,MessageRefList} = dict:find(messageRefs,PersonDatabase),
% io:format("MessageRef: ~p~n", [MessageRefList]),
%first chcek the radius for resending
case R > 0 of
true ->
%send to friends with (R-1)
{ok, FriendList} = dict:find(friend_list, PersonDatabase),
lists:map(fun({FriendName,Pid}) -> Pid ! {self(), {broadcast_msg, {P,MessageRef, M, R-1}}} end, FriendList),
true;
false -> false
%stop sending
end,
%then check if the message is already in the list to stop resending it
case lists:member(MessageRef,MessageRefList) of
false ->
NewMessageListRef = [MessageRef | MessageRefList],
{ok, MessageList} = dict:find(messages, PersonDatabase),
NewMessageList = [{P,M} | MessageList],
loop(dict:store(messageRefs,NewMessageListRef,
dict:store(messages, NewMessageList, PersonDatabase)));
true ->
loop(PersonDatabase)
end;
{From, get_messages} ->
{ok, MessageList} = dict:find(messages, PersonDatabase),
% io:format("MessageList: ~p~n", MessageList),
From ! {self(), MessageList},
loop(PersonDatabase);
{From, Other} ->
From ! {self(), {error, {Other}}},
loop(PersonDatabase)
end.