Table of Contents

Commit 2010-12-20

Visu rupture (3/3)

En résumé: si à la fermeture d'un test vous avez des leaks VTK, c'est que soit vous avez interrompu brutalement votre test, soit il y a un problème dans les destructeurs. Dans ce dernier cas, si vous n'avez pas touché à la visu, signalez moi le problème.

Interface rupture

L'interface “rupture” de Pierre-Paul a été nettoyée parce qu'elle n'était pas claire. Avant, le fait qu'un élément soit cassé était décrit par un booléen nommé activity qui n'a rien à voir avec la classe Activable de Metafor. Pour manipuler cette variable à partir d'un critère de rupture par exemple, il y avait les traditionnels setActivity() et getActivity() mais aussi setActive() et setInActive() qui géraient la transition d'un état à l'autre. Pour corser le tout, malgré le fait que les Elements ne soient pas Activable, il était possible de les désactiver (au sens Activable du terme) par un appel d'une interface vers l'autre, camouflé dans Interaction.

Outre le problème de confusion de nom, le plus gros problème, selon moi, est qu'il était possible de casser un élément par setActivity(false) sans passer par la routine setInActive(), et donc sans gérer la transition d'état!! On était donc pas loin d'un état “ça marche, j'y touche plus”.

Donc, j'ai renommé tout d'abord activity en enabled pour éviter la confusion de nom avec Avtivable. Les fonctions setActivity() et getActivity() deviennent naturellement setEnabled() etgetEnabled(). J'ai ensuite fusionné le contenu de setActive() et setInActive() dans ces mêmes fonctions pour éviter les problèmes de transition d'état. En rendant setEnabled() virtuelle, on peut être certain que la transition d'un état à l'autre (cassé ⇔ pas cassé) se fait à un endroit unique! (c'est évidemment à cet endroit que je remets à jour la visu)

J'ai eu de gros problèmes avec cette modif parce que la confusion des deux systèmes d'activation (Activable et rupture) était un moyen de faire fonctionner beaucoup de tests, notamment les tests de soudure (welding). Pour arriver à faire tout fonctionner avec l'interface nettoyée, j'ai du faire des hypothèses au niveau de l'activation/désactivation des interactions. la logique est la suivante:

Lors d'une transition de stage:

Nouveau système d'Events

Le problème est le suivant:

Pour résoudre ce genre de problème, il existe un “Design Pattern” nommé Subject/Observer. Je l'ai déjà utilisé plusieurs fois dans le code (dans Gen4 et pour les DataCurve, c'est-à-dire la visu des courbes).

Le “sujet” (subject), ici, est l'élément fini qui peut se rompre. Il doit informer la visu d'une manière ou d'une autre qu'il est cassé. Il contient une liste d'observateurs (observers) qui peuvent s'enregistrer auprès de lui (ici, ce sont les objets “drawables” associés de la visu). Quand l'élément se casse, il prévient les observateurs en appellant explicitement une fonction “notify()” qui transmet l'info aux observateurs. Eux font ce qu'ils veulent à ce moment là (ici, ils se déclarent “invalides” pour le remettre à jour lors de la prochaine mise à jour de la visu.

Si on veut un peu complexifier le système, comme par exemple ajouter des arguments aux appels “notify()”, on ajoute le concept d' “événement” (Event). La fonction notify() envoie alors aux observateurs un objet de type Event qui peut contenir autant d'infos qu'on veut. Le sujet peut être vu ainsi comme un générateur d'événements. Il dit “je suis cassé”, “je suis sur le pont de me détruire”, … et n'importe quel objet peut l' “écouter” et réagir à ces événements.

Pour que tout ceci soit codé de manière générique tout en restant simple, j'ai fusionné les interfaces “subject” et “observer” traditionnelles en une seule classe que j'ai nommée EventAware (en hommage à JCVD, mon acteur préféré).

En pratique, Element, ElementSet, Interaction, InteractionSet sont awares (EventAware) et utilisent uiquement l'interface “sujet” de la classe. ElementDrawable, ElementSetDrawable, InteractionDrawable, InteractionSetDrawable sont aussi awares mais ils utilisent l'interface “observateur”.

Dans d'autres libs, ce type de pattern est poussé encore plus loin. Par exemple, dans VTK, il est possible de mettre des priorités d'appels parmi les observateurs ou même enregistrer un observateur pour écouter un type d'événement particulier (et pas les autres). Dans Qt, ce pattern se limite à tout ce qui n'est pas gérable avec le mécanisme signaux/slots (c'est-à-dire très peu de choses).

Si je me suis cassé la tête à écrire du code générique, c'est évidemment pour pouvoir le réutiliser. Il serait possible de remplacer le vieux code de DataCurve par ce système. On pourrait aussi imaginer d'utiliser ce code pour mettre à jour certains objets de calcul sans lier explicitement deux objets parfois très éloignés. Par exemple, certains appels à Metafor au milieu du code de calcul pourrait être remplacé par un évémenement que Metafor viendrait écouter si nécessaire.

Ce travail est également un très grand pas vers la visu de maillages dynamique (cas du remaillage par exemple, si j'ai un jour le temps de faire la thèse d'Antoine).

Nettoyage divers

Debug leaks

Activer l'option METAFOR_DEBUG_LEAKS

Voilà ce que ça donne sur le test apps.ale.testConv2D par exemple. Le texte suivant est affiché à la fin du test.

====================================
SUMMARY OF POSSIBLE LEAKS
====================================

        NAME                    REMAINING REFS
        BcInteraction              4
        GPointFieldApplicator      2
        Geometry                   2
        Group                      4
        MaterialSet                1
        Mesh                       4
        Node                     120
        Point                    562
        Properties                 3
        Side                     120
        Wire                     120
        non-VirtualObject          3

Dans ce cas-ci, j'ai l'impression que les maillages ALE ne sont pas (plus) détruits. Il reste donc du boulot…

On pourrait imaginer de sommer ces références non détruites et les mettre dans un TSC pour la batterie. C'est ce que je ferai prochainement.

Romain BOMAN 2010/12/20 09:47