Emporte Une Vache !!!

Aller au contenu | Aller au menu | Aller à la recherche

mercredi 19 septembre 2007

France Telecom, ou le service cher servi chaud (2)

Où en étais-je ? Oui, la téléphonite aigüe et purulente. J'ai tendance à perdre, à égarer facilement mon auditoire... Mon crachoir ? mon déversoir ? quelque chose avec un magnifique "-oir" phonétique qui se vulgarise par un "ouère"... mais voici mon habitude de l'insert qui s'instille entre les mots d'une introduction que je voulais didactique à l'usage d'un lecteur et ami fort désabusé qui s'est plaint vertement de mon entrée en matière imbitable... C'est que lorsque l'inspiration vient, et elle vient quand elle est la plus gênante : réunion, soutenance, ou lors d'une séance de pénétration d'huiles essentielle d'orange dans la peau d'un dos à la courbe généreuse, tâtillonne et exigeante... je me sens alors pris d'une loghorrée, sans papier, sans sac, sans balai à chiottes et surtout sans les médicaments (j'entends le souffleur, chauve et victime d'une infection urinaire, se gargariser sur la marque "Immodium" alors que je cherche le nom du remède, du principe actif, le Lopéramide, merci Google !), pour arrêter de vomir en spray des expressions alambiquées mises en exergue par une syntaxe ma foi fort pompeuse.

Voyez-vous ? Non ? Tant pis... Prêts pour la suite ?

Prenez donc un appartement. Emménagez gaiement un samedi avec votre colocataire masculin barbu et insouciant. Riez grassement dans votre moustache naissante quand l’agent en costume et en voiture familiale neuve vous raconte ses difficultés - d’entrepreneur en costume et en voiture familiale neuve – avec le service clientèle, ou technique (allez savoir) de l’entreprise susmentionnée de télégraphes – les bons vieux « PéTéTés » font tinter un carillon sensible, une nostalgie de l'acronyme – et autres plus modernes et vulgaires télécommunications analogiques et numériques, et vous conseille de raccrocher quand un conseiller FT vous amène sur une pente un peu raide. Jubilez quand vous pouvez voir ce nabab sortir les crocs par réflexe en repensant à ses déboires avec l’opérateur historique…

Faites l’état des lieux dans la plus grande minutie d’un bureaucrate Franco-Prussien « là il y a une rayure presque invisible sur la poignée d’entrée de la salle de bain… ah non pardon c’est un cheveu… NOTEZ-LE QUAND MÊME ». Profitez quelques minutes de la paix intérieure que vous apporte la remise d’une somme de 2000EUR en chèques épars à un caissier en costume et en voiture familiale neuve. Appréciez la chance qui a mis sur votre chemin un colocataire qui avance l'argent, topaze sur l'ongle... Ventrebleu, il ne mettrait jamais un rubis, une pierre rouge sur son ongle voyons, si précieuse soit-elle... Avec ces yeux bleus d'un bleu à vous glacer le sang bleu ! Laissez-vous envahir toutes ces considérations semi-comiques, semi-fuite-en-avant... Soûlez-vous de l’espace gigantesque à votre disposition pour roulez sur vous-même sur une moquette neuve (pour combien de temps...).

Et puis commencez, EDF. Ah non. Pas de réponse… France Télécom ? pas plus… un samedi, il faut peut-être s'armer de patience. Appelez vos amis : Joie ! Joie, Belle étincelle divine, Fille de l'Elysée... (Ah Beethov’…), et vantez-vous des grands espaces, la tranquillité… Comment ça, ils ont eu le téléphone en 20 minutes ? Et l’électricité aussi ? Courage, patience, retournons au fourneau : « votre temps d’attente est estimé à 10 minutes », ça veut dire « attendez 14 minutes, payez avec votre portable, nous raccrochons automatiquement ». On ne dit rien, on essaie encore, on persévère. On est encore deux à en rire. Deux jours après, toujours rien, pas faute d’appeler ! Ah, le mardi suivant, EDF vous accorde le droit d’avoir votre nom sur la facture. Trop aimables… Mais ça avance ! FREUD FREUD… vive la France et le téléphone ! Manque plus que le téléphone…

Maintenant vous pouvez commencer à rire saumâtre. Le samedi soir, sur internet de votre ancien logement, effectuez la commande du déménagement de votre ligne France Télécom vers votre nouveau logement. Donnez l’adresse exacte, appartement, escalier, couloir, circonférence de votre verge au pico-mètre près pendant le visionnement de votre scène préférée de C’est arrivé près de chez vous (moi c’est la scène où le déversoir à cadavre est asséché…). Il vous manque juste le fameux logo… Bah, la dernière fois, ils s’en sont passés… Mardi donc, une hôtesse vous contacte, vous demandant gracieusement de vous grouiller de lui filer le fameux logo parce qu’elle ne trouve pas l’appartement, la dame… Et je passe sur la fleur qu’elle m’a fait « je n’annule pas la commande mais je devrais »… vraiment, trop aimable… Et hop, une journée perdue…

