-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathworker.erl
87 lines (76 loc) · 2.03 KB
/
worker.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
-module(worker).
-export([start/4, start/5]).
-define(change, 20).
-define(color, {0, 0, 0}).
-define(timeout, 10000).
start(Id, Module, Rnd, Sleep) ->
spawn(fun() -> init(Id, Module, Rnd, Sleep) end).
init(Id, Module, Rnd, Sleep) ->
Cast = apply(Module, start, [Id]),
Color = ?color,
init_cont(Id, Rnd, Cast, Color, Sleep).
start(Id, Module, Rnd, Peer, Sleep) ->
spawn(fun() -> init(Id, Module, Rnd, Peer, Sleep) end).
init(Id, Module, Rnd, Peer, Sleep) ->
Cast = apply(Module, start, [Id, Peer]),
{ok, Color} = join(Id, Cast),
init_cont(Id, Rnd, Cast, Color, Sleep).
join(Id, Cast) ->
receive
{view, _} ->
Ref = make_ref(),
Cast ! {mcast, {state_request, Ref}},
state(Id, Ref)
after ?timeout ->
{error, "no response from group"}
end.
state(Id, Ref) ->
receive
{state_request, Ref} ->
receive
{state, Ref, Color} ->
{ok, Color}
end;
_Ignore ->
state(Id, Ref)
end.
init_cont(Id, Rnd, Cast, Color, Sleep) ->
random:seed(Rnd, Rnd, Rnd),
Gui = gui:start(Id, self()),
Gui ! {color, Color},
worker(Id, Cast, Color, Gui, Sleep),
Cast ! stop,
Gui ! stop.
worker(Id, Cast, Color, Gui, Sleep) ->
Wait =
if Sleep == 0 ->
0;
true ->
random:uniform(Sleep) end,
receive
{change, N} ->
Color2 = change_color(N, Color),
Gui ! {color, Color2},
worker(Id, Cast, Color2, Gui, Sleep);
{state_request, Ref} ->
Cast ! {mcast, {state, Ref, Color}},
worker(Id, Cast, Color, Gui, Sleep);
{state, _, _} ->
worker(Id, Cast, Color, Gui, Sleep);
{join, Peer, Gms} ->
Cast ! {join, Peer, Gms},
worker(Id, Cast, Color, Gui, Sleep);
{view, _} ->
worker(Id, Cast, Color, Gui, Sleep);
stop ->
ok;
Error ->
io:format("strange message: ~w~n", [Error]),
worker(Id, Cast, Color, Gui, Sleep)
after Wait ->
Cast ! {mcast, {change, random:uniform(?change)}},
worker(Id, Cast, Color, Gui, Sleep)
end.
%% rotate RGB and add N
change_color(N, {R,G,B}) ->
{G, B, ((R+N) rem 256)}.