Handleren

aRts/MCOP afhænger helt af at opdele objekter i små komponenter. Dette gør alt meget fleksibelt, eftersom man let kan udvide systemet ved at tilføje nye komponenter, som implementerer nye effekter, filformater, oscillatorer, grafiske elementer, ... Eftersom næsten alt er komponenter, kan næsten alt let udvides uden at ændre eksisterende kildekode. Nye komponenter kan enkelt indlæses dynamisk for at forbedre programmer som allerede eksisterer.

For at dette skal virke, kræves der dog to ting:

Kombinationen af dette: komponenter som siger “her er jeg, jeg er smart, brug mig”, og programmer (eller om man vil, andre komponenter) som går ud og leder efter hvilken komponenter de kan bruge for at få noget gjort, kaldes at handle.

I aRts beskriver komponenter sig selv ved at angive værdier som de “understøtter” som egenskaber. En typisk egenskab for en filindlæsningkomponent kan være filendelsen for filerne som den kan behandle. Typiske værdier kan være wav, aiff eller mp3.

I virkeligheden kan hver komponent vælge at tilbyde mange forskellige værdier for en egenskab. Så en enkelt komponent ville kunne tilbyde at læse både wav og aiff-filer, ved at angive at den understøtter disse værdier for egenskaben “Endelse”.

For at gøre dette, skal en komponent placere en .mcopclass-fil som indeholder egenskaberne den understøtter på et passende sted. For vort eksempel, kan den se sådan her ud (og ville være installeret i komponentmappen/Arts/WavPlayObject.mcopclass):

Interface=Arts::WavPlayObject,Arts::PlayObject,Arts::SynthModule,Arts::Object
Author="Stefan Westerfeld <stefan@space.twc.de>"
URL="http://www.arts-project.org"
Extension=wav,aiff
MimeType=audio/x-wav,audio/x-aiff

Det er vigtigt at filnavnet på .mcopclass-filen også angiver hvad komponentens grænseflade hedder. Handleren kigger ikke på indholdet overhovedet, hvis filen (som her) hedder Arts/WavPlayObject.mcopclass, og komponentgrænsefladen hedder Arts::WavPlayObject (moduler hører sammen med mapper).

For at lede efter komponenter er der to grænseflader (som er definerede i core.idl, så de er tilgængelige i hvert program), som hedder Arts::TraderQuery og Arts::TraderOffer. Du går på en “indkøbsrunde” efter komponenter sådan her:

  1. Opret et forespørgselsobjekt:

    Arts::TraderQuery query;
    
  2. Angiv hvad du vil have. Som du så ovenfor, beskriver komponenter sig selv med egenskaber, som de sætter til visse værdier. Så at specificere hvad du vil have gøres ved at vælge komponenter som understøtter en vis værdi for en egenskab. Dette sker med metoden supports i TraderQuery:

    query.supports("Interface","Arts::PlayObject");
        query.supports("Extension","wav");
    
  3. Tilsidst udføres forespørgslen med metoden query. Derefter får du (forhåbentlig) nogle tilbud:

    vector<Arts::TraderOffer> *offers = query.query();
    
  4. Nu kan du undersøge hvad du fandt. Det vigtige er metoden interfaceName i TraderOffer, som giver dig navnene på komponenterne som svarede på spørgsmålet. Du kan også finde ud af yderligere egenskaber med getProperty. Følgende kode løber helt enkelt gennem alle komponenterne, udskriver deres grænsefladenavn (som ville kunne bruges til at oprette dem), og fjerner resultaterne af forespørgslen igen:

    vector<Arts::TraderOffer>::iterator i;
        for(i = offers->begin(); i != offers->end(); i++)
            cout << i->interfaceName() << endl;
        delete offers;
    

For at denne slags handelsservice skal være nyttig, er det vigtigt på en eller anden måde at blive enig om hvilke egenskaber som komponenter normalt skal definere. Det er væsentligt at mere eller mindre alle komponenter indenfor et vist område bruger samme sæt egenskaber til at beskrive sig selv (og samme sæt værdier når det behøves), så programmer (eller andre komponenter) kan finde dem.

Author (type streng, valgfri): Forfatter. Dette kan bruges til endelig at lade verden finde ud af at du har skrevet noget. Du kan skrive hvad du vil her, en e-mail-adresse er naturligvis en god hjælp.

Buildable (type boolean, anbefales): Bygbar. Dette angiver om komponenten er brugbar med RAD-værktøj (såsom aRts-builder) som bruger komponenter ved at tildele egenskaber og forbinde porte. Det anbefales at denne værdi sættes til true for næsten alle signalbehandlingskomponenter (såsom filer, lydeffekter, oscillatorer, ...), og for alle andre objekter som kan bruges på en RAD-lignende måde, men ikke for interne objekter som for eksempel Arts::InterfaceRepo.

Extension (type streng, brugt hvor det passer): Filendelse. Alle moduler som håndterer filer bør overveje at bruge dette. Du angiver filendelsen med små bogstaver uden “.” her, så noget som wav skulle virke udmærket.

Interface (type streng, kræves): Grænseflade. Dette skal omfatte hele listen af (nyttige) grænseflader som din komponent understøtter, formodentlig inklusive Arts::Object og hvis anvendeligt Arts::SynthModule.

Language (type streng, anbefales): Sprog. Hvis du ønsker at din komponent skal indlæses dynamisk, skal du angive sproget her. For øjeblikket er den eneste tilladte værdi C++, som betyder at komponenten er skrevet med den normale C++ programmeringsgrænseflade. Hvis du angiver dette, skal du også angive egenskaben “Library” nedenfor.

Library (type streng, brugt hvor det passer): Bibliotek. Komponenter som er skrevet i C++ kan indlæses dynamisk. For at gøre dette skal du kompilere dem i et dynamisk indlæseligt libtool (.la) modul. Her kan du angive navnet på .la-filen som indeholder din komponent. Husk at bruge REGISTER_IMPLEMENTATION (som altid).

MimeType (type streng, brug hvor det passer): Mimetype. Alle som håndterer filer bør overveje at bruge dette. Du skal angive standard-mimetypen med små bogstaver her, for eksempel audio/x-wav.

URL (type streng, valgfri): Hvis du vil fortælle hvor man kan finde en ny version af komponenten (eller en netside eller noget andet), kan du gøre dette. Dette skal være en standard HTTP- eller FTP-netadresse.