Le lendemain, aux aurores (8h30 tout de même), problème suivant : c’est que « le logo n’existe pas à l’adresse demandée »… « Je ne vois pas ce que ça peut être Monsieur »… Vraiment pas… Votre appartement n’existe pas (ha ha me dis-je, en voila une théorie intéressante, devrais-je la soumettre à ma chère et excentrique professeur de philo d’antan… oui je suis encore à cette étape capable d’entretenir une causticité retenue, un humour jaunâtre de client juste « mécontent »).

Moi, intuitif et pratique, je lui souffle la réponse au problème : et si les anciens locataires étaient en dégroupage total… Surprise totale de l’autre côté du combiné : quelle idée saugrenue ! Je lui dis d’abandonner la commande, et, riant un peu, m’en vais causer à l’opérateur – désormais lui aussi historiquement connu pour la qualité de son service et la compétence humaine et technique de sa hot-line – Free.

Là, je vis un vrai cauchemar éveillé pendant 2 heures. Personne ne parle français plus loin que « bonne journée, monsieur au revoir » ; je me fais couper la parole quand j’articule une phrase plus de 2 questions ; elles (ce sont des « elles » je crois) répondent non à toutes les questions compliquées, refusent de m’indiquer la moindre piste… Un magnifique jeu d’ignorance. Merveilleux… J’en ressors époustouplifié, assommé par tant de vide, tant de haine du client, tant d'abstraction inhumaine… Mon esprit vient d’imploser de tant de frustration instantanée. Je me sens fatigué, d’un coup… "Finalement, FT c’est pas si mal on dirait…" Entre un mal et un pire, choisissons la voie où on peut au moins hurler sur quelqu’un…

On ne sait jamais, une soupape…

De retour à France Télécom, pour la suite

France Telecom, ou le service cher servi chaud

Aujourd’hui, pour la reprise, donnons dans le populo, et faisons preuve d’un peu d’empathie. Voici une histoire, la première ici, en plusieurs parties, parce que j'ai lu quelque part, après une diatribe aux contours larges et à la vigueur turgescente - entendez bien sentie - ces quelques mots, à mon adresse :

Il faudrait inventer le Touisteur précis et concis

Je ne comprenais pas jusque-là ces énergumènes excités et en général sanguins qui hurlaient au téléphone « MAIS VOUS ETES DES GROS CONS » ! Je les avais mis depuis longtemps dans une catégorie à part, ces braves qui rugissaient d’énervement dans un combiné bien innocent, à l’adresse d’une opératrice – hôtesse vocale ai-je entendu ? – choisie pour son incompétence et son incapacité à répondre à la question au demeurant simple : QUAND ? QUAND recevrai-je ma livraison ? QUAND me passerez-vous votre chef ? QUAND arrêteras-tu d'avoir des migraines le samedi soir ?

Par-dessus tout, je me pensais malin, supérieur, loin au dessus de la masse beuglante. Patient par timidité, éducation, et parce que je connais mon vocabulaire une fois que les 3 premières étincelles ont mis feu à une petite poche de frustration furibonde bien comprimée par un interlocuteur au cerveau confinant au chou de Bruxelles sans plomb, les flatulences en sus.

La patience donc, je m’en étais empli tout le mois d’Août, à l’approche des milliards de ronds de cuirs (entendez-le avec l’accent de Francis Lalanne) qu’allaient emplir de joie automnale ma paperasse maladroitement remplie de nouveau locataire, employé, jeune actif, cotisant à une mutuelle de riche et demandeur de cautions en tous genre… J’avais passé le cap des documents de location au prix de quelques douloureuses leçons : quand vos amis vous disent d’avoir les papiers prêts au cas où vous trouveriez un superbe appartement, ne riez-pas – gros malin ou niaise que vous êtes – en pensant – classique ! – que vous aurez le temps.

Que nenni ! Les agents immobiliers, ces nouveaux vecteurs du fascisme bureaucratique et libéraliste, n’ont qu’une parole de vent. Entendez que sans un chèque immédiat et une garantie d’une douzaine d’autres chèques à suivre, vous n’êtes pour eux que des éreinteurs de moquette, des parasites téléphoniques… Ils vous méprisent avec leurs petits sourires : ils s’amusent :

  • « ah, vous voulez être prêt d’une gare… » qui sonne comme un « feignasse, 20 minutes de marche, ça va te dessaler, gras du bide »…
  • « à 2 ? votre conjointe ? », le sourire complice et vendeur. Vous pensez au début qu'il tente une première touche de complicité masculine burnesque, la seule qu'ils connaissent. Je crois l'entendre mugir "mouiii" en se grattant l'entre-jambe quand je réalise que ses yeux me crachent « toi ? tu vas la garder quoi… 2 semaines ta grosse ? ».
  • « c’est peu… » (mon préféré) quand vous leur griffonnez votre salaire annuel brut, pourtant un chouïa au-dessus du salaire d’une femme de ménage… 3 fois plus, tout juste…

