Edito

Bienvenue à toi, noble visiteur.

Si tu t'attends à trouver ici des récits épiques passionnants, tu risques d'être déçu.
Si par contre tu n'as rien a faire de tes journées, peut-être ce blog t'aidera-t-il à écouler quelques secondes de ton temps.
Les sujets abordés ici peuvent être divers et variés, mais comme il n'y a qu'un seul rédacteur, il se pourrait que cela ne soit pas le cas.

Bon voyage :D

Mardi 21 Janvier 2014
Et les données encore
Résumons brièvement ce que j\'ai plus ou moins maladroitement tenté d\'expliquer lors de l\'épisode précédent…
  • Tout est donnée
  • Les données, c\'est l\'argent
  • Les données, c\'est le pouvoir
  • Bref, les données, c\'est la vie


Les données occupant un role si important dans nos vies — surtout lorsque l\'on sait que nos vies sont des données — que l\'on a naturellement cherché à trouver un moyen de gérer les données en informatique dès l\'apparition des premiers ordinateurs doués d\'une mémoire.

Nous avons donc inventé le principe de système de fichiers, celui-ci s\'inspirant grossièrement du modèle d\'une grosse armoire à tiroirs dans lesquels sont entreposés des dossiers suspendus, aussi appelés fichiers (parce qu\'ils contiennent des fiches).
Désirant nous aventurer plus loin que cette modeste avancée, nous avons également inventé des théories mathématiques liées au traitement des données, et, dès 1970, l\'algèbre relationnelle était née.

Tels la soupe primitive, nos cerveaux encore effervescents de toutes ces percées dans le domaine de l\'informatique, ont continué de persévérer, jusqu\'à produire la première abomination création permettant d\'exprimer la manipulation de données informatiquement.
1974. Le SQL était né. Si l\'on excepte l\'idée assez ridicule, surtout pour l\'époque, d\'avoir prévu un langage qui ne puisse s\'exprimer que par le texte (et uniquement par le texte) lisible et écrivable par des humains pour manipuler des données, ceci est une des fondations de notre monde moderne. (Ça et Ethernet, TCP/IP, et le World Wide Web :o )
<div class='lireSuite'><a href='blog.php?id=109&amp;i=154'>Lire la suite ...</a></div>
Posté à
23:40
 par GoldenCrystal - | Général
Jeudi 19 Décembre 2013
Parlons données
Les données, parlons-en… sérieusement.

Mettons les choses au clair tout de suite, nous ne parlerons pas ici des données que vous fournissez gracieusement à Facebook ou de celles que la NSA collecte généreusement à des fins d'archivage.

Non, ici, nous allons parler de la donnée au sens pur du terme.

Par exemple, 5.

Oui, voilà. 5, c'est une donnée. Pas très utile telle quelle toutefois.
Si 5 était le nombre de fois ou vous avez réussi à compter jusqu'à l'infini, déjà, ça serait plus intéressant : Cela nous apprendrait que la donnée est fausse, et que vous n'êtes qu'un vilain menteur.

Cela étant dit, vraie ou fausse, une donnée reste une donnée. Sa véracité en est une autre.

Au final une donnée, n'est rien d'autre qu'une valeur rattachée à un libellé. Nos lointains ancêtres ayant compris le problème, nous avons rapidement inventé des moyens de stocker les données afin de pallier les lacunes de notre mémoire…
<div class='lireSuite'><a href='blog.php?id=109&amp;i=153'>Lire la suite ...</a></div>
Posté à
23:26
 par GoldenCrystal - | Random Writings
Samedi 07 Décembre 2013
Bloquer les pubs avec un Raspberry Pi
Je pense que nous sommes assez nombreux à être dérangés par les publicités agressives qui détruisent notre expérience sur mobile, soit en nous empêchant de naviguer sur notre page (pubs plein écran), soit en nous redirigeant vers le store, ou même en tentant de nous faire avaler des téléchargements frauduleux. Les mobiles (surtout iOS) sont mal fournis en ce qui concerne le bloquage des publicités, et mieux à faire de leur batterie que de s'occuper des publicités.

Mais à la maison, il y a quelque chose que nous pouvons tous faire : Créer un proxy DNS qui bloquera les domaines publicitaires par une redirection sur localhost. Ainsi, notre cher appareil mobile, connecté à ce serveur DNS, se retrouvera dans l'incapacité d'afficher les publicités.

C'est quelque chose auquel je ne suis pas le premier à penser, mais ce n'est pas forcément la première chose qui nous vient à l'esprit lorsque l'on a un mini ordinateur connecté à internet entre les mains…
Mais le Raspberry Pi se colle merveilleusement à la tâche de bloquer les publicités sur un réseau domestique : Connexion Ethernet permanente, faible encombrement, consommation d'énergie minimale.

Bref, il ne tenait alors qu'à mettre le système en place. À la lecture des différentes informations, la tâche pouvait paraître somme toute assez compliquée, mais il n'en est rien.

