Satimage Précédent | Suivant
Création du dictionnaire : le fichier sdef
Accueil Documentation Smile Calcul numérique Exploitation de programmes externes Les projets XCode Création du dictionnaire : le fichier sdef  

Nous avons vu comment gérer les AppleEvents depuis votre code, afin de pouvoir l'appeler depuis AppleScript. Il reste à définir le dictionnaire AppleScript de l'application ou du complément de pilotage qui sera fabriqué par votre projet.

Un dictionnaire AppleScript est la définition d'une terminologie utilisable dans un script AppleScript. Vous pouvez consulter dans Smile les dictionnaires disponibles en déroulant le menu Fichier > Ouvrir un dictionnaire.

Le fichier .sdef

Vous définirez le dictionnaire AppleScript correspondant à votre code en réécrivant le fichier «NomDuProjet».sdef du projet. Il s'agit d'un fichier XML correspondant à la DTD sdef.dtd (la DTD est une description des données qu'il contient).

Smile étant un éditeur de XML (permettant notamment de valider la syntaxe d'un XML), nous vous recommandons d'éditer ce fichier dans Smile. Pour cela, déplacez l'icône du fichier sur l'icône de Smile, le fichier s'ouvrira alors dans une nouvelle fenêtre Unicode. Vous pouvez alors vérifier la syntaxe XML en appuyant sur ^⌘R, et valider le fichier relativement à sa DTD (c'est-à-dire en tant que fichier .sdef) en appuyant sur ⌥⌘R. Cela vous permettra de vérifier si votre fichier .sdef est valide. Les messages d'erreurs que vous obtiendrez alors pourront vous être d'une grande aide pour trouver et résoudre rapidement les problèmes que vous rencontrez dans ces fichiers.

Introduction au XML

Si vous ne savez pas ce que c'est qu'un fichier XML, il vous suffit de savoir qu'il s'agit d'un fichier texte balisé. Les balises de texte commencent par le caractère < et finissent par le caractère >. par exemple, <balise> est une balise ouvrante, qui doit être suivie par une balise fermante </balise>, ce qui délimite ainsi le texte qui les sépare. <balise/> est également une balise, mais elle n'encadre aucun texte. Les balises peuvent contenir des attributs, par exemple <balise name="toto"/> contient un attribut name dont la valeur est "toto". Les balises peuvent être emboîtées mais il est toujours nécessaire qu'elles soient refermées dans l'ordre où elles ont été ouvertes.

Dans un tel fichier, vous devrez définir des chaînes de texte (par exemple les attributs description) pour lesquelles certains caractères sont réservés : vous aurez besoin d'utiliser des codes d'échappement pour les écrire, qui sont les mêmes qu'en html. Voici une liste des principaux caractères réservés avec leurs codes d'échappement respectifs :

CaractèreCode d'échappement
&&amp;
<&lt;
>&gt;
"&quot;
'&apos;

Structure d'un fichier .sdef
Pour connaître la structure d'une DTD, vous pouvez consulter les man pages de sdef. Pour cela, exécutez la commande man sdef dans un terminal.
En pratique il vous suffit de vous appuyer sur les fichiers fournis avec les projets d'exemple, en recopiant des structures de classes et de commandes, et de modifier les attributs leur correspondant. Les informations qui suivent ne sont pas exhaustives mais vous suffiront pour construire votre propre dictionnaire.
  • Les suites
    Un dictionnaire peut contenir plusieurs suites (comme par exemple le dictionnaire de Smile).
    L'élément dictionary peut contenir une ou plusieurs éléments suite. Ces éléments doivent avoir un attribut name, et un attribut code. Elles ont généralement aussi un attribut description. La valeur de l'attribut code doit être une chaîne de 4 caractères identifiant la suite.

    Exemple :
    <suite name="Sample Additions" code="SAMP" description="This is a sample by Satimage to be used within Smile. Check www.satimage-software.com for additional information.">

  • Les classes
    Les éléments suite peuvent contenir un ou plusieurs éléments class. Les éléments class doivent avoir un attribut name et un attribut code. D'autres attributs sont optionnels. La valeur de l'attribut code doit être une chaîne de 4 caractères identifiant la classe.

    Exemple :
                   <class name="array of real" code="Lido" hidden="yes" plural="arrays of real">
                   </class>
                   <class name="matrix" code="Matr" hidden="yes" plural="matrices">
                   </class>

  • Les commandes

    Les éléments suite peuvent contenir un ou plusieurs éléments command. Les éléments command doivent avoir un attribut name et un attibut code. D'autres attributs sont optionnels.
    La valeur de l'attribut code doit être une chaîne de 8 caractères identifiant la commande et correspondant aux deux codes de 4 octets identifiant l'AppleEvent. Les 4 premiers caractères sont généralement les mêmes que ceux de la suite qui contient la commande. Ce sont ces caractères qui doivent être utilisés dans la liste EventDescription gEventDescriptionList[] définie dans le fichier «NomDuProjet».cp.

    Chaque élément command peut contenir des éléments direct-parameter, parameter et result. Ces éléments doivent avoir des attributs type et (de préférence) description. L'attribut type doit correspondre à un type d'AppleScript (integer, real, string, etc.) ou à un nom de classe déjà défini. Les éléments parameter doivent de plus avoir des attributs name et code.
    La valeur de l'attribut code doit être une chaîne de 4 caractères identifiant le paramètre. Ce sont ces codes de 4 caractères qui doivent être utilisés comme paramètre de type AEKeyword dans l'appel de la fonction AEGetParamDesc qui récupère les paramètres d'entrée, dans le fichier «NomDuProjet».cp pour un projet d'osax, ou bien dans le fichier main.cp pour les projets d'applications scriptables.

    Exemple :


                   <command name="mandelbrot" code="SAMPMAND" description="compute a fractal set associated to the iterations of the analytic function f(z)=z*z+c">
                        <direct-parameter type="integer" optional="yes" description="maximum number of iterations. Default: 2556."/>
                        <result type="matrix" description="a matrix containing for each value of c the number of iterations necessary to reach abs(f(z))&gt;2"/>
                        <parameter name="xdata" code="x$$$" type="array of real" description="real part of c"/>
                        <parameter name="ydata" code="y$$$" type="array of real" description="imaginary part of c"/>
                   </command>
                   <command name="julia" code="SAMPJULI" description="compute a julia fractal set">
                        <direct-parameter type="integer" optional="yes" description="maximum number of iterations. Default: 2556."/>
                        <result type="matrix" description=""/>
                        <parameter name="xdata" code="x$$$" type="array of real" description="real part of c"/>
                        <parameter name="ydata" code="y$$$" type="array of real" description="imaginary part of c"/>
                   </command>

    Pour cet exemple, la variable gEventDescriptionList du code source (dans le fichier «NomDuProjet».cp) serait donc :

    EventDescription gEventDescriptionList[]={{'SAMP','MAND',0}, {'SAMP','JULI',1}};
    Et la fonction OsaxEventHandler pourrait être :
    pascal OSErr OsaxEventHandler(const AppleEvent* message, AppleEvent* reply, long refCon){
         switch(refCon){
              case 0: return MandelbrotFractalHandler( message, reply);
              case 1: return JuliaFractalHandler( message, reply);
              //insert here other cases as needed.
              default:return errAEEventNotHandled;
         }
    }

Remarques importantes
  • Le choix des noms des verbes
    Vous allez être amené à définir de nouveaux verbes, de nouveaux noms de paramètres et de nouveaux noms de classes pour votre propre dictionnaire. Si vous choisissez des noms qui existent déjà par ailleurs dans un autre dictionnaire, par exemple dans le dictionnaire de Smile ou dans celui d'un complément de pilotage, cela posera des problèmes de conflits de noms. Par conséquent il est très important de définir le moins de mots nouveaux et il faut que ces mots soient le plus spécifiques possible pour diminuer ce risque de conflit de noms.

    Par exemple, si vous programmez un complément de pilotage qui implémente une fonction de recherche de minimum, n'appelez pas cette fonction minimum, ce mot étant déjà défini comme paramètre de certaines fonctions de la Satimage.osax, et n'utilisez aucun autre terme générique.

    Diverses stratégies sont possibles pour éviter ce type de problème : vous pouvez définir des noms de commandes composés, par exemple FindMinimum, ou faire précéder tous vos noms de fonctions de lettres identifiant votre osax, comme par exemples les commandes de XMLLib qui commencent toutes par 'XML' (XMLOpen, XMLclose, etc). Certes, cela donnera des termes moins élégants que des termes génériques, mais cela vous évitera bien des soucis et vous permettra si vous le souhaitez de distribuer votre osax à d'autres personnes sans que cela ne puisse poser de problèmes.

  • Le choix des codes de 4 octets
    Comme vous l'avez vu, il est nécessaire de définir des codes de 4 octets pour définir certains mots du dictionnaire, ces codes servant à faire le lien avec les fonctions du C. Il est très important que ces codes ne correspondent pas à des codes déjà choisis pour d'autres fonctions ou correspondant à d'autres mots-clés d'AppleScript (ou d'autres mots-clés définis par d'autres projets). Le plus simple consiste à utiliser des mots-clés déjà existants avec leur code respectif. La liste des mots-clés définis par Apple est donnée sur cette page. Il est bon de savoir qu'Apple n'utilise que des codes de caractères minuscules. Il est donc conseillé d'utiliser des codes comportant au moins une majuscule lorsque vous inventez votre propre mot-clé. Ces codes peuvent aussi comporter des nombres, et d'autres caractères ASCII.

    Pour vérifier qu'un code n'est pas déjà utilisé, s'il s'agit d'un code de 4 caractères, par exemple 'Par1', tapez «class Par1» dans un terminal AppleScript de Smile et exécutez la ligne en appuyant sur ⌘R. Si ce code correspond déjà à un mot-clé, la ligne sera traduite par ce mot. Cela signifie que ce code est déjà pris et que vous devez en choisir un nouveau si le mot auquel il correspond n'est pas celui que vous avez choisi. Pour vérifier que l'identifiant d'un AppleEvent (c'est-à-dire un ensemble de deux codes de 4 octets) n'est pas déjà pris, par exemple SAMPMAND, exécutez de même la ligne de texte «event SAMPMAND».

  • Le choix des noms des paramètres
    En ce qui concerne le choix des noms de paramètres, il est préférable de réutiliser des noms déjà définis, afin de ne pas surcharger l'espace des noms.

    Pour connaître le code associé à un mot-clé que vous connaissez, par exemple data, écrivez ce mot dans un terminal AppleScript de Smile, sélectionnez-le et choisissez le menu User Scripts > More Smile Commands > Scripting > Property & class to raw code. L'opération inverse de celle décrite au paragraphe précédent s'effectuera et le mot sera remplacé par «class r$$$» : vous savez alors que vous pouvez utiliser comme paramètre de vos fonctions le mot-clé data, à condition de lui associer le code de 4 caractères 'r$$$'.

  • Modification de la terminologie d'un dictionnaire
    Si vous modifiez la terminologie AppleScript des commandes de votre code scriptable sans changer les codes de 4 octets les identifiant (par exemple lorsque vous renommez une commande findMin en findMin2), vous devrez relancer Smile pour qu'il puisse utiliser cette nouvelle terminologie.
English version
Copyright ©2008 Paris, Satimage