### Trading interfaces

aRts/MCOP heavily relies on splitting up things into small components. This makes things very flexible, as you can extend the system easily by adding new components, which implement new effects, fileformats, oscillators, gui elements, ... - as almost everything is a component, almost everything can be extended easily, without changing existing sources. New components can be simply loaded dynamically to enhance already existing applications.

However, to make this work, two things are required:

- components must advertize themselves - they must describe what great things they offer, so that applications will be able to use them
- applications must actively look for components that they could use, instead of using always the same thing for some task

The combination of this: components which say "here I am, I am cool, use me", and applications (or if you like, other components) which go out and look which component they could use to get a thing done, is called trading.

#### How components describe themselves

In aRts, components describe themselves by specifying values that they "support" for properties. A typical property for a file-loading component could be the extension of the files that it can process. Typical values could be "wav", "aiff" or "mp3". In fact, every component may choose to offer many different values for one property. So one single component could offer reading both, "wav" and "aiff" files, by specifying that it supports these values for the property "Extension".

To do so, a component has to place a .mcopclass file at an appropriate place, containing the properties it supports, for our example, this could look like this (and would be installed in <componentdir>/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

It is important that the filename of the .mcopclass-file also says what the interface of the component is called like. The trader doesn't look at the contents at all, if the file (like here) is called Arts/WavPlayObject.mcopclass, the component interface is called Arts::WavPlayObject (modules map to directories).

#### How to look for components

To look for components, there are two interfaces (which are defined in core.idl, so you have them in every application), called Arts::TraderQuery and Arts::TraderOffer. You to go on a "shopping tour" for components like this:

1. Create a query object:

           Arts::TraderQuery query;

2. Specify what you want. As you saw above, components describe themselves using properties, for which they offer certain values. So specifying what you want is done by selecting components that support a certain value for a property. This is done using the supports method of a TraderQuery.

           query.supports("Interface","Arts::PlayObject");
           query.supports("Extension","wav");

3. Finally, perform the query using the query method. Then, you'll (hopefully) get some offers.

           vector<Arts::TraderOffer> *offers = query.query();

4. Now you can examine what you found. Important is the interfaceName method of TraderOffer, which will tell you the name of the component, that matched the query. You can also find out further properties by getProperty. The following code will simply iterate through all components, print their interface names (which could be used for creation), and delete the results of the query again:

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

#### Conventions (usual properties)

For this kind of trading service to be useful, it is important to somehow agree on what kinds of properties components should usually define. It is essential that more or less all components in a certain area use the same set of properties to describe themselves (and the same set of values where applicable), so that applications (or other components) will be able to find them.

property | type | use | description
--- | --- | --- | ---
Author | string | optional | This can be used to ultimately let the world know that you wrote something. You can write anything you like in here, e-mail adress is of course helpful.

Buildable

boolean

recommended

This indicates whether the component is usable with RAD tools (such as Arts Builder) which use components by assigning properties and connecting ports. It is recommended to set this value to true for almost any signal processing component (such as filters, effects, oscillators, ...), and for all other things which can be used in RAD like fashion, but not for internal stuff like for instance Arts::InterfaceRepo.

Extension | string | where relevant | Everything dealing with files should consider using this. You should put the lowercase version of the file extension without the "." here, so something like "wav" should be fine.
Interface | string | required | This should include the full list of (useful) interfaces your components supports, probably including Arts::Object and if applicable Arts::SynthModule.
Language | string | recommended | If you want your component to be dynamically loaded, you need to specify the language here. Currently, the only allowed value is "C++", which means the component was written using the normal C++ API. If you do so, you'll also need to set the "Library" property below.
Library | string | where relevant | Components written in C++ can be dynamically loaded. To do so, you have to compile them into a dynamically loadable libtool (.la) module. Here, you can specify the name of the .la-File that contains your component. Remember to use REGISTER_IMPLEMENTATION (as always).
MimeType | string | where relevant | Everything dealing with files should consider using this. You should put the lowercase version of the standard mimetype here, for instance "audio/x-wav".
URL | string | optional | If you like to let people know where they can find a new version of the component (or a homepage or anything), you can do it here. This should be standard http or ftp URL.

back to index