On trouve différentes informations à ce sujet ça et là, mais il semble qu'à chaque fois la procédure n'y paraisse plus compliqué que nécessaire. En ce qui me concerne, j'ai choisi d'adopter une approche minimaliste (minimum d'efforts, maximum de bénéfices), et je vous propose ici la procédure de mise en place :

1. Tout d'abord, installez dnsmasq via apt-get.
sudo apt-get install dnsmasq
L'installeur devrait aussitôt démarrer le service dnsmasq. Mais celui-ci ne servira à ce moment que de cache DNS, ce qui est sans nul doute intéressant, mais pas encore suffisemment.

2. La configuration de dnsmasq se situe dans /etc/dnsmasq.conf. Ouvrez-la à l'aide de votre éditeur favori (j'utilise vim par habitude, mais vous y préfèrerez sans doute nano qui est installé par défaut sur le système)
sudo vim /etc/dnsmasq.conf
En ce qui nous concerne ici, nous ne voulons pas vraiment altérer la configuration en tant que telle, et nous contenterons d'ajouter un autre fichier de configuration spécifique au blocage de publicités.

3. Ajoutez cette ligne à la fin du fichier :
conf-file=/etc/dnsmasq.adblock.conf
Nous y placerons par la suite les règles de blocage des publicités.

4. Pour simplifier notre tâche, nous allons créer un petit script de mise à jour des règles.
Je me suis inspiré de celui proposé ici en le simplifiant quelque peu. :p
Si on le désirait, on pourrait résumer le script en deux lignes, et c'est pratiquement ce que l'on va faire ici, si on excepte la configuration.
Créez le fichier /usr/bin/adblock-update à l'aide de votre éditeur de texte favori :
sudo vim /usr/bin/adblock-update
Tapez-y ensuite ces quelques lignes :
#!/bin/sh

configfile=/etc/dnsmasq.adblock.conf
tmpfile=/tmp/dnsmasq.adblock.conf.new

redirectip='127.0.0.1'

args="hostformat=dnsmasq&showintro=0&mimetype=plaintext&useip=${redirectip}"
url="http://pgl.yoyo.org/adservers/serverlist.php?${args}"

reloadcmd="service dnsmasq restart"
wget=/usr/bin/wget

($wget -qO $tmpfile $url && mv -f $tmpfile $configfile && $reloadcmd) || rm -f $tmpfile

Petite explication: Le fournisseur de liste d'adresses propose déjà un format de fichier adapté à dnsmasq. Nous récupérons les données via wget, remplaçons le fichier de configuration par les nouvelles données, puis nous redémarrons le service. Les différents composants de la requête sont paramétrables si besoin :)

5. Ajoutez les droits d'exécution sur le script nouvellement créé, puis exécutez-le :
sudo chmod +x /etc/adblock-update
adblock-update


6. Pour être totalement complet, créez un job cron qui se chargera de mettre à jour les filtres périodiquement, et de manière automatique :
echo @daily update-adblock|sudo crontab -
Cela devrait mettre à jour la configuration automatiquement tous les jours à minuit.

7. N'oubliez pas de configurer vos appareils pour pointer vers ce DNS. ;)


Et voilà, les publicités seront à présent bloquées automatiquement pour tous les appareils qui pointeront leur recherches DNS sur le Raspberry Pi :)
Certains conseillent également de mettre en place "pixelserv" pour accélérer le chargement de certaines pages. J'avoue ne pas m'y être intéressé pour le moment vu que le fonctionnement actuel me convient, mais j'y reviendrai sans doute plus tard.
Posté à
18:53
 par GoldenCrystal - | Général
Dimanche 25 Aout 2013
J'ai toujours du mal avec les "design pattern" et autres trucs tordus…
Franchement, je ne comprends pas cette manie qu’ont beaucoup trop de développeurs de vouloir rendre complexe quelque chose de tout à fait simple.
Je voulais jeter un œil au code de .LESS¹, histoire de voir s’il y avait moyen de bosser dessus et de faire en sorte qu’il puisse parser la dernière version de Bootstrap sans soucis. Le projet ayant l’air de tourner au ralenti, je me suis dit que j’aurai sans doute pu apporter ma petite pierre à l’édifice.