Regardez-donc son allure mercantile, le front lisse, la cravate légèrement desserrée, la mâchoire faiblarde crispée dans un grincement aigu de lèvres, ce qu'ils appelent le sourire vendeur n'est-ce pas ? Le pouvoir fortifie les zygomatiques.

Que j’aime que ces petits crétins tous frais sortis de je-ne-sais quelle école de commerce immobilier crachent sur le moindre défaut de votre candidature. On apprend vite la mendicité, au fil des agences de plus en plus miteuses, de moins en moins souriantes, trouvant votre de dossier de pis en pis… Mais passons… Notons juste : toujours être prêt, et je ne parle pas de sortir couvert, c’est votre affaire le mastic…

Une fois l’appartement en votre chère responsabilité (en bois ! votre compte est vide de toute façon...), l’électricité et le téléphone ne devraient être que de vulgaires formalités, avant de s’attaquer à l’animal sacré, le monstre pugnace, le chef-d’œuvre de l’échec des masses décérébrées devant la libéralisation des services… J’ai nommé – en grandes pompes… qui a dit dans le cul ? – le fournisseur internet.

Mais je vous arrête, une pause dans le récit. Car ici commence le fond de l’histoire. Quand vous pensez encore les difficultés surmontables. Avant tout, vous essayez de vous rassurer : il ne s’agit pas d’une vulgaire crise d’adolescence, mais à l’heure du tout numérique, où l’interweb est partout et ou les amours de bits passent allègrement dans les tuyaux du réseau (ai-je épuisé le stock de métaphores désastreuses quand à la technologie de l’information…), on compte encore une ribambelle de Schtroumpfs-à-lunettes dans le village planétaire (oups elle s’est échappée celle-là).

Ici commence le récit classique, qu’on voudrait toujours froid, mais où on ressent la solidification progressive du liquide cérébro-spinal, la monté des frissons, les débuts de grincements sous les restes d’émail que vous ont laissés cinq ans d’études – pardon… de remontées acides du sphincter aux molaires. Les premiers symptômes de la téléphonite purulente…

La suite bientôt...

lundi 6 novembre 2006

Touisteur au Caire

Retour sur Cairo

J’ai repris l’Ada, après 6 mois de travaux forcés en Java (il faut bien travailler pour son diplôme). En jetant un regard neuf sur mon travail en Ada, je me suis rendu compte que j’avais pris de mauvaises approches pour beaucoup de projets… J’ai donc décidé de reprendre mes activités sur :
  • Cairo-Ada et l’intégration GtkAda
  • Un générateur de binding OpenGL/Ada automatisé
  • Mon parseur iCalendar
Et je me suis laissé tenter par beaucoup d’idées que j’ai commencé à implémenter avec plus ou moins de succès : binding Qt4, générateur automatique de binding C/C++… Sujets d’autres posts.

Le progrès le plus important pour l’instant est au niveau de Cairo, et son intégration à GtkAda. A l’époque j’utilisais gtkcairo, un widget C trouvé dans l’arbre de sources de cairo… où l’on pouvait récupérer une surface Cairo et dessiner dessus. J’avais bindé ce widget comme indiqué dans la documentation de GtkAda et j’étais assez satisfait du résultat. Mais il était totalement non portable, et surtout impossible à compiler sous windows… Et non maintenu. C’était une impasse, mais je m’en satisfaisais.

L’autre solution, celle explicitée dans cet article dans le GNOME Journal est qu’en GTK+ 2.8 il suffit d’appeler gdk_cairo_create pour récupérer une surface Cairo et dessiner dessus à l’intérieur d’un widget… Mais GtkAda était lié à la version 2.4 de GTK+…

Du nouveau sur GtkAda !

Récemment, j’ai appris que GtkAda était passé à la version 2.8, et bindait désormais la version 2.8.* de GTK+. Un grand pas pour l’humanité. J’ai donc facilement bindé les fonctions gdk_cairo* dans un package Gtk.Cairo_Integration. Ainsi, on peut désormais reprendre l’article et implémenter sans problème la partie Cairo et au lieu d’appeler en C :

gdk_cairo_create()

On notifiera au début de notre paquetage qu’on veut utiliser le package Gtk.Cairo_Integration :

with Gtk.Cairo_Integration;

Et pour récupérer la surface (dans le handler de l’événement Expose), il nous faudra déclarer une constante (une variable fera aussi l’affaire) de type Gdk_Window et récupérer le Gdk_Window du widget courant (l’exemple est sur Gtk_Drawing_Area) :

Win : constant Gdk_Window : Gtk.Drawing_Area.Window(Widget);
Cr : Cairo.Cairo_Object;
begin
Cr := Gtk.Cairo_Integration.Cairo_Create(Win);
-- do your drawing stuff
-- ...
Cairo.Destroy(Cr);

