/** file: Flux.java - definizione degli oggetti connettibili */
import java.awt.*;
/** ========================
OGGETTO CONNETTIBILE
======================== */
/** Questo "OGGETTO CONNETTIBILE" e' la classe astratta da cui
derivano le successive classi.
Ogni sottoclasse sara' un oggetto connettibile specializzato
(che assolve una propria funzione).
Grazie al collegamento ritardato (late-binding) un oggetto
connettibile puo' chiedere dati a un'"oggetto d'input" che
e' dichiarato come "OggConnet" ma che in realta' (durante
l'esecuzione) e' un'istanza di una qualsivoglia sottoclasse
di "OggConnet". */
abstract class OggConnet {
/** E' l'"oggetto connettibile" di input a cui questo "oggetto
connettibile" (in realta' l'istanza di una sua sottoclasse
specializzata) richiede di volta in volta i dati.
Questo oggetto e' a sua volta un "oggetto connettibile" */
protected OggConnet Input;
/** Area per stampare i messaggi (di evoluzione dello stream) */
protected TextArea ZonaMsg;
public OggConnet() {
this (null, null);
}
public OggConnet(OggConnet OggInput) {
this (OggInput, null);
}
/** Costruisce un "oggetto connettibile" collegato a un certo
oggetto (a cui richiedere l'"input" successivo).
Sulla TextArea passata si scriveranno i messaggi */
public OggConnet(OggConnet OggInput, TextArea AreaMsg) {
Input = OggInput; // Salva oggetto da cui ricevere dati
ZonaMsg = AreaMsg;
}
/** Rende il dato successivo.
Viene specializzata nelle sottoclassi */
public abstract int DammiSucc();
/** Rende l'oggetto a cui questo oggetto connettibile
chiede i dati d'ingresso */
public OggConnet RendiOggInput() {
return Input;
}
/** Stampa il messaggio nella TextArea definita (se c'e') */
public void StampaMsg (String Messaggio) {
if (ZonaMsg != null)
ZonaMsg.appendText (Messaggio);
}
/** Rende la TextArea usata per la stampa dei messaggi */
public TextArea RendiZonaMsg () {
return ZonaMsg;
}
}//OggConnet
/** ==============
GENERATORE
============== */
/** E` il generatore di numeri interi */
class Generatore extends OggConnet {
int Valore;
public Generatore (int ValIniz) {
this (ValIniz, null);
}
/** Costruisce un generatore di interi che comincia dall'
intero ValIniz in avanti (stampa sulla TextArea data) */
public Generatore (int ValIniz, TextArea A) {
super (null, A);
Valore = ValIniz;
}
/** Genera (e rende) il numero intero successivo */
public int DammiSucc() {
int Rendo=Valore;
Valore=Valore+1;
StampaMsg ("\nGen("+Rendo+")-->"); // Dice che num. genera
return Rendo;
}
}//Generatore
/** ==========
FILTRO
========== */
/** Il filtro lascia passare solo una certa "categoria" di
numeri interi. Viene chiesto all'oggetto d'ingresso di
dare un nuovo numero; se questo "soddisfa" il filtro,
viene reso; altrimenti si continua a chiedere
all'ingresso un nuovo numero. */
class Filtro extends OggConnet {
int Valore;
public Filtro (OggConnet OggInput, int ValIniz) {
this (OggInput, ValIniz, null);
}
/** Costruisce un filtro che chiedera' dati all'oggetto di
ingresso e fara' "passare" solo i dati che soddiferanno
alla "proprieta'" caratteristica del filtro.
Per la "proprieta'" il filtro usera' il dato "ValIniz". */
public Filtro (OggConnet OggInput, int ValIniz, TextArea A) {
super (OggInput, A);
Valore = ValIniz;
}
/** Rende il dato successivo.
La richiesta viene passata all'oggetto collegato all'
input del filtro (un generatore o un filtro).
La richiesta arrivera' fino al generatore che rendera'
l'intero successivo fino al filtro stesso ma per essere
reso da questo il dato deve soddisfare una "proprieta'"
(caratteristica del filtro).
In caso negativo, viene automaticamente richiesto un
nuovo dato all'oggetto d'input, e cosi' via finche' non
si avra' un dato che "soddisfi" il filtro. */
public int DammiSucc() {
int Num = 0;
boolean Continua=true;
while (Continua) {
// Passa la chiamata all'oggetto precedente (filtro/gen.)
Num=Input.DammiSucc();
StampaMsg ("Filtro("+Valore+")"); //Dice cosa blocca
// Controllo se filtrare o meno il numero reso
if ((Num % Valore)!=0) {
Continua=false;
StampaMsg ("-->");
}
else
StampaMsg (":BLOCCATO");
}
// Rende il numero (non e' stato fermato dal filtro)
return Num;
}
}//Filtro
/** ================
ACCUMULATORE
================ */
/** L'accumulatore deve essere inizialmente collegato a un
generatore (cioe' deve chiedere i dati al generatore).
Ogni volta che un dato reso dall'oggetto di ingresso
arriva all'accumulatore, viene creato un oggetto "filtro"
tra l'accumulatore e il suo oggetto d'input. */
class Accumulatore extends OggConnet {
public Accumulatore (OggConnet OggInput) {
this (OggInput, null);
}
/** Crea un accumulatore connesso (inizialmente) al
generatore passato (scrivera' sulla TextArea data) */
public Accumulatore (OggConnet OggInput, TextArea A) {
super (OggInput, A);
}
/** Rende il dato successivo.
La richiesta viene passata all'oggetto collegato all'
input dell'accumulatore (inizialmente un generatore,
poi un filtro). La richiesta arrivera' fino al
generatore ma per tornare fino all'accumulatore
dovra' passare (e quindi "andare bene") attraverso
tutti i filtri posti nel "flusso". */
public int DammiSucc() {
int Num=Input.DammiSucc();
// Al ritorno un numero sara' arrivato all'Accumulatore:
// creero' un nuovo filtro (basato su quel numero) tra
// l'accumulatore e il filtro/generatore.
Input=new Filtro (Input, Num, RendiZonaMsg());
StampaMsg ("Accum("+Num+"). <CREO Filtro("+Num+")>");
return Num; // e rendo il numero trovato
}
}//Accumulatore
//FINE FILE