Le projet est hébergé sur Git (bouh :( ) qui a l’air d’être très à la mode de nos jours. (Beaucoup trop à mon gout)
Mais heureusement, la dernière version de Visual Studio incorpore un support « Git pour les débiles profonds », ce qui correspond parfaitement à mes besoins, donc tout se passe bien. À l’ouverture du projet, tout fonctionne nickel… Mais ce fut de courte durée. Voilà déjà que la solution ne compile pas. Il manque des fichiers (AssemblyInfo.cs), et un innocent warning suggère qu’un truc pas très net s’opère dans les fichiers (MSBuild) du projet…

Ben non, voyez-vous, c’eût été trop beau. J’étais vraiment trop bête (y-a-t-il une limite à ma stupidité ?) de m’attendre à ce que la solution se compile en appuyant simplement sur un bouton dans Visual Studio, cela n’aurait sans doute pas été très Pro… #gol#
En fait, pour compiler la solution, il faut utiliser un sombre outilscript du nom de PSake. Apparemment c’est un truc hype qui fait la même chose que MSBuild mais différemment (basé sur PowerShell au lieu de fichiers xml), et en moins bien. Mais c’est vachement cool ! #triso#
Donc en gros juste pour le hype je vais aller me faire chier à apprendre à utiliser un outil pour faire quelque chose qui à la base ne nécessite aucun outil ? (Car en plus, cet outil ne fonctionne pas out-of-the-box, il faut taper une ligne de commande PowerShell à la con pour autoriser l’exécution -_-)
C’est bien la peine que Microsoft se soit emmerdé à coder MSBuild, qui malgé sa relative complexité (en réalité, je ne dirais pas que c’est complexe, mais juste assez mal documenté ), est incroyablement simple d’utilisation… Et surtout le standard de facto. Ça permet juste à des mecs visiblement très intelligents (mais pas encore assez) de coder un outil un peu plus compliqué juste pour le principe de le faire. Apparemment se compliquer la vie est une pratique à la mode.

Pas grave, en attendant je vais regarder un peu le code de cette librairie qui, à priori ne devrait pas être trop compliquée. (Oui, ça traite de CSS, mais ça ne nécessite pas pour autant une architecture incroyablement complexe). Quelle ne fut pas ma surprise en constatant le bordel présent dans le projet principal. Plein d’interfaces dans tous les sens, à ne plus quoi savoir en faire, du code totalement impossible à suivre… Mais oui mais oui, c’est de l’inversion de contrôle ! (IoC) #trioui#
Alors la je crois avoir atteint le summum du ridicule. J’ai beau parfaitement comprendre le concept de la chose; c’est vrai que dans certains cas c’est très pratique de rendre l’application modulaire en découplant les différents composants de l’application entre eux… Mais c’est une putain de librairie de parsing CSS ! Quelqu’un peut-il m’expliquer ce qui est passé par la tête complètement tordue de l’auteur pour avoir choisi de mettre de l’IoC partout dans son projet qui n'en nécessite pas un gramme ? :|
Qui plus est, ce n’est pas une des grosses librairie à la mode (je n’arrive pas à savoir si c’est un mal, ou un bien, d’avoir évité une de ces usines à gaz…), mais un truc obscur codé par celui qui l’a intégré au projet…

Parcourant un peu le code, je tombe sur la classe Logger… Pardon, l'interface ILogger, et après un peu de fouille, sur la classe Logger et ses semblables…
Encore un autre mécanisme totalement inutile, qui n'apporte rien de plus que ce que propose déjà Microsoft en mieux avec Trace et TraceListener
Ça a sans doute été le coup de grâce pour moi, à supposer que le reste n'ait pas déjà été suffisant…

Au final, le code est totalement illisible. Il y a plus de code pour cacher l'exécution du vrai code que de vrai code. À vrai dire je n'ai même pas encore réussi à localiser le vrai code. (Celui qui fait quelque chose de concret…)
L’utilisation d’interfaces de toutes part rend le flux d’exécution du code quasiment impossible à tracer, et la complexité du système de build m’ôte toute envie d’essayer d’aller plus loin…
Je ne suis pas con, avec quelques efforts je pourrais parfaitement comprendre le fonctionnement du code, en connaissance de ces éléments. Mais après le peu j’en aie vu, je n’ai juste même plus envie d’essayer. Je devrais alors apprendre à maîtriser tous ces outils tiers qui n’apportent concrètement rien. Cela n’en vaut pas la peine².

Me voilà un peu frustré³, mais surtout très déçu.

Je crois que j’aurai meilleur temps à recoder un concurrent plutôt que de m'attarder sur ce projet. Mais cela n'est pas sur la liste de mes projets, donc il est plus probable que j'attende que quelqu'un fasse tout le boulot dans un temps fini… Avec un peu d'espoir, cela pourrait toujours arriver.


En tout cas, il ne faut pas s'étonner que "personne" ne contribue à ce genre projets. S'ils passaient moins de temps à la branlette intellectuelle et plus de temps à rendre l'expérience de développement aussi simple que l'expérience d'utilisation, beaucoup de projets iraient dans doute beaucoup mieux.



¹ less c'est cool, et apparemment, c'est un peu à la mode dernièrement. Et .LESS fonctionne en .NET donc c'est mieux que SASS. :p
² C'est surtout que si je passais par là je risquerais de faire gicler beaucoup de lignes de code, mais un refactoring intégral ne serait sans doute pas très conforme à la politique de ceux qui gèrent le projet… #trivil#
³ À la base, mon but était juste d'ouvrir le projet pour voir si les modifications étaient dans mes cordes. Cela impliquait de localiser le vrai code et d'arriver à le compiler simplement. Chose qui s'est avérée impossible. Cela demande trop d'efforts pour peut-être me rendre compte par la suite que pour une raison x ou y, modifier ce code en particulier n'est pas dans mes cordes.
Posté à
16:35
 par GoldenCrystal - | Programmation
Vendredi 28 Juin 2013
Et on remet un peu de couleur…
Vous savez sans doute déjà ce que j'en pense, alors inutile de trop détailler…

Behold the new Visual Studio interface !

En gros, on améliore l'interface en la rendant plus proche de celle de la version précédente… #tritop#

(C'est bien… Enfin, c'est mieux, mais c'est ridicule d'en arriver là… -_-)
Posté à
19:37
 par GoldenCrystal - | Programmation
Mardi 28 Mai 2013
Rendu de texte avec DirectWrite pour WinRT… [2/2]
Étonnamment, le plus complexe dans l'utilisation du couple Direct2D/DirectWrite dans une application WinRT n'est pas l'API Direct2D/DirectWrite.
Bien évidemment, certaines spécificités de l'API sont un peu moins bien documentées, mais l'API est très simple d'utilisation, et la documentation est plus que suffisante. (Cela explique probablement le nombre assez resreint d'articles sur le sujet)
La dernière fois, nous nous étions arrêtés sur l'implémentation d'une classe de base gérant le rendu via VirtualSurfaceImageSource / IVirtualSurfaceImageSourceNative…