Rien de bien compliqué, et aucun dépaysement pour les développeurs Cairo/GTK+ existants. La même chose, dans un vrai langage :-D. Vrai, c’est un peu verbeux, mais Gtk.Cairo comme nom de package entrait en conflit avec Cairo (tout court), le nom du package du binding Cairo...

Le package Cairo_Integration est un binding du fichier gdkcairo.h et toutes les fonctions s’y trouvant sont bindées. Je travaille encore pour intégrer tout cela à la chaîne de compilation de GtkAda, afin de produire un patch utilisable.

Le gros problème désormais reste de nettoyer le binding Cairo… Il reste beaucoup de fonctions mal ou pas bindées, et surtout toute l’API est en un seul package/fichier… difficile à maintenir, mais je réfléchis à un découpage similaire à celui de la documentation mais j’ai encore quelques soucis avec la gestion des types et des packages enfant... Une solution viendra peut-être.

Une fois ce découpage effectué et les fonctions bindées correctement (il manque le binding des fonctions concernant SVG et libsvg par exemple…), je vais faire un patch pour les sources de GtkAda (je ferais un checkout avant) et verrais bien si Act le prend =o).

Mon grand espoir est de parvenir à porter la fameuse horloge de MacSlow ou de produire un widget de qualité graphique comparable.

Six mois de cours^Wtorture (1/2)

Long Time No See

Je n'avais pas posté ici depuis 1/2 siècle , le moment est venu de recommencer un peu. J'ai entre temps brouillonné quelques articles plus ou moins intéressants et je ne vais pas les jeter. Mais avant de poster tout cela, parlons un peu de mon activité durant ces 6 derniers mois...


Mon stage s'est plutôt bien terminé, mon travail a été considéré comme très satisfaisant et ma connaissance des shaders et des technologies 3D a fait un bond conséquent, ainsi que mes compétences en matière de développement, de réflexion et de conception... Le chemin reste long bien sûr. Pour ne rien gâcher, j'ai été très bien noté et rémunéré. Un très, très bonne expérience donc, et cerise sur le gâteau, en Ada...

Je m'étais promis de continuer le développement des projets que j'avais commencés en entreprise et personnellement en Ada : un binding OpenGL et un binding Cairo/GTK+. Le second recevra les honneurs de plusieurs articles très bientôt (le temps de la mise en page) et le premier un peu plus tard. Malheureusement, comme d'habitude mon enthousiasme a été quelque peu écrasé sous la masse de travail des études qui ont repris. J'ai rapidement mis de côté le plaisir du développement Ada personnel pour la "joie" du développement Java forcé.


Parce que voila, le dernier langage pour la pédagogie et pour simplifier les corrections d'exercices, c'est Java. Le thème global des trois projets Java à rendre était cependant toujours frais dans ma tête : Graphisme et Visualisation d'Information étaient à base d'OpenGL. L'un était un exercice de modélisation du campus de la fac' où j'étudie, et les deux autres consistaient en deux applications/composants de visualisation d'informations.

Je vais me contenter de parler du projet de Graphique, et continuerai au prochain article sur la Visu...

Le projet Graphique

La consigne était de modéliser un minimum de bâtiments de mon campus, les voies de circulation, des voitures pour s'y déplacer, un ciel et un sol, et des buttes à l'aide de courbes de béziers, une caméra qui va bien et quelques optimisations (graphe de scène...). Jusque-là, rien de bien pénible ou de surprenant. Le hic, c'est qu'il fallait utiliser Java pour s'interfacer avec OpenGL, via le désormais fameux JOGL. Ce dernier est une usine à gaz et a rendu le développement de ce projet extrêmement pénible et laborieux. La lenteur, la complexité induite par Java/Swing par rapport à une application Ada ou C++ correspondante a rendu le travail sur ce projet une corvée. Pour ma part j'en ai effectué le moins possible graphiquement, me contentant d'aider mes trois courageux (http://blog.gmo-web.info/) binômes (http://jbamassy.blogspot.com) dans leur quête vers la compréhension d'OpenGL et des petites absurdités, incompatibilités, incohérences quotidiennes...

Je m'étais affecté aux tâches de gestion de caméra et de la partie optimisation.

La caméra

J'ai mis un temps fou à créer une caméra qui au final ne fonctionnait pas correctement, mais permettait de se déplacer simplement dans la scène. Dans la recherche du Graal de la caméra j'ai découvert les joies de la gestion de la pile de matrice OpenGL, et ai beaucoup joué avec pour obtenir des mouvements et transformations de façon plus intuitives et pratiques que les transformations classiques. Ainsi, au lieu de reprendre un code de quaternions que je ne comprenais qu'à moitié, j'ai préféré implémenter une caméra un peu originale. Au final, elle était plus que compliquée à réutiliser et absolument inmaintenable, mais ce que j'ai appris ici m'a beaucoup servi pour la phase optimisation.

