Aula nº 12

Incorpore uma interface gráfica ao módulo desenvolvido na aula 9.
As mensagens deverão manter-se da versão anterior, mas a informação apresentada deverá ser substituída. Assim, quando um nó receber a mensagem de hello, deverá apresentar na sua janela um símbolo (e.g. círculo) durante um determinado tempo (timeout). Passado esse tempo, o símbolo é apagado e a mensagem deverá ser enviada para o nó seguinte. Este ao receber a mensagem procederá da mesma forma. Aquando da recepção da mensagem de fim, cada nó deverá apresentar outro símbolo (ou de outra cor) e terminar.

OC 98-99 (Exercícios Práticos)

-module(aula12).
-export([anel/2, no_anel/1]).

-define(SCREEN_HEIGHT, 600).
-define(SCREEN_WIDTH, 800).
-define(WIN_HEIGHT, 100).
-define(WIN_WIDTH, 100).

-define(TIMEOUT, 500).

anel(N_msg, M_nos) ->
	% como este proprio processo conta como no,
	% entao apenas se criam M - 1 processos
	Pid_seguinte = criar_nos_anel( M_nos - 1, self() ),
	Canvas = create_window(),
	enviar_msgs_anel( N_msg, Pid_seguinte, Canvas ).

criar_nos_anel( 0, Pid_seguinte ) ->
	Pid_seguinte;
criar_nos_anel( M, Pid_seguinte ) ->
	Pid_anterior = spawn( ?MODULE, no_anel, [ Pid_seguinte ] ),
	criar_nos_anel( M-1, Pid_anterior ).

no_anel( Pid_seguinte ) ->
	Canvas = create_window(),
	process_msg( Pid_seguinte, Canvas ).

process_msg(Pid_seguinte, Canvas ) ->
	receive
		hello ->
			Bola = gs:create(oval, Canvas, [
							{ coords, [{30, 30},{70, 70}] },
							{ fill, blue }
							] ),
			receive
				after ?TIMEOUT ->
					gs:destroy(Bola)
			end,

			Pid_seguinte ! hello,
			process_msg( Pid_seguinte, Canvas );
		fim ->
			Bola = gs:create(oval, Canvas, [
							{ coords, [{30, 30},{70, 70}] },
							{ fill, red }
							] ),
			receive
				after ?TIMEOUT ->
					gs:destroy(Bola)
			end,
			% termina processo
			Pid_seguinte ! fim
	end.

enviar_msgs_anel( 0, Pid_seguinte, Canvas ) ->
	enviar_msg_anel_fim( Pid_seguinte, Canvas );

enviar_msgs_anel( N, Pid_seguinte, Canvas ) ->
	Pid_seguinte ! hello,
	receive
		hello ->
			Bola = gs:create(oval, Canvas, [
							{ coords, [{30, 30},{70, 70}] },
							{ fill, blue }
							] ),
			receive
				after ?TIMEOUT ->
					gs:destroy(Bola)
			end,

			enviar_msgs_anel( N-1, Pid_seguinte, Canvas )
	end.

enviar_msg_anel_fim( Pid_seguinte, Canvas ) ->
	Pid_seguinte ! fim,
	receive
		fim ->
			Bola = gs:create(oval, Canvas, [
							{ coords, [{30, 30},{70, 70}] },
							{ fill, red }
							] ),
			receive
				after ?TIMEOUT ->
					gs:destroy(Bola)
			end,
			gs:stop()
	end.

create_window() ->
	Top = gs:start(),
	{X, Y} = get_window_position(),
	Win = gs:create(window, Top, [{x, X}, {y, Y}, {width, ?WIN_WIDTH}, {height, ?WIN_HEIGHT}] ),
	Canvas = gs:create(canvas, Win, [{x,0}, {y,0}, {width,  ?WIN_WIDTH}, {height, ?WIN_HEIGHT}] ),
	gs:config(Win, {map, true}),
	Canvas.

get_window_position() ->
	{A, B, C } = now(),
	random:seed(C, C*B, C*C),
	X = random:uniform(?SCREEN_WIDTH - ?WIN_WIDTH),
	Y = random:uniform(?SCREEN_HEIGHT - ?WIN_HEIGHT),
	{X, Y}.
Índice

Última actualização: 18 Abr 2005

OC 98-99 (Exercícios Práticos)