<div class='lireSuite'><a href='blog.php?id=109&amp;i=149'>Lire la suite ...</a></div>
Posté à
01:26
 par GoldenCrystal -
Lundi 20 Mai 2013
Ou pourquoi WinRT est un hack…
Dans mes méandres à travers les API WinRT, j'ai eu le malheur d'avoir eu besoin d'une fonctionnalité « intelligente » qui n'existe pas d'origine dans le Framework.

J’eus aimé, de manière élégante, pouvoir invoquer des méthodes d'instance sur un type X en fonction d'un paramètre Y. Bien évidemment, de la manière la plus performante qui soit, car ce code risque fort de se retrouver à tourner en arrière plan, et WinRT est très restrictif à ce niveau (1sec de temps CPU pour 2h, de mémoire).
Bien que cette fonctionnalité n'existe pas de manière tout à fait générique dans le framework .NET, cela reste assez facile à implémenter. Dans mon cas, je n'ai besoin que de pouvoir effectuer des appels de réflection et de créer un delegate ouvert…

Oui, mais voilà… !

C'était sans compter le framework .NET castré de WinRT ! Celui-là même qui est implémenté par dessus et à l’intérieur d'un framework .NET standard et parfaitement fonctionnel… :)

<div class='lireSuite'><a href='blog.php?id=109&amp;i=148'>Lire la suite ...</a></div>
Posté à
00:46
 par GoldenCrystal -
Jeudi 09 Mai 2013
Rendu de texte avec DirectWrite pour WinRT… [1/2]
Comme je le disais donc, pour remplacer le rendu de texte déficient de la plateforme XAML de Windows RT, nous avons à disposition des API plus avancées, que sont Direct2D et DirectWrite.

Conceptuellement, il est possible d'intégrer un rendu Direct3D ou Direct2D à peu près n'importe où dans une application XAML pour WinRT. (Donc une application « native », codée dans un des langages disponibles, à savoir C#, C++ ou VB.NET pour l'instant)
Passons donc brièvement en revue les trois façons qui sont à notre disposition pour mélanger ces technologies plutôt abouties dans nos interfaces modernes :
  • On peut intégrer de « petits » éléments sous forme d'image avec la classe SurfaceImageSource et son interface associée ISurfaceImageSourceNative. Le rendu se fera dans une surface DXGI native, et devra être effectué de manière synchrone avec le rendu de l'interface XAML lorsqu'une mise à jour sera nécessaire.

  • De manière assez similaire, on peut intégrer de « très grands » éléments sous forme d'image avec la classe VirtualSurfaceImageSource et son interface associée IVirtualSurfaceImageSourceNative. Le rendu suivra les mêmes contraintes que pour SurfaceImageSource, mais beaucoup plus de choses seront gérées automatiquement par l'interface.

  • Enfin, pour un rendu très avancé, beaucoup plus proche de ce qui se fait traditionnellement pour une application en plein écran, il existe SwapChainBackgroundPanel et, bien évidemment, son interface associée ISwapChainBackgroundPanelNative :) Avec cette interface, le rendu est libre, et non lié au rendu de l'interface XAML. Bref, c'est l'interface rêvée pour un jeu, ou tout autre type d'application nécessitant un rendu 2D/3D plein écran tout en offrant une interface XAML évoluée.

<div class='lireSuite'><a href='blog.php?id=109&amp;i=147'>Lire la suite ...</a></div>
Posté à
01:00
 par GoldenCrystal -
Lundi 29 Avril 2013
L'art du rendu du texte sous WinRT…
Ceux qui auront déjà eu l'occasion d'utiliser WPF savent sans doute à quel point le modèle de rendu du texte basé sur FlowDocument était puissant…
Nous aurions donc pu nous attendre à un modèle aussi évolué pour nos applications XAML WinRT, mais il n’en est rien.
Nous aurions pu également nous attendre à un modèle similaire à celui de Silverlight… C'eût été bien plus proche de la vérité, mais ce n’est pas encore exactement ça.

Vous ne vous en doutiez sans doute pas, mais le modèle de rendu du texte en XAML/WinRT est… Tout pourri ! -_-

Voyez vous, en Silverlight, il existe deux moyens d'afficher du texte. On peut utiliser TextBlock ou RichTextBlock. La différence entre les deux vient du type des éléments qui sont directement dontenus par le contrôle. TextBlock contiendra des éléments Inline, qui contiendront le texte, tandis que RichTextBlock contiendra des éléments Block, qui seront souvent des Paragraph contenant des éléments Inline. Jusque là, avec WinRT, c'est pareil… (Ce qui semble confirmer que WinRT/XAML est basé sur une version dénaturée de Silverlight)
En Silverlight, on peut définir l’essentiel des propriétés du texte sur le seul élément Run, ce qui rend les éléments Bold, Italic et Underline quelque peu superflus. (Mais pas complètement, car ceux-ci dérivent de Span. Ils contiennent donc plusieurs autres éléments Inline.)
Mais avec WinRT… Vous perdez l’élément Hyperlink. Vous perdez la propriété TextDecorations.
Bref, c’est la fête, quoi… Des fonctionnalités ont été coupées, sans raison logique.

Bien sûr, avec Silverlight, on ne peut pas appliquer de couleur d’arrière plan à une plage de texte, vous vous doutez donc bien qu’avec WinRT/XAML, on ne peut pas non plus ;)