L'idée était qu'au lieu de donner (position + 3 angles d'Euler) ou un quaternion pour décrire la position et direction de la caméra, j'ai utilisé le contexte courant et appliquait mes transformations directement sur la matrice de caméra courante. Pour ceux qui l'ignorent, dans OpenGL quand on applique une transformation (glRotate, glTranslate, etc.) celle-ci est considérée comme la première transformation effectuée, à l'origine... Donc si vous vous éloignez de l'origine et que vous appliquez une rotation ensuite, OpenGL va d'abord faire la rotation, puis la translation. Pour un débutant en Graphique c'est parfois rebutant, mais j'ai l'habitude depuis le temps.

Le problème est que je souhaitais que la transformation soit effectuée à partir de l'endroit et de l'orientation où se trouvait la caméra. Je voulais l'opération habituelle dans le sens opposé (la multiplication de matrices n'est pas commutative). Après bien des batailles contre le systèmes de matrices d'OpenGL (que j'ai quasiment toutes perdues), j'ai découvert par exemple que les matrices y sont stockées dans le sens différent du sens commun (en maths (en france)): en colonnes/lignes... Ensuite j'ai du appliquer mes magnifiques capacités de calcul et de repérage dans l'espace pour rater complètement toutes les transformations que je tentais, jusqu'à ce que me vienne l'idée (bien tard) de m'imaginer la caméra comme un objet, un point... J'ai fini par trouver des solutions, à grands coups de glLoadMatrix, glMultMatrix, glGetfv()... Bien sûr, Java/JOGL n'aidait pas dans ce capharnaüm, avec sa grande verbosité et son abstraction trop poussée. Et dire qu'un des "grands" arguments contre Ada est sa verbosité...

Les premières implémentations avaient des effets de bords désastreux, car personne dans le projet n'utilisait les glPushMatrix() glPopMatrix() avant de faire joujou avec la transformation courante... Et ensuite je me suis redécouvert un très vieux problème que j'avais rencontré quand j'avais développé à partir de zéro une toute petite bibliothèque de rendu 2D/3D logicielle pour de la stéréoscopie : la précision des nombres à virgule flottante. Usant et abusant des glMultMatrix(), l'erreur ou l'imprécision de chaque opération se répercutait extrêmement vite, en particulier lors des rotations. On voyait progressivement mais très vite l'horizon se pencher alors qu'il s'agissait d'une rotation dans le plan de l'horizon. Le passage à des calculs en précision double a un peu amélioré la situation. Et j'ai laissé le tout tel quel, en priant pour que l'examinateur ne s'en rende pas compte.

Au final je ne suis pas du tout satisfait de ce code, horrible, mais ce qui comptait c'était qu'il fonctionne, pour que je puisse me consacrer à la partie vraiment, vraiment intéressante du projet et qui n'avait plus besoin d'approcher JOGL et consistait majoritairement en de l'algorithmique et de ce fameux number crunching (gros calculs brutaux) dont Java se dit capable de rivaliser avec le C aujourd'hui.

Quatre pommes

Lors de ma soutenance de stage, lorsque j'ai présenté mon travail sur OpenGL et la recherche de performances maximales, via Pixel Buffer Objects, des mécanismes utilisant des textures rectangles, des FrameBuffer Objects pour l'écriture texture-to-texture... Un professeur dans le jury m'a demandé si j'avais recherché des optimisations de plus haut niveau, algorithmiques, en particulier dans le domaine du partitionnement de l'espace (Kd-Tree et autres friandises). Etant un ignare total dans le domaine, j'ai regretté de ne pas m'être penché plus tôt sur ce genre d'idées. Il me fallait corriger mon ignorance au plus tôt.

Je cherchais donc via ce projet à implémenter un algorithme intéressant permettant de réduire le nombre d'objets à afficher dans une scène. On avait survolé rapidement les BSP en cours et je voyais poindre la lourde, peu originale et surtout peu adaptée implémentation basique d'un tel engin... En recherchant d'autres solutions, j'ai découvert les Oct-tree et les Quad-tree. En résumé, il s'agit d'algorithmes très simples de découpage récursifs de l'espace. Ceux-ci sont beaucoup plus adaptés à la modélisation de bâtiments, car leur forme "carrée" simplifie énormément les calculs et leur structure rigide y rend la recherche extrêmement efficace.


L'idée était de gérer le frustum-culling avec un algorithme de détection de collision via un quadtree. Le frustum était projeté sur le sol (ses 6 faces l'étaient), et on utilisait ces quadrilatères pour vérifier la collision avec d'autres objets présents dans la scène.

Le problème premier et pénible était de récupérer le frustum, c'est à dire les coordonnées de ses 8 sommets. Il fallait faire ça à partir de la matrice de caméra. Heureusement j'avais déjà dépensé beaucoup de temps de cerveau à jouer avec les matrices et j'ai rapidement trouvé comment récupérer la position et l'orientation de la caméra, pour ensuite récupérer les 8 sommets à coup de géométrie simplette =oD.

