-module(tp2_correction). %% ---------------------------------------------------------------------------- -export([launch_ping/0, launch_ping/1, pong/0]). -export([launch_ring/1, launch_ring/2, deploy_ring/2]). -export([launch_star/1, launch_star/2, star_echo/0]). %% ---------------------------------------------------------------------------- launch_ping() -> launch_ping(1). launch_ping(0) -> io:fwrite("please, let me ping at least once~n"); launch_ping(Circles) -> self() ! {spawn(tp2, pong, []), Circles}, ping(). ping() -> receive {_, 0 } -> ok; {Pid, Token} -> io:fwrite("[~p] ~p ping~n", [Token, self()]), Pid ! {self(), Token}, ping() end. pong() -> receive {Pid, Token} -> io:fwrite("[~p] ~p pong~n", [Token, self()]), Pid ! {self(), Token-1}, if Token > 1 -> pong(); true -> ok end end. %% ---------------------------------------------------------------------------- launch_ring(Nb) -> launch_ring(Nb, 1). launch_ring(_, Circles) when Circles < 1 -> io:fwrite("ERROR : ring must go around at least once~n"); launch_ring(Nodes, _) when Nodes < 1 -> io:fwrite("ERROR : ring must contain at least 1 nodes~n"); launch_ring(Nodes, Circles) -> self() ! Circles, deploy_ring(Nodes-1, self()). deploy_ring(0, LoopPid) -> ring(LoopPid, true); deploy_ring(Count, LoopPid) -> ring(spawn(tp2, deploy_ring, [Count-1, LoopPid]), false). ring(Pid, Last) -> receive 0 -> if Last -> ok; true -> Pid ! 0, ok end; Token -> io:fwrite("[~p] ~p got token~n", [Token, self()]), if Last -> Pid ! (Token-1); true -> Pid ! Token end, ring(Pid, Last) end. %% ---------------------------------------------------------------------------- launch_star(Nodes) -> launch_star(Nodes, 1). launch_star(_, Circles) when Circles < 1 -> io:fwrite("ERROR : star must go around at least once~n"); launch_star(Nodes, _) when Nodes < 0 -> io:fwrite("ERROR : star cannot have a negative number of satellites~n"); launch_star(Nodes, Circles) -> star_root(deploy_star(Nodes), Circles). deploy_star(0) -> []; deploy_star(Count) -> [spawn(tp2, star_echo, []) | deploy_star(Count-1)]. star_root(Pids, State) -> case lists:foldl( fun (Target, Token) -> if Token == 0 -> ok; true -> io:fwrite("[~p] ~p send to ~p~n", [Token, self(), Target]) end, Target ! {self(), Token}, receive {_, N} -> N end end, State, Pids) of 0 -> ok; N -> star_root(Pids, N-1) end. star_echo() -> receive {Root, 0} -> Root ! {self(), 0}, ok; {Root, N} -> io:fwrite("[~p] ~p echo~n", [N, self()]), Root ! {self(), N}, star_echo() end.