Aula nº 8

Desenvolva um conjunto de funções em Erlang, que modelize as actividades habituais duma biblioteca

segundo o modelo cliente-servidor.

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


-module(aula8).

-export([start/0, biblioteca/0, introduzir/1, retirar/1, emprestar/1, devolver/1, listar/0]).

-define(BIBLIOTECA_NO, andy@jardel).

start() -> spawn( ?MODULE, biblioteca, [] ).

biblioteca() ->
	register( biblioteca, self() ),
	bib_processo( { [], 1 } ),
	io:format("serviço biblioteca terminou!").

bib_processo( {Livros, Num} ) ->
	receive
		{ msg_introduzir, Pid, Titulo } ->
			LivrosNovo_tuplo = introduzir( Titulo, { Livros, Num } ),
			Pid ! { msg_introduzir_conf, Num },
			bib_processo( LivrosNovo_tuplo );	

		{ msg_retirar, Pid, NumExcluir } ->
			case apagar( NumExcluir, Livros ) of
				erro ->
					Pid ! { msg_retirar_erro, NumExcluir },
					bib_processo( { Livros, Num } );
				LivrosActual ->
					Pid ! { msg_retirar_conf, NumExcluir },
					bib_processo( { LivrosActual, Num } )
				end;

		{ msg_emprestar, Pid, NumEmprestar } ->
			case emprestar( NumEmprestar, Livros ) of
				erro ->
					Pid ! { msg_emprestar_erro, NumEmprestar },
					bib_processo( { Livros, Num } );
				LivrosActual ->
					Pid ! { msg_emprestar_conf, NumEmprestar },
					bib_processo( { LivrosActual, Num } )
			end;

		{ msg_devolver, Pid, NumDevolver } ->
			case devolver( NumDevolver, Livros ) of
				erro ->
					Pid ! { msg_devolver_erro, NumDevolver },
					bib_processo( { Livros, Num } );

				LivrosActual ->
					Pid ! { msg_devolver_conf, NumDevolver },
					bib_processo( { LivrosActual, Num } )
			end;

		{ msg_listar, Pid } ->
			Pid ! { msg_listar_conf, Livros },
			bib_processo( {Livros, Num} )
	end.

introduzir( Titulo, { Lista, Num } ) ->
	{ [ { Num, Titulo, disponivel } | Lista ], Num + 1 }.

apagar( Num, Livros ) ->
	case [ X || X <- Livros, element( 1, X ) == Num ] of
		[] ->
			erro;
		[ Livro ] ->
			[ X || X <- Livros, element(1, X) =/= Num ];
		_ ->
			erro
	end.

emprestar( Num, Livros ) ->
	case [ X || X <- Livros, element(1, X) == Num, element(3, X) == disponivel ] of
		[] ->
			erro;
		[ { Num, Titulo, disponivel } ] ->
			[ { Num, Titulo, emprestado } | [ X || X <- Livros, element(1, X) =/= Num ] ];
		_ ->
			erro
	end.

devolver( Num, Livros ) ->
	case [ X || X <- Livros, element(1, X) == Num, element(3, X) == emprestado ] of
		[] ->
			erro;
		[{ Num, Titulo, emprestado }] ->
			[ { Num, Titulo, disponivel } | [ X || X <- Livros, element(1, X) =/= Num ] ];
		_ ->
			erro
	end.


% interface

introduzir( Titulo ) ->
	{ biblioteca, ?BIBLIOTECA_NO } ! { msg_introduzir, self(), Titulo },
	receive
		{ msg_introduzir_conf, Num } ->
		io:format( "Livro ~w, introduzido na BD com o numero ~w.~n", [ Titulo, Num ] )
	end.

retirar( Num ) ->
	{ biblioteca, ?BIBLIOTECA_NO } ! { msg_retirar, self(), Num },
	receive
		{ msg_retirar_conf, Num } ->
			io:format( "Livro ~w, retirado da BD.~n", [ Num ] );
		{ msg_retirar_erro, Num } ->
			io:format( "Livro ~w NAO existe da BD.~n", [ Num ] )
	end.

emprestar( Num ) ->
	{ biblioteca, ?BIBLIOTECA_NO } ! { msg_emprestar, self(), Num },
	receive
		{ msg_emprestar_conf, Num } ->
			io:format( "Livro ~w emprestado.~n", [ Num ] );
		{ msg_emprestar_erro, Num } ->
			io:format( "Livro ~w, NAO esta disponivel.~n", [ Num ] )
	end.

devolver( Num ) ->
	{ biblioteca, ?BIBLIOTECA_NO } ! { msg_devolver, self(), Num },
	receive
		{ msg_devolver_conf, Num } ->
			io:format( "Livro ~w devolvido.~n", [ Num ] );
		{ msg_devolver_erro, Num } ->
			io:format( "Livro ~w, NAO esta emprestado.~n", [ Num ] )
	end.

listar( ) ->
	{ biblioteca, ?BIBLIOTECA_NO } ! { msg_listar, self() },
	receive
		{ msg_listar_conf, ListaLivros } ->
			io:format( "Livros e seus estados:~n", [] ),
			apresentalivros( ListaLivros )
	end.

apresentalivros( [] ) -> true;
apresentalivros( [ { Num, Titulo, Estado } | Livros ] ) ->
	io:format("Numero: ~w Titulo: ~w Estado: ~w~n", [ Num, Titulo, Estado ]),
	apresentalivros( Livros ).
Índice

Última actualização: 14 Março 2000

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