Ensuite et enfin (j'aime garder le plus agréable pour la fin), j'ai implémenté l'algorithme de quadtree en 2 journées (de 22h) et ai optimisé la recherche ainsi que l'occupation mémoire comme j'ai pu, et ai fini de le débugger un autre soir. C'était vraiment agréable d'enfin développer quelque chose qui soit simple, relativement élégant dans le principe, sans la lourdeur pénible des abstractions d'interface graphique... Et surtout de pouvoir tester cet outil directement et de façon interactive avec une petite application Java2D (temps de développement compris dans l'implémentation de l'algorithme :-)) qui a plus tard été intégrée à l'interface finale. Elle sert de radar pour montrer quels objets statiques sont présents dans la scène et montre les frustum et les objets qu'il contient ou coupe, et donc les objets qui sont dessinés et ceux qui ne le sont pas. On visualise le résultat de l'algorithme d'optimisation, à défaut de pouvoir le constater.

En effet, les trois quarts de fonction géométriques que j'ai utilisées, je les ai recodées à la main, à partir de formules pas optimisées du tout. La recherche dans un cas bouclait infiniment et je n'avais pas réussi à reproduire cet Heisenbug. Quelques autres erreurs de conceptions ralentissaient encore ce code, mais priorité a été donnée au bouclage du projet. L'optimisation ralentissait en fait l'application :-D. Etant donnée la complexité de l'algorithme il aurait fallu avoir un nombre conséquent d'objets pour y trouver son compte :-).

Bile-an

Au final, ce projet étalé sur 2 mois m'aura rappelé que j'aime toujours si peu le Java, et que seul Eclipse qui m'a maintes fois sauvé de la dépression, en fait un langage de travail passable. J'aurai tout de même découvert beaucoup d'éléments intéressants, fait beaucoup (beaucoup !) d'erreurs, et donc appris énormément mais que le rapport :
Apprentissage / PITA
était proche de 0.


Ce projet nous a quand même valu la meilleure note de la promo... comme quoi...


Python : first sight

Cela fait presque une semaine maintenant que je travaille sur un binding OpenGL avec les derniers drivers nVidia.

Jusque-là je travaillais sur d’anciens headers datant de 2003, qui me donnaient entière satisfaction, car j’ignorais l’avancée récente des technologies graphiques. Avec la découverte de gl_framebuffer_object et gl_pixel_buffer_object, et autres sucreries, il m’a fallu me remettre en cause.

Un binding OpenGL ?

En C pour travailler avec OpenGL il « suffit » de faire #include et à la rigueur la même chose pour le header de glut quand on travaille avec Glut.

Les choses ses corsent quand on veut faire la même chose en Ada. On ne peut pas faire #include . On ne peut pas appeler une fonction C sans au préalable l’avoir déclarée, avec les types corrects et avoir déclaré qu’il s’agissait d’une fonction importée d’un autre langage…

En gros, si on a une fonction dans une DLL (j’ignore si ça marche aussi avec une bibliothèque statique) il faut procéder ainsi :
  • Supposons qu’en C on ait la fonction :
unsigned char cEstCoolTaVie(int genre, float crari);
  • En Ada on déclarera (si on le fait à la main) :
function C_Est_Cool_Ta_Vie(Genre : Integer ; Float : Crari)
return Interfaces.C.unsigned_char;
  • Il faudra ensuite écrire dans le source Ada
Pragma Import (C, C_Est_Cool_Ta_Vie, "cEstCoolTaVie");


A propos de la taille du code (le double de lignes ici) : Ada est un langage plus verbeux, c’est sûr. Mais en général, comme on a moins de vérifications à ajouter dans le code en permanence – beaucoup sont faites par défaut par le langage – le code est souvent plus court et concis.

A propos de la notation, qui est critiquable (majuscule ET underscore ?) : c’est une convention de style du langage ou du compilateur. On est pas obligé de la suivre (la casse n’a aucune importance en Ada), mais la plupart des développeurs Ada y sont habitués, et les IDE Ada font le passage en majuscule automatiquement. On peut aussi utiliser gnatpp (pp pour pretty print), outil en ligne de commande assez configurable.

Les problèmes

Bien, maintenant si vous voulez regarder un instant un header glext.h sur lequel je travaille en ce moment.

Il fait plus de 5000 lignes et c’est un header C, avec les sympathiques instructions au préprocesseur pour définir des constantes et garder du code ou pas… Vraiment du code comme je l’aime : efficace - cà ! en performance c’est sûr… -, et compréhensible.


