L'objectif de ce TP est de se faire la main sur l'utilisation de l'architecture PAC en programmant une application simple. Cette application n'a rien de révolutionnaire car le but ici est de :
Dans ce TP, nous allons créer une application qui permet de jouer avec la formule des gaz parfaits (PV=nRT). Cette application simule un ballon en verre fermé hermétiquement ayant une capacité d'1m3 dans lequel se trouve un certain nombre de moles d'un gaz parfait. Ce gaz a une certaine température et une certaine pression. Le but est d'arriver à une application qui gère le changement d'une de ces valeurs et qui repércute ce changement sur les autres valeurs suivant la formule. L'interface de notre application pourra avoir la forme suivante :
Par commodité, travaillez dans un répertoire IHM/TP1/
.
Créez un sous-repertoire à l'intérieur de celui-ci par étape proposée en recopiant le résultat final de l'étape précédente.
Par exemple, quand vous avez fini l'étape 2, vous pouvez faire :
[sunset:IHM/TP1/2] blanch% cd .. [sunset:IHM/TP1] blanch% ls -l total 0 drwxr-xr-x 2 blanch 68 Oct 10 17:46 1 drwxr-xr-x 2 blanch 68 Oct 10 17:46 2 [sunset:IHM/TP1] blanch% cp -R 2 3 [sunset:IHM/TP1] blanch% cd 3
Nous allons créer un premier agent.
Implémentons un agent température (AgentTemperature) qui permet à l'utilisateur de rentrer une température en degrés Kelvin.
Côté interface faites au plus simple (par exemple un canvas qui contient un label
et un entry
).
Exemple d'interface résultat :
Nous avons maintenant un agent température qui gère ce concept. Modifiez-le afin que la température soit affichée en degrés Celsius. Quels changements doit-on apporter ? Précisez où ? Une fois que vous avez ces réponses, effectuez les modifications dans le code
Exemple d'interface résultat :
Modifiez votre agent pour qu'il affiche la température en degrés Kelvin et Celsius. La température en degrés Celsius et la température en degrés Kelvin doivent s'afficher dans 2 fenêtres distinctes. Quand l'utilisateur modifie la valeur de l'une des températures, la valeur de l'autre est mise à jour. Avant de le programmer, dessinez la forme de votre nouvel agent et précisez les messages qui circulent entre ses facettes.
Exemple d'interface résultat :
On a maintenant un agent température qui fonctionne. On veut construire l'application qui gère la formule PV=nRT. On souhaite réutiliser l'agent Temperature qui stockait la température en Kelvin et l'affichait en Celsius. On veut visualiser la température, la pression et le nombre de moles, chacun des concepts étant affiché dans une fenêtre propre. Quels agents doit-on écrire pour avoir l'application compléte ? Dessinez l'architecture que vous envisagez ? Avant de passer à la partie programmation montrez moi votre architecture sur papier.
Dans la formule PV=nRT, la pression s'exprime en pascal, le volume en m3 et la temperature en degrés Kelvin. R vaut 8,31 J.mol-1.K-1 On veut visualiser la pression en bar (1 bar vaut 100 000 pascal) et la température en degrés Celsius (0 degré Kelvin vaut -273,15 degrés Celsius). Pour notre application on suppose que le volume restera constant : 1m3.
Faites en sorte que votre application soit contenue dans une seule fenêtre et que les concepts visuels soient affichés les uns à coté des autres. Quelles parties du code faut-il modifier ? Effectuez ces modifications.
Exemple d'interface résultat :
On veut maintenant que, lorsque l'utilisateur appuie sur les touches <Control>
et <p>
en meme temps, l'interface se modifie.
Les concepts affichés ne doivent plus être alignés horizontalement mais verticalement.
Si l'utilisateur reproduit cette combinaison de touches l'interface doit revenir dans son état d'origine.
Comment gérer ceci ?
Quelles modifications faut-il faire ?
Effectuez les modifications désirées.
Exemple d'interface résultat :
Dans cette étape, nous allons simuler un fuite de gaz du ballon en verre. Nous supposons que la fuite est de 0,01 moles par seconde et que l'environnement en dehors du ballon est constitué uniquement de "vide" (ainsi pas d'échange de gaz à l'intérieur du ballon).
Cette fuite implique que le ballon se vide progressivement de tout son contenu. Pour modéliser cette fuite vous devez modifier l'agent qui gère le nombre de moles. Le reste de l'architecture doit être prévenue du changement du nombre de moles ; ainsi on doit voir la pression diminuer toutes les secondes.
Pour modéliser ce phénomène vous avez besoin de créer un "thread" qui toutes les secondes modifie la valeur du nombre de moles. C'est à dire vous devez créer une callback qui modifie ce nombre et se rappelle une seconde plus tard... Attention : le nombre de moles ne peut être négatif !
method Agent callback {} { # modifier la valeur considérée ... set value [expr $value - 0.01] if { $value < 0 } { set value 0 } # ... prevenir ceux qui ont besoin du changement ... (à vous de jouer) # puis rappeller la callback une seconde plus tard # à l'aide de la commande after. after 1000 "$objName callback" }
Basez vous sur cet exemple pour résoudre le problème (bien sûr il y a d'autres choses à modifier). Cette fonction doit être définie au bon endroit dans l'architecture (justifiez votre choix).
Il faut appeler une première fois la fonction de rappel pour qu'ensuite le "thread" soit lancé. Cet appel ne peut être fait que quand toute l'architecture de votre application a été construite. Vous devez donc dans votre fichier de lancement de votre application créer votre application et ensuite appeller une méthode sur l'agent racine qui permet le lancement de la fonction de rappel.