# &MCOP; : modèle object et streaming

## Aperçu

&MCOP; est utilisé dans &arts; pour :

- la communication entre objets

- la transparence réseau

- décrire les interfaces objet

- l'indépendance du langage

Un aspect majeur de &MCOP; est l'interface description language, &IDL;, dans laquelle les interfaces de &arts; et les API sont définies dans un langage indépendant.

Pour utiliser les interfaces &IDL; avec C++, le code &IDL; est compilé par le compilateur &IDL; en code C++. Lorsque vous implantez une interface, vous dérivez à partir de la classe squelette que le compilateur &IDL; a généré. Lorsque vous utilisez une interface, vous utilisez ainsi un wrapper. De cette façon,&MCOP; peut utiliser un protocole si l'objet auquel vous vous adressez n'est pas local - vous bénéficiez de la transparence réseau.

Ce chapitre est supposé décrire les caractéristiques de base du modèle objet qui résulte de l'utilisation de &MCOP;, le protocole, comment utiliser &MCOP; en C++ (language binding),etc.

## Interfaces et &IDL;

La plupart des services fournis par &arts;, comme les modules et le serveur sonore, sont définis en termes d'interfaces. Les interfaces sont spécifiées dans un format indépendant du langage de programmation :&IDL;.

Ceci permet de dissimuler la plupart des détails d'implantation des spécifications de l'interface, comme par exemple le format des flux de données multimédia, la transparence réseau, et les choses dépendantes du langage de programmation. Un outil, &mcopidl;, traduit la définition de l'interface en un langage de programmation spécifique (actuellement, seul le C++ est géré).

L'outil génère une classe squelette avec tout le code élémentaire et les fonctionnalités de base. Vous dérivez cette classe pour implémenter les caractéristiques souhaitées.

L'&IDL; utilisé par &arts; est similaire à celui utilisé par CORBA et DCOM.

Lesfichiers &IDL; peuvent contenir :

- Des directives #include dans le style C pour d'autres fichiers &IDL;.

- Des définitions d'énumérations et de types de structures, comme en C/C++

- Des définitions d'interfaces

En &IDL;, les interfaces sont définies comme une classe C++ ou une structure C, bien qu'il y ait certaines restrictions. Comme en C++ des interfaces peuvent être définies par héritage d'autres interfaces. Les définitions d'interfaces peuvent inclure trois choses : des flux, des attributs et des méthodes.

### Flux

Les flux représentent les données multimédia, faisant partie des composants les plus importants d'un module. Les flux sont définis par le format suivant :

[ async ] in|out [ multi ] type streamname [ , name ] ;

La direction d'un flux est définie par rapport au module, comme le précisent les paramètre obligatoires "in" et "out". L'argument "type" définit le type de la donnée, qui peut être de n'importe quel type décrit plus tard pour les attributs (tous ne sont pas encore supportés). Beaucoup de modules utilisent le type "audio", qui est un synonyme pour le type float (réel) utilisé en interne pour les flux audio. Plusieurs flots du même type peuvent figurer dans la même définition sous la forme d'une liste de noms séparés par des virgules.

Les flux sont par défaut synchrones, ce qui signifie qu'il constituent un flux continu de données à un taux constant, comme les données audio PCM. Le qualificateur async dénote un flux asynchrone, qui est utilisé pour les flux de données discontinus, comme par exemple les messages &MIDI;.

Le mot clé multi, valide uniquement pour les flux entrants, indique que l'interface gère un nombre variable d'entrées. C'est utile pour implanter des périphériques comme des tables de mixage qui peuvent accepter un nombre indéterminé de flux entrants.

### Attributs

Les attributs sont des données associées à une instance d'une interface. Ils sont déclarés comme variables membres en C++, et peuvent utiliser n'importe lequel des types suivants : boolean, byte, long, string, or float. Vous pouvez aussi utiliser des types de structure ou d'énumération définis par l'utilisateur aussi bien que des séquences de taille variable en utilisant la syntaxe sequence <type>. Les attributs peuvent en option être marqués en lecture seule.

### Méthodes

Comme en C++, des méthodes peuvent être définies dans les interfaces. Lesparamètres des méthodes sont restreintes au même type que celui des attributs.Le mot clé oneway indique une méthode qui renvoie une valeur immédiatement etest exécutée de manière asynchrone.

### Interfaces standards

Plusieurs interfaces de modules standards sont déjà définies dans &arts;, comme par exemple StereoEffect et SimpleSoundServer.

### Exemples

Un exemple simple de module tiré de &arts; est le module contenant un délai avec retard constant, qui se trouve dans le fichier `kdemultimedia/arts/modules/artsmodules.idl`. La définition de l'interface est donnée ci-dessous :

    interface Synth_CDELAY : SynthModule {
            attribute float time;
            in audio stream invalue;
            out audio stream outvalue;
    };

Ce module hérite de SynthModule. Cette interface, définie dans `artsflow.idl`, défini les méthodes standards implantées dans tous les modules de synthèse sonore.

L'effet CDELAY retarde un flux audio stéréo d'une durée spécifiées comme paramètre à virgule flottante. La définition de l'interface comporte un attribut de type float pour mémoriser la valeur du retard. Deux flux audio en entrée et deux en sortie sont définis (caractéristique des signaux stéréo). Aucune méthode n'est requise autre que celles héritées.

##

### Types de Flux

###

### Flux par défaut

    interface TwoToOneMixer {
        default in audio stream input1, input2;
        out audio stream output;
    };

