Jak vyrobit nový modul do JaGrLibPiece.
@author).
@version, viz soubor
Version.java).
package java.util: (BitSet), HashMap,
HashSet, ArrayList, LinkedList, apod. + prislusne Iterator. I zde jsou samozrejme
vyjimky potvrzujici pravidlo..
package cz.cuni.jagrlib.testing
package cz.cuni.jagrlib.obscure (bez zdrojaku) nebo
package cz.cuni.jagrlib.piece (uplne verejne).
Piece, Plug, Channel:Piece je zakladni "stavebni kamen", ze ktereho se sklada
"stavebnice" = algoritmus.
Je to jakasi "krabicka" ("black-box"), ktera implementuje predepsane protokoly
(interface v Jave) a az v druhem planu (prip. zcela nedulezita) je konkretni metoda
jejich realizace.
Kazdy Piece definuje jakesi "stycne body" se svym okolim -
Plugs (zasuvky). Kazdy Plug rika, ktery protejsek (opet formalne typu
Piece) se na tomto miste muze pripojit (a zda smi pripadne tento Plug
zustat nezapojen). Konkretni propojeni je realizovano tridou Channel: na kazde
strane ma jeden Piece (vlastne jeden jeho Plug), a tedy jeden protokol
(interface v Jave). Pres Channel se tedy da komunikovat oboustranne:
leva strana vola dany protokol prave strany a naopak..
Plug je v ramci sveho Piece odkazovani pomoci "klice" -
znakoveho retezce. Stejny klic se pouziva ke konkretnimu propojeni (Channel).
Kazdy Plug ma nekolik atributu:
isMandatory() - oznacuje, zda musi byt tato zasuvka vzdy povinne zapojena.
isMulti() - dovoluje pripojit zasuvku na tzv. MultiChannel
(protejskem by pak bylo soucasne nekolik objektu Piece).
isCloneable() - oznacuje tzv. "klonovatelne" zasuvky:
Piece na tomto miste muze obslouzit jednu nebo vice kompatibilnich zasuvek. Jedna
takova zasuvka existuje vzdy, ostatni se mohou v pripade potreby " naklonovat"
(identifikatory jsou pak zakonceny poradovymi cisly).
inputInterfaceName - identifikator protokolu, ktery muze byt zvnejsku volan
(muj protejsek mne vola).
outputInterfaceName - identifikator protokolu, ktery volam smerem ven
(ja volam muj protejsek).
Template, registrace:Konkretni konfigurace zasuvek (Plugs) nejakeho modulu muze byt
reprezentovana ve forme objektu s protokolem Template. Je to jakysi
"vzor", katalogizace Piece z hlediska kompatibility (spise
formalni = syntakticke, nez semanticke).
Jeden konkretni Piece muze splnovat nekolik ruznych Template,
tj. muze hrat nekolik ruznych "roli" (byt zamenitelny podle ruznych vzoru).
Jednotlive Template hraji roli ekvivalenci (ve smyslu kompatibility) na tride
vsech modulu.
Moduly se v systemu JaGrLib registruji v tzv. registracni databazi. Ucelem registracni databaze je umoznit pracovat s modulem jako s "cernou skrinkou" (krabickou), aniz bychom meli k dispozici jeho zdrojovy soubor (nebo .class soubor). Zaznam v registracni databazi obsahuje:
Informace o zasuvkach musi obsahovat kompletni udaje o vsech povinnych i nepovinnych
zasuvkach, jejich typech (interface), apod.
Parametry jsou zadany retezcovym identifikatorem, datovym typem a prip. muze byt u kazdeho parametru definovano, jak se ma editovat v GUI podobe (tzv. "manipulator"). Na vyber jsou editacni radky, list-boxy, ruzna "tocitka" a nakonec i GUI objekty, ktere muze naprogramovat sam uzivatel. Parametr muze mit implicitni hodnotu, rozsah pripustnych hodnot, atd.
Textove registracni udaje slouzi pouze cloveku k lepsi orientaci v registracni databazi a pri vyberu modulu:
name - kratke jmeno modulu (ukazuje se v titulku krabicky v GUI), napr.
"Bresenham"
template - zkratka "typu modulu" (resp. jeho role), strucne
shrnuje typy vstupnich a vystupnich zasuvek, napr.
"LineRenderToBitMask"
category - strukturovany retezec popisujici kategorii modulu, napr.
"2d.draw.line.integer"
description - libovolny delsi popis modulu a jeho funkce (komentar autora)
setTemplate():Ve staticke rutine setTemplate(Template,int) programator modulu deklaruje
vlastnosti modulu, ktere jsou potreba pro jeho praci, ulozeni do registracni databaze,
apod. Nektere zde definovane hodnoty se pozdeji mohou v registracni databazi rucne
prepsat, ale neni to standardni postup (normalne by se autorske hodnoty mely respektovat).
Muze-li modul vystupovat ve vice "rolich" (sablonach, Templates),
je treba testovat pozadovanou sablonu (parametr int ord) a chovat se
pokazde jinak.. Je-li zadana hodnota ord < 0, znamena to, ze se ma nastavit
sjednoceni vsech zasuvek a parametru:
public static int setTemplate ( Template t, int ord )
K zadani registracnich retezcu slouzi rutina
t.setRegStrings(NAME,TEMPLATE,CATEGORY,DESCRIPTION) (semantika
parametru je popsana vyse). U testovaneho modulu neni retezce bezpodminecne nutne
zadavat, u modulu pripraveneho ke zverejneni by se tam mely vyplnit smysluplne hodnoty!
Povinna je cast definujici zasuvky ( Treti cast definuje parametry (atributy, "Properties") modulu.
Jedna se o tytez hodnoty, na ktere program muze pristupovat pomoci Podrobnejsi a uplny vycet vsech moznosti pri registraci parametru modulu je mozne
nalezt v dokumantaci k interface Template.
Nepovinne je mozne zadavat napr. implicitni hodnotu ( Priklad trochu slozitejsi definice parametru (ze souboru
LineBresenham.java):
Kompletni priklad registracni procedury Jednotlive kroky pri vytvareni potomka tridy Je nutne vytvorit fungujici "skladacku" rucne - viz napr.
Main00.java.
Copyright (c) 2000-2009 Josef Pelikán,
last change: $Date: 2013-11-22 23:47:16 +0100 (Fri, 22 Nov 2013) $
Plugs). V interface
Template lze najit nekolik variant metod, kterymi se zasuvky definuji:
void newPlug ( String key, boolean _mandatory,
boolean _multi, boolean _cloneable,
String
_inputInterface, String _outputInterface );
void newInputPlug ( String key, String _inputInterface );
void newOptInputPlug ( String key, String _inputInterface );
void newOutputPlug ( String key, String _outputInterface );
void newOptOutputPlug ( String key, String _outputInterface );
interface
Property - tj. metodami set(String,Object) a
get(String).
Registrace parametru je dulezita proto, aby se daly pouzivat i v GUI (aby je mohli
cist a zadavat uzivatele interaktivne).
popis kazdeho jednotliveho parametru je uzavren mezi
t.propBegin(String name,String type,String descr,boolean visual);
a
t.propEnd();
propDefault()),
mezni hodnoty (propBounds()) nebo tzv. "manipulator", kterym se
v GUI vizualne hodnota edituje (propManipulator()).
t.propBegin( LINE_JOIN, TYPE_INTEGER, "Line-join style", true );
t.propDefault( LINE_JOIN_DISJOINT );
t.propBounds( LINE_JOIN_DISJOINT, LINE_JOIN_OVERLAP );
t.propManipulator( MANIPULATOR_COMBO );
t.propEnum( "Disjoint", LINE_JOIN_DISJOINT, "Subsequent line segments are disjoint" );
t.propEnum( "Overlap", LINE_JOIN_OVERLAP, "Subsequent line segments have one common pixel" );
t.propEnd();setTemplate(template,int)
lze najit v nasledujicim oddile:
Jak napsat novy modul (potomek tridy
Piece):Piece mohou vypadat takto (priklady
jsou ze skutecne implementace LineBresenham):
interface), ktere musi dany objekt implementovat,
a deklarovat tridu s vhodnym jmenem jako potomka Piece (pracujeme v testovacim
balicku cz.cuni.jagrlib.testing):
package cz.cuni.jagrlib.testing;
public class LineBresenham extends Piece implements LineRender
{
...
}
interface). Pritom pro odkazovani na napojene Piece
pouzivat funkce getInterface(), napr.:
public void drawLine ( int x1, int y1, int x2, int y2 )
{
BitMask out = (BitMask)getInterface(OUTPUT,IFACE+"BitMask");
...
}
interface Property:
public void set ( String key, Object value )
public Object get ( String key )
public static int setTemplate ( Template t, int ord )
Tato rutina musi obsahovat definici registracnich retezcu (viz setRegStrings()),
definici vsech zasuvek Plugs daneho modulu a dale popis verejne pristupnych
parametru Properties.
Pro funkcnost modulu v systemu JaGrLib/Skel je bezpodminecne nutne zaregistrovat minimalne
zasuvky (Plugs). Zbytek registracni procedury jiz neni tak dulezity..
Podrobnosti viz interface Template a predchozi
oddil setTemplate. Priklad konkretni registracni procedury modulu
JFIFFileFormat:
public static int setTemplate ( Template t, int ord )
{
if ( t != null && ord <= 0 )
{
t.setRegStrings("JFIF file format","DataFileFormatToRasterGraphicsAndBitStream",
"io.2d.raster","JFIF (JPEG File Interchange Format) filter");
// Plugs:
t.newInputPlug( PL_INPUT, IFACE+"DataFileFormat" );
t.newOutputPlug( PL_RASTER, IFACE+"RasterGraphics" );
t.newOptOutputPlug( PL_OUTPUT, IFACE+"BitStream" );
// Property:
t.propBegin( DOUBLE_STREAM, TYPE_BOOLEAN, "Use floating-point data stream?", true );
t.propDefault( false );
t.propEnd();
t.propBegin( QUALITY, TYPE_FLOAT, "Compression quality in %", true );
t.propBounds( 0, 100 );
t.propDefault( 75 );
t.propEnd();
}
return 1;
}
Pokud by stacilo pouzivat modul bez GUI (jako napr.
v Main00.java), muze se vynechad predchozi
bod (registrace modulu).
Testování (starý zpusob - bez GUI):
Piece), ktere se budou pouzivat.
Piece.connect().
RasterImage.getBufferedImage() (viz
Main00.java).
JPEGImageEncoder (viz
Main00.java).
[JaGrLib home-page]
[News, credits]
[CGG at MFF UK]