Ce qu’on peut voir c’est que « globalement », on a 3 parties intéressantes dans chaque header gl.h et glext.h :
  • des redéfinitions de types C (typedef), préfixés en GL, collé. Par exemple : GLint, GLuint, GLubyte, GLfloat…
  • des définitions de constantes « en dur » à l’aide de #define. Cela veut dire qu’en C ou en C++, à la précompilation le nom des constantes qu’on aurait pu insérer dans notre code sera remplacé « textuellement » par la valeur définie. Les constantes ont pour charte d’être entièrement en majuscules et les mots sont séparés par des caractères underscore ‘_’. Par exemple : GL_TRUE, GL_FALSE, GL_STREAM_DRAW.
  • des fonctions. Préfixées en gl (minuscule) et ensuite avec un style « dromadaire ». Par exemple : glDrawBuffers, glCreateShaderProgram.

Si on suppose qu’on veut séparer les fonctions OpenGL de base des extensions, on se retrouve avec 4 catégories d’éléments.

Mon job cette semaine, après avoir analysé et tergiversé sur les fonctionnalités récentes que j’allais utiliser pour multiplier la vitesse de l’appli OpenGL sur laquelle je travaille, c’est de transformer tout ce fatras de headers C de façon à pouvoir utiliser OpenGL en Ada, y compris les dernières extensions. Et, bien sûr il faut que l’expérience soit reproductible : les headers changent en fonction des constructeurs et des versions et des extensions…

Il faut donc que le processus de génération du binding soit automatisé au maximum.


Première étape : le gros outil pas terrible

Pour écrire un binding vers du C en Ada, en général on se pédale les signatures de fonction à la main, ainsi que les pragma import.

Mais ici, vu la taille du header, même pas la peine d’y penser. Alors j’ai cherché s’il existait des solutions, si possible « éprouvées ». J’étais très enthousiaste, car mon tuteur m’avait dit que le header qu’il m’avait passé, et dont je me servais depuis un mois, et qui fonctionnait très bien à quelques retouches près, avait été généré avec un « logiciel » appelé c2ada.

Mon enthousiasme s’est vite dégonflé. Le makefile de base, pour compiler c2ada, est assez mal fait et il faut un peu mettre la main au cambouis. Ensuite une fois qu’on a son exécutable – non sans des dizaines de warning à la compilation et même à l’édition de liens – il faut encore bidouiller $PYTHONPATH pour arriver à le lancer pour la première fois. J’ai essayé chez moi sous Windows, c’est encore pire… Bon, un après-midi perdu comme ça…

Le résultat fourni par c2ada est plutôt décevant. D’abord il lui faut inclure toutes les dépendances et donc en générer des sources Ada. Ainsi, glext.h faisant référence à des variables et types définis dans gl.h, il faut faire un petit script pour ajouter #include "gl.h" au début du fichier.

Les fonctions dans le header C sont déclarées (avec des APIENTRYP WINGDI et GLAPI…), puis plus tard dans le fichier on trouve leur signature. Bien sûr, c2ada ne retrouve pas ça tout seul. A priori, on dirait presque qu’il traduit ligne par ligne. Il faut donc encore un script pour retrouver les correspondances et virer les APIENTRYP et autres joyeusetés dédiées au préprocesseur, dont on a rien à faire en Ada.

Résultat, après avoir bataillé sec, on se retrouve avec plusieurs fichiers Ada, même pas compilables et bien sales.

Il faut donc se contenter du résultat. Bon en réalité je résume, parce que j'ai essayé au maximum d'utiliser les fonctionnalités proposées par c2ada, pour limiter la casse.

Mais encore une fois, il va être nécessaire de passer un script, mais sur du code Ada cette fois-ci.


Deuxième étape : l’outil puissant

En partant de ce code Ada tout pourri généré par c2ada, il me faut arriver à 4 « beaux » paquetages, contenant chacun les éléments qu’il faut.

Il faut aussi que soit respectée la Convention_De_Nommage_Ada, ce qui met en conflit les types, les fonctions, et les constantes, très proches "graphiquement". D’où l’intérêt des paquetages séparés.

Bien sûr les types ne sont pas convertis comme il faut par défaut. Il faut virer la dépendance à stddef.h et changer les ptrdiff_t pour ce que ça peut représenter… Les types contenus dans gl.h et glext.h peuvent se recouvrir, il faut les fusionner pour ne pas avoir de déclaration en double.


J’en passe et des meilleures...

Alors je me lance dans l’écriture d’un script Python pour faire tout ça. Oui, Python. En général je n’aime pas trop les langages de script. Pas typés statiquement, trop "je code à l’arrache et on verra" (mais on ne voit jamais en fait) et lents.

Mais la sagesse populaire dit : chaque langage a son utilité. Ou plutôt chaque type de langage a son champ d’utilité.

Or, pour ce que j’ai à faire j’avais besoin :
  • d’un bon système pour détecter les expressions régulières
  • de pouvoir faire relire le code =o)
  • de pouvoir coder assez vite sans avoir besoin de la vérification apportée par le typage
  • de fonctions de traitement de chaînes de caractères et d’entrées-sorties, simples et directes