## notifications de changement d'attribut

Les notifications de changement d'attribut sont un moyen de savoir lorsqu'un attribut a changé. C'est un peu semblable aux signaux et slots de &Qt;'s ou Gtk. Par exemple, si vous avez un élément d'interface graphique, une glissière, qui sélectionne un nombre entre 0 et 100, vous avez certainement un objet qui fait quelque chose avec ce nombre (par exemple, ce peut être contrôler le volume d'un signal audio). Donc vous voudrez que chaque fois que lag lissière change de position, l'objet qui gère le volume soit mis au courant. Une connexion entre un émetteur et un récepteur.

&MCOP; gère cela en fournissant des notifications lorsque des attributs changent. Tout ce qui est déclaré comme attributdans l'&IDL; peut émettre de telles notifications de changement, et devrait le faire chaque fois qu'il est modifié. Tout ce qui est déclaré comme attribut peut aussi reçevoir de telles notifications de changement. Donc par exemple si vous avez deux interfaces &IDL;, comme celles-ci :

     interface Slider {
             attribute long min,max;
             attribute long position;
     };
     interface VolumeControl : Arts::StereoEffect {
         attribute long volume; // 0..100
     };

Vous pouvez les connecter en utilisant les notifications de changement. Il utilise les opérations habituelles de connexion d'événements . Dans ce cas, le code C++ pour connecter deux objets ressemblerait à ceci :

    #include <connect.h>
    using namespace Arts;
    [...]
    connect(slider,"position_changed",volumeControl,"volume");

Comme vous pouvez le voir, chaque attribut offre deux flux, un pour envoyer cette notification de changement, appelé `attributename_changed`, et un pour reçevoir les notifications de changement, appelé `attributename`.

Il est important de savoir que ces notifications de changement et flux asynchrones sont compatibles. Ils sont aussi transparents vis-à-vis du réseau. Vous pouvez donc connecter une notification de changement d'un attribut de type flottant d'un widget de l'interface à un flux asynchrone d'un module de synthèse exécuté sur un autre ordinateur. Ceci implique bien sûr que les notifications de changement ne soient pas synchrones, ceci signifie qu'après avoir envoyé une notification de changement, il faut un certain temps avant qu'elle soit réellement reçue.

### Envoi de notifications de changement

Lorsque vous implantez des objets qui ont des attributs, vous devez envoyer des notifications de changement chaque fois qu'un attribut est modifié. Le code correspondant ressemble à ceci :

     void KPoti_impl::value(float newValue)
     {
         if(newValue != _value)
         {
             _value = newValue;
             value_changed(newValue); // <- send change notification
         }
     }

Il est fortement recommandé d'utiliser ce genre de code pour tous les objets que vous implantez, de façon à ce que les notifications de changement puissent être réutilisées par d'autres personnes. Il est préférable d'éviter d'envoyer des notifications trop fréquemment. Ainsi, si vous faites du traitement du signal, il est surement mieux de mémoriser les dernières notifications envoyées, afin de ne pas en envoyer une avec chaque échantillon traité.

### Applications pour les notifications de changement

Il est tout particulièrement intéressant d'utiliser les notifications de changement en conjonction avec des oscilloscopes (pour visualiser les données audio par exemple), éléments de l'interface, widgets de contrôle, et monitoring. Le code pour utiliser ceci se trouve dans `kdelibs/arts/tests`, et dans l'implantation expérimentale de artsgui, que vous pouvez trouver dans `kdemultimedia/arts/gui`.

###

Le fichier `.mcoprc` (présent dans le dossier personnel de chaque utilisateur) peut être utilisé pour configurer &MCOP;. Actuellement, les réglages suivants sont disponibles :

GlobalComm

  Nom de l'interface à utiliser pour la communication globale. Celle-ci est utilisée pour trouver des objets et obtenir le cookie secret. Les clients/serveurs &MCOP; multiples qui devraient pouvoir communiquer entre eux nécessitent un objet GlobalComm capable de partager l'information. Actuellement, les valeurs possibles sont Arts::TmpGlobalComm pour communiquer via le dossier `/tmp/mcop-username` (qui ne fonctionnera que sur l'ordinateur local) et Arts::X11GlobalComm pour communiquer via les propriétés de la fenêtre principale sur le serveur X11. Par exemple :

TraderPath

  Spécifie où chercher les informations du sélecteur dynamique d'application (trader). Vous pouvez lister plus d'un dossier ici, et les séparer par des virgules, comme

ExtensionPath

  Spécifie dans quels dossiers se situent les extensions (sous la forme de librairies partagées). Plusieurs valeurs peuvent être saisies, séparées par des virgules.

Voici un exemple qui utilise toutes les possibilités ci-dessus

    # $HOME/.mcoprc file
    GlobalComm=Arts::X11GlobalComm

    # if you are a developer, it might be handy to add a directory in your home
    # to the trader/extension path to be able to add components without
    # installing them
    TraderPath="/opt/kde2/lib/mcop","/home/joe/mcopdevel/mcop"
    ExtensionPath="/opt/kde2/lib","/home/joe/mcopdevel/lib"

### &MCOP; pour les utilisateurs de CORBA

####

dans &MCOP;

####

####

    // MCOP idl
    interface Synth_ADD : SynthModule {
        in audio stream signal1,signal2;
        out audio stream outvalue;
    };

####

####

### Aspect sécurité de &MCOP;

###

#### Introduction

####

|  | ``
|  | ``
|  | ``
|  | ``
|  | ``

struct

####

####

####

####

###