Je me permet un petit aparté pour vous laisser comparer le niveau de la documentation Silverlight/.NET 4.5 avec la documentation « Windows APIs »
Cela laisse rêveur, n'est-ce pas ?



Pour résumer où nous en sommes pour l'instant, WPF avait un système de rendu de texte tellement évolué (je n'ai pas jugé utile de détailler ici) qui a servi de référence à ce qui a été fait pour Silverlight. (Bien que similaires sur de nombreux point, les deux API ont été développés séparément #triso# )
Et l'API de Silverlight a été plus ou moins repris au cœur de WinRT pour donner ce qu'on a aujourd’hui avec les applications « natives » (non HTML5/JS) pour Windows 8.

N'existe-t-il pas au moins un truc qui puisse afficher du texte de manière convenable là dedans ? Réfléchissons y bien… Oui, il y a un truc. Il y a WebView, autrement dit internet explorer…
Oui, internet explorer, c'est bien, mais c'est complètement overkill si vous voulez afficher quelques caractères avec des couleurs et des polices variées. En plus, il y a des problèmes de partage de surface de rendu à gérer… WebView sera toujours par dessus XAML donc il faut le masquer au bon moment et le remplacer par une image statique de lui-même…


À ce moment là, vous devriez commencer à comprendre que les applications de base de Microsoft sont toutes codées en HTML5/JavaScript, et que si vous voulez faire une application un peu évoluée, vous allez peut-être être contrait de coder dans ce HTML5/JS bâtard basé sur une partie des API WinRT… (Ça n'a pas grand chose à voir avec du HTML5/JS basique en réalité, il y a donc beaucoup d'apprentissage malgré tout)

Car oui, au moins, vous aurez un moteur de rendu digne de ce nom. Qui ne vous contraindra pas de manière arbitraire. Vous aurez avec vous la puissance des CSS. Sentez-vous comme moi que Microsoft a réellement envisagé, l'espace d'un instant, de totalement évincer le développement de vraies applications sur son système Windows 8 ? La qualité de la réalisation des API laisse fort à y penser. On est très loin du niveau habituel de Microsoft.

Quoi qu'il en soit, il était nécessaire de fournir une API native. Pour permettre aux développeurs de s'exprimer en C++ avec DirectX, il fallait que le système soit utilisable. C'est peut-être là où les API sont *potentiellement* intéressants. En se basant sur ce qui a été fait pour WPF mais pas pour Silverlight, Microsoft a permi de faire interagir le moteur XAML avec un rendu personnalisé DirectX.
Ne vous faites pas d'illusions à ce sujet, c'est quand même diablement compliqué à mettre en place, surtout quand on y combine la gestion d'erreurs « super informative » de WinRT/XAML. Mais c'est possible, et vous devriez vous en sortir en suivant à la lettre le quelques rares exemples qui existe.

D'ailleurs, voilà peut-être une solution pour supplanter le rendu de texte tout pourri de WinRT… Pourquoi ne pas utiliser DirectWrite comme le fait lui-même Internet Explorer… ?
Avec un peu d'aide de SharpDX, on peut s'en sortir en C#… Ça semble quand même un peu overkill pour un simple rendu de texte.

C'est là qu'on entre dans la partie intéressante qui est de réussir à créer un contrôle XAML avec un rendu Direct2D qui fonctionne de manière raisonnable. (Ne bouffe pas toute la mémoire et tout le CPU de la machine)

Et là, les API d'interopérabilité XAML/DirectX ont le mérite d'exister, mais là encore, c'est diablement complexe à mettre en place. Vous serez certainement obligé de coder vous-même une surcouche aux API pour pouvoir les utiliser correctement, car en l'état (de base), ils ne présentent aucun intérêt…

Je reviendrai sur les détails une prochaine fois, mais voilà encore un truc frustrant.

Oui, en fait, WinRT/XAML est frustrant. C'est exactement ça…
Posté à
02:23
 par GoldenCrystal - | Programmation
Dimanche 07 Avril 2013
J'ai testé pour vous… le développement d'applications WinRT (En C#)
Et bien, pour faire court, ça pue :D
Surprenant, n'est-ce pas ?

Peut-être faut-il commencer par le commencement, alors allons y.
(NB : Nous supposerons ici que l'on emploie un vrai langage de programmation, aussi je remercierai les développeurs HTML5/JS de dégager le plancher… (Nanmého :o ))

Tout d'abord, il est peut-être utile de savoir comment se présente pour le développeur une application WinRT :
Le choix du langage de développement (C++, C# ou VB.NET) est laissé au développeur pour son plus grand bonheur… (Ou pas ?)
Si vous avez un peu suivi l'actualité récente, vous serez au courant de la nouvelle fonctionnalité async/await pour C#5 et VB.NET (VB 11.0). Il faut savoir que tous les API WinRT ont été construits autour de ce concept d'opérations asynchrone.
Que ce soit pour lire un fichier ou envoyer des données sur un serveur, vous ne trouverez pas d'API synchrone pour effectuer la chose. C'est certainement une très bonne idée, mais heureusement que les modifications nécessaires ont été apportées aux langages C# et VB.NET… Si vous espérez coder en C++ par contre, ce ne sera pas le cas. Heureusement, les fonctionnalités de C++11 aideront un peu beaucoup, mais vous n'aurez pas cette fonctionnalité bien polie qu'est async/await, et vous devrez faire plus de choses à la main.

Quoi qu'il en soit, le point important ici est que vous vous retrouverez face à un nouvel API… Microsoft a fait son possible pour que cet API soit accessible à tous les langages de manière uniforme.
Au niveau de l'interface utilisateur, vous ne serez sans doute pas surpris d'apprendre que ce qui nous est présenté ressemble fort à une version bidouillée de Silverlight… L'interface est conçue en XAML et le code de l'application est exécuté dans le langage de votre choix.
Si vous avez déjà eu l'occasion d'utiliser un peu la technologie XAML (que ce soit via Silverlight ou WPF), vous devriez être un peu étonnés.
Câbler le XAML avec les objets d'un langage quelconque, ça a quelque chose de… Comment dire… Impressionnant ? Non, plutôt intriguant.
Tout cela est rendu possible grâce à un système mis au point par Microsoft, nommé "projections".
Concrètement, tout l'API WinRT est exposé dans un format bâtard qui ne correspond exactement à aucun langage. Sous le capot, vous serez surpris de retrouver des interfaces COM… Et des métadonnées .NET. Mais WinRT n'est pas du COM… enfin, pas complètement. Et WinRT n'est pas non plus du .NET… enfin, pas complètement.

WinRT a plus que certainement été conçu en C++, mais WinRT n'est pas adapté à être utilisé dans du C++, parce que WinRT ressemble beaucoup trop à du .NET.
Et comme WinRT redéfinit beaucoup d'API pré-existants en .NET à sa sauce, WinRT n'est pas directement adapté à être utilisé en .NET…
Côté C++, il a donc fallu développer des extensions au langage pour y intégrer WinRT. Certains trouverons peut-être que cela ressemble fort à du C++/CLI…
Côté .NET, il a fallu procéder à des gros travaux. Un bon nombre de types WinRT faisant directement doublon avec les types de la BCL, il a fallu mettre en place des conversions transparentes entre ces types équivalents. Pire encore, il a fallu masquer une bonne partie de l'API .NET, qui est basé sur le bon vieux Win32, pour n'exposer que des API WinRT-compliant. Par exemple, le ThreadPool de .NET passe à la trappe, et se fait remplacer par le ThreadPool WinRT; la quasi intégralité de System.IO est supprimée, des méthodes sont supprimées sur certains types.
C'est normal, me direz-vous, puisque le framework n'est pas le même. Que nenni ! Cette surcouche est bel et bien implémentée par dessus sur un Framework .NET version Desktop 100% fonctionnel… Hé oui… %)

Malgré tout, creusons un peu l'aspect des choses en .NET. Grâce au mot clé await, il est possible d'attendre n'importe quelle opération asynchrone. Mais avec WinRT, les opérations asynchrones retournent IAsyncOperation (& co.) plutôt que Task ou Task<TResult>.
Heureusement, on vient à notre secours avec des méthodes d'extension qui vont convertir ces objets en quelque chose que le compilateur peut supporter. Si le coût des opérations asynchrones pouvait rester "faible" avec les Task de .NET, autant dire qu'avec tous les niveaux de conversion pour travailler avec WinRT, il faut oublier toute notion de performance à ce niveau.

On pourrait également se tourner vers les interfaces IInputStream et IOutputStream de WinRT. Ces deux interfaces requièrent que vous leur fournissiez un IBuffer pour qu'elles puissent faire leur travail. Quézaco ?
IBuffer est l'interface WinRT (en fait, il y a beaucoup d'interfaces avec WinRT, cela vous rappellera sans doute COM…) qui représente un buffer. Mais encore ? Ah oui, cette interface ne sert à rien :)
La documentation dans sa grande clémence (j'y reviendrai) nous explique qu'il faut implémenter IBufferByteAccess pour que les choses fonctionnent correctement. Mais IBufferByteAccess n'existe pas en .NET.
C'est vrai quoi, ça serait beaucoup trop simple de permettre d'implémenter une interface pour pouvoir utiliser les API de Windows. Sans déconner.
Heureusement, là encore, il existe la classe WindowsRuntimeBuffer et une classe d'extensions nommée WindowsRuntimeBufferExtensions qui vous permettront de faire tout un tas de choses profondément inintéressantes en rapport avec des IBuffer. Celles-ci auront au moins le mérite de vous fournir un IBuffer à utiliser pour faire votre affaire.
Inutile de préciser que tout ce qui touche à l'interface IBuffer est d'une complexité sans nom pour effectuer un truc aussi con que de représenter un tableau d'octets de taille fixe… Oui, oui, vous avez bien lu, tableau d'octet de taille fixe…

Supposons que vous ayez un objet de type IInputStream, lisant des octets dans un fichier ou sur un socket. Vous voulez appeler la méthode ReadAsync pour qu'elle fasse son boulot.
Vous obtenez donc un buffer avec WindowsRuntimeBuffer.Create.
var buffer = WindowsRuntimeBuffer.Create(4096);
stream.ReadAsync(buffer, 4096, InputStreamOptions.None);
Aussitôt l'euphorie retombée, vous vous apercevrez que vous ne savez pas lire les données dans un IBuffer. #triso#
C'eût été trop beau…
C'est là que viennent à votre secours les extesions de WindowsRuntimeBufferExtensions. Toutes plus inefficaces les unes que les autres, vous pourrez utiliser une des méthodes de cette classe pour convertir votre buffer WinRT en quelque chose que vous pourrez utiliser, qui sera produit à l'aide une allocation mémoire et une copie de données.
Oui, vous m'avez bien lu.
Si vous ne comprenez pas, laissez moi étaler les choses plus clairement : Il est impossible d'écrire du code performant pour lire (ou écrire, en fait) des données provenant d'un flux…
Ce qui ce passerait idéalement :
var buffer = new byte[4096];
int count = await stream.ReadAsync(buffer, 4096);
for (int i = 0; i < count; i++)
DoSomething(buffer[i]);

Ce qui va se passer en réalité :
var buffer1 = new byte[4096];
int count = await stream.ReadAsync(buffer, 4096);
var buffer2 = new byte[4096]; // Allocation mémoire complètement inutile
Array.Copy(buffer1, buffer2, count); // Opération de copie complètement inutile
for (int i = 0; i < count; i++)
DoSomething(buffer2[i]);
Bon, voilà le schéma de principe. Il y a cependant un point sur lequel j'ai un peu menti. Il est possible d'éviter l'allocation mémoire inutile. En utilisant un MemoryStream, le IBuffer partagera le même tableau de byte[]. Cependant, avec WinRT, la méthode GetBuffer() de MemoryStream n'est pas exposée, il faudra s'en tenir aux méthodes Read ou ReadByte… #triso#
var bufferStream = new MemoryStream(BufferLength);
var runtimeBuffer = bufferStream.GetWindowsRuntimeBuffer();

Un petit détail n'aura, je l'espère, pas manqué de vous faire hérisser le poil… IBuffer utilise bel et bien un tableau (.NET) byte[] pour son stockage interne… Mais vous n'y avez pas accès #trinon#
Qui plus est, ce buffer est à l'état "pinned" et ne pourra pas être déplacé par le Garbage Collector…
Et vous ne pouvez pas réimplémenter IBuffer par vos propres moyens puisque toutes les interfaces nécessaires ne sont pas disponibles. (En théorie c'est possible, puisque le code unsafe est autorisé par WinRT, mais ça demande juste pas mal de boulot pour le faire correctement ;) )
Magnifique, n'est-ce pas ?

Et ce n'est là qu'une partie des choses qui pourraient aider votre crâne à se dégarnir prématurément.

Aussi, laissez moi continuer un peu; attaquons-nous cette fois-ci au cœur du combat, le XAML. Si vous avez déjà eu l'occasion de pratiquer un peu WPF et XAML, les choses vous seront très familières. Mais suffisamment différentes pour que vous n'y compreniez rien… #trioui#
Quoi qu'il en soit, les principes de base n'ont pas changé, c'est déjà ça. Vous déclamez votre interface sous forme de fichiers XAML, qui sont rattachés à un fichier code-behind dans le langage que vous aurez choisi.
Les composants sont sensiblement différents de ceux que vous connaissiez avec Silverlight ou WPF, et aussi sensiblement différents de ceux que vous pourriez trouver dans les applications natives de Microsoft telles que Mail, Messages, etc. On retrouve les bugs habituels de Silverlight/WPF, à savoir, le texte qui devient flou sans raison quand on fait défiler une liste, etc.
Il est bien évidemment impossible d'avoir une application aussi "jolie" que celles de Microsoft avec uniquement le thème par défaut. (Bizarre, n'est-ce pas ?)
Le soin apporté à la chose laisse à désirer, mais il est toutefois possible d'arriver à un résultat convenable avec une lutte acharnée.

Il faut savoir qu'avec la technologie WinRT/XAML, la moindre étrangeté présente dans le code aura vite fait de faire planter votre application avec un magnifique message d'erreur "xClassNotDerivedFromElement" ou pire encore, "Exception of type 'System.Exception' was thrown." #tritop#
Hé oui, car cela serait bien trop simple de vous en dire plus. Démerdez vous plutôt pour trouver d'où vient l'erreur :]

Attachons nous donc à l'étude de ces erreurs. La première erreur indique un dysfonctionnement dans le moteur XAML, probablement lié à un bug dans la gestion des classes. Ce bug peut notoirement se produire (100% du temps) si vous essayez de dériver d'une classe qui possède une interface XAML. Il faut croire que ce n'est pas pour rien que les classes sont sealed par défaut sans explication… #roll#
La seconde erreur par contre, c'est un peu la cerise sur la gâteau, ou plutôt la cacahuète à l'intérieur du M&M's, mais plus exactement, le caillou qui a pris la place de la cacahuète à l'intérieur du M&M's.
Voyez-vous, quoi qu'il se passe lors de l'initialisation de l'application et de la création de la page principale, la moindre erreur qui se produira sera instantanément absorbée dans le vide cosmique et il vous reviendra indéfiniment le même message sans queue ni tête. "Exception of type 'System.Exception' was thrown."
Mais encore ? Ben c'est tout, il y a une exception. Démerde toi donc! #triso#
Et Dieu sait que c'est simple de faire planter le moteur XAML de WinRT, diablement simple. (C'est peut-être un trait qu'il partage avec Silverlight, il me semble avoir déjà rencontré quelques difficultés du genre dans le passé)
Mais c'est surtout que ça serait déjà extrêmement simple si ce n'était que du XAML, mais ici, on y mélange du WinRT avec des projections d'API à profusion; en veux-tu en voilà.

Vous pourriez, par exemple tenter d'implémenter l'interface INotifyCollectionChanged pour façonner votre objet qui peut être lié à l'interface. Malheureusement pour vous, WinRT ne reconnaît pas cette interface qui était le standard en Silverlight/WPF.
Hé non, car WinRT veut utiliser… IObservableVector<T>. C'est presque la même chose, mais c'est pas pareil. Bien évidemment, le mécanisme de projection montre ici ses limites puisqu'il est incapable de vous permettre de faire du data binding sans devoir implémenter cette interface vous-même.
Vous vous lancez alors dans l'implémentation de IObservableVector<T> avec T le type qui vous intéresse… Tout va bien jusqu'à… jusqu'à… Ah oui, on ne vous avais pas dit, mais les événements WinRT ne sont pas compatibles avec les événements .NET.
Gare à vous si vous désirez implémenter l'interface de manière explicite, vous en perdriez votre latin.
Vous vous attendriez à devoir écrire quelque chose de ce genre :
private VectorChangedEventHandler<MyObject> VectorChanged;

event VectorChangedEventHandler<MyObject> IObservableVector<MyObject>.VectorChanged
{
add { VectorChanged += value; }
remove { VectorChanged -= value; }
}
Mais la réalité est tout autre. Ce que vous devrez écrire, le voici :
private EventRegistrationTokenTable<VectorChangedEventHandler<MyObject>> VectorChanged;

event VectorChangedEventHandler<MyObject> IObservableVector<MyObject>.VectorChanged
{
add { return EventRegistrationTokenTable<VectorChangedEventHandler<MyObject>>.GetOrCreateEventRegistrationTokenTable(ref VectorChanged).AddEventHandler(value); }
remove { EventRegistrationTokenTable<VectorChangedEventHandler<MyObject>>.GetOrCreateEventRegistrationTokenTable(ref VectorChanged).RemoveEventHandler(value); }
}
Bien évidemment, Visual Studio en sera tout confus et vous notifiera d'une erreur évidente de syntaxe, cela ne respectant pas la syntaxe C# standard… %)

Passons. À cet instant, vous êtes plutôt contents de vous-même, et vous désirez démarrer l'application.
Une instance de votre objet créée dans le constructeur de votre page principale…
Allez, faites un petit effort, et devinez…

"Exception of type 'System.Exception' was thrown." ! Et BAM !

Magie magie :)