Alors je suis parti d’un script qu’avait déjà commencé à coder mon collègue pour « Adaifier » les fonctions… J’avais sous la main le bouquin « Introduction à Python » et l’aide en ligne Python. Et j’avais cet exemple de code qui faisait la majorité de ce que j’aurais à faire :
  • compilation d’une regex
  • parcours du fichier source
  • match de la regex
  • reformatage ou autre
Passée la première phase de bidouille, j'ai très vite et très facilement compris comment ça foncitonne. Du coup en une journée j'adapté mes regex à mon code, fait des expressions « récursives » - terme bien pompeux par rapport à la réalité : il s’agissait juste de matcher des expressions dans des expressions dans des expressions, en appelant successivement des regex différentes… - testé, recommencé, ajouté encore des regex, encore des conditions, encore des fonctionnalités. On est loin des grammaires...

Ca allait très vite et j’ai pris plaisir à coder aussi simplement. Tout ce dont j’avais besoin était sous la main : liste, map, expressions régulières, traitement de chaînes flemmard-friendly, fichiers, et je pouvais très vite tester, regarder, modifier, tester, regarder, modifier…

Encore avant hier, j’étais un peu effrayé par la simplicité apparente du langage, alors j’avais vaguement lu quelques notions de syntaxe Python et c’est tout. Voyant les codes bizarres que mes camarades pythonistes postaient de temps en temps sur IRC (la vraie vie), je me disais qu’en fait il s’agissait plus d'un perl bis/beurkque d'un « bon langage simple ». Je m’étais trompé. Une fois de plus ça m’apprendra à penser/supposer sans tester.

J’avais déjà fait du « script » assez longtemps et pensais avoir fait le tour. Franchement vbs (Microsoft ASP) et vba (Microsoft Office) et javascript (dans les DOM HTML et SVG) étaient vite devenus pour moi des boulets plutôt que des outils appréciables qui auraient du faire gagner du temps, avec lesquels je n’ai que rarement apprécié coder. Et encore Javascript restait *relativement* intéressant parce qu’on pouvait manipuler le DOM SVG assez facilement.

Alors qu’en Python, j’ai l’impression que tout est simple, déjà là. Au point même que j’avais du mal à m’enlever de la tête la question suivante : « à part pour les applications de performances très très pointues ou encore pour des applications sûres, à quoi peuvent servir les autres langages après Python ? ». Peut-être qu’on fait trop de développement « simples » en C ou C++ juste « parce que ».

Le même argument vaut pour Ada ou Eiffel : j’ai l’impression que peu de décideurs et de développeurs se posent la question « le bon outil pour le bon job ». Je connais peu C++ mais est-on obligé de l’utiliser PARTOUT ? Si je veux écrire un logiciel de façon ultra-structurée, sûre (éviter trop d’overflow) ; passer mon temps à coder (après la phase de conception bien sûr) plutôt qu’à débugger ; avoir immédiatement le multi-tâches, des moniteurs en 3 lignes de code, des objets protégés… Gérer la mémoire finement via Storage Pool et ne pas trop m’inquiéter pour les fuites mémoire… Si je veux tout ça, je me tournerai vers Ada.

Si je veux de l’ouverture, pouvoir utiliser toutes les bibliothèques C++ du marché, organiser mon code un peu comme je veux... J’utiliserai C++.
Peut-être qu’en avançant plus dans le Stroustrup, d’autres arguments de choix me viendront…

En tout cas, l'argument "je n'arrive pas à recruter des programmeurs Ada qualifiés" est franchement fallacieux. L'apprentissage d'Ada est très rapide. En 2 semaines on est formé à l'essentiel. Et ensuite, des revues de code, quelques petits projets simples proches du sujet du travail. En général c'est plus que suffisant. Ada et Eiffel sont, par leurs contraintes et la qualité de leurs compilateurs, des langages qui s'apprennent presque "tout seul". En tout cas, très rapidement.

A quand une front/backend Swig pour Ada, ou encore un binding maison pour intégrer Python dans une application Ada ? Je vais regarder du côté de GPS.

Conclusion : une très bonne expérience

Ainsi, à la fin de cette journée, il me reste une impression de grand plaisir à coder, comme après une bonne journée de codage Ada.

Le script n’est pas fini, il fait déjà 400 lignes et fait déjà énormément de travail. Je l’ai étendu avec plein de regex (expressions régulières), et des conditions des plus en plus compliquées, et ça fonctionne encore sans que mon cerveau n’explose ou que je ressente le besoin de « partitionner » ou ranger le code (je commente bien sûr).

Seule remarque : malgré tout je trouve que l’indentation pour les blocs, même si c’est une idée intéressante, c’est PITA =o).

En deux jours j’ai réussi à améliorer/nettoyer mon binding généré de 90%. J’en suis même au point que le code généré compile sans même un warning.

Comme on dit par chez moi :
YaY !
et non pas LOLJesus ou encore LMAOZedong...