Vous chercherez, mais vous ne trouverez pas.

Car, voyez vous, WinRT est bogué, et ne vous délivrera jamais l'exception.

Heureusement, en déplaçant le code fautif ailleurs, vous serez peut-être en mesure d'obtenir une exception plus utile… Faut-il encore y penser.
Dans ce cas précis, vous apprendriez que .NET net sait pas "projeter" vers WinRT votre type "MyObject" passé comme paramètre T. Non, ça ne marche pas si bien que ça. Ça marche même plutôt mal en fait.
En réalité, vous devriez implémenter IObservableVector<object> pour que cela fonctionne. Et effectivement, cela fonctionnera.
Mais normalement, vous n'auriez surtout rien du faire, et tout aurait marché comme sur des roulettes.
Il semble qu'un traitement spécifique soit apporté à ObservableCollection<T> pour que la collection fonctionne du premier coup avec le data-binding de WinRT, mais si vous voulez implémenter la collection vous-même, voilà à quoi vous vous heurterez…

Bien évidemment tout cela ne serait rien sans compter la qualité hors du commun de la documentation de MSDN sur les API WinRT. Si d'ordinaire, pour les composants standards de .NET ou de l'API Win32, la qualité de la documentation est d'un niveau très bon à excellent (moyennant les erreurs de documentation qui existent parfois), la documentation WinRT laisse tout bonnement à désirer. Hormis la mise en page Typique de MSDN, à présent dénuée de la moindre couleur ( #sick# ) et faisant bugguer l'historique de chrome, le contenu est digne de la documentation d'une classe java quelconque… À savoir, qu'il y a peut de chances que vous en appreniez plus sur la méthode que ce que son nom laissait entendre…
Autrement dit, vous avez de nouveaux API, dont vous ne connaissez pas le nom, de nouvelles fonctions qui s'utilisent de manière particulière, parfois de manière assez tordue, mais vous aurez tout le mal du monde à trouver le moindre exemple ou la moindre documentation vous indiquant comment vous y prendre.

Bien évidemment, ce ne sont que quelques exemples du pire, il y a aussi du meilleur, mais je suis certain de pouvoir trouver d'autres aberrations ci et là…
Posté à
20:14
 par GoldenCrystal -
Samedi 12 Mai 2012
Tout espoir n'est pas perdu…
Après s'être pris une quantité inimaginable de retours négatifs dans la figure, les développeurs de Visual Studio ont finalement revu leur copie… La couleur est de retour.

Ce n'est toujours pas franchement à mon gout, mais c'est quand même beaucoup moins moche que la première version qu'ils avaient proposé… À part pour la barre de menus.
L'interface est plus claire (le gris était vraiment abominable), et les icônes ont été recolorés en partie.

Même si (pour moi) ce n'est pas encore parfait, il devrait y avoir moyen de travailler avec ça.
Dans l'état des choses je pense qu'il y a peu de chances qu'il y ait de gros changements à présent, et il faudra de toutes façons s'en contenter…

En tout cas, nous avons échappé au pire.
Posté à
19:23
 par GoldenCrystal - | Programmation

 RSS  - ©yNBlogs 2004 - 120ms

Login : - Mot de passe :