IKImageView and kCGErrorIllegalArgument
RAAAHHH !!! Putain de SDK de con ! Bon, belle entrée en matière pour un post qui ne servira probablement qu’à ma petite mémoire défaillante, mais bon, si jamais un jour quelqu’un d’aussi tordu que moi rencontre le même problème, au moins Google devrait lui renvoyer cet article où il y trouvera son bonheur :) (enfin, j’espère !)
Le problème : Vous avez une application qui utilise une IKImageView pour afficher des images, les manipuler, etc. Cet IKImageView, vous l’avez overridé pour lui rajouter quelques fonctionnalités, comme par exemple la possibilité de passer en plein écran. Et là, c’est le drame ! Votre IKImageView marche bien quand il n’est pas en plein écran, mais dès que vous passez en fullscreen, paf, écran blanc uni, avec les laconiques messages d’erreur suivants dans votre log :
<Error>: kCGErrorIllegalArgument: CGSGetSurfaceBounds
<Error>: kCGErrorFailure: Set a breakpoint @ CGErrorBreakpoint()
to catch errors as they are logged.
Hum … petite recherche sur le net, et là, pfff, aucune info (en tout cas à l’heure d’écrire ces lignes) En tout cas, aucun ressemblant de près ou de loin à mon setup.
Solution : Dans mon cas, j’avais un IBoutlet nommé window. J’utilise cet outlet pour faire de mon ImageView le first responder, lorsque je passe en plein écran (ça me permet d’être sur que mon ImageView récupère bien les évènements clavier / souris en fullscreen au lieu d’un autre élément de mon appli en background) Et c’est précisément cet outlet à la con qui posait problème ! Visiblement, IKImageView utilise en interne un window, qui ne correspond pas à celui que moi j’avais setté. Du coup lorsuq’il passait en fullscreen, bah gros problème … Et comme ça break pas, impossible de débugger. Sans compter que le “Set a breakpoint …” j’ai pas réussit à le faire marcher … vive le message d’erreur utile.
Bref, pour conclure, si vous créez une classe héritant de IKImageView, bannissez window de vos noms de variable. Pour ma part, j’utilise myWindow à la place, et je n’ai plus aucun bug !
Image Viewer v0.4
English will follow
Petite mise à jour de ImageViewer sur MacOSX :
- Correction d’un bug aléatoire qui faisait que la lecture des .gif animés ne marchait pas.
- Ajout d’une fonction de slide show, configurable via les préférences.
Prochaine mise à jour : J’aimerais ajouter un système permettant à l’ImageViewer de se mettre à jour lorsque le contenu change (par exemple si on supprime ou ajoute une image / un répertoire via le Finder, ImageViewer devrait se mettre automatiquement à jour)
——
Litle update to the MacOSX ImageViewer :
- Fixed a bug that was breaking animated gif’s playback.
- Added a slideshow function that you can configure through the preferences panel.
Next release : I want to make it update on file system change (if you add / remove an image via the Finder, the ImageViewer should update itself automatically)
Le code source / The source code : ImageViewer.v0.4
vidz
New York et Lúnasa
Un petit post “ma life” pour changer ! Le WE du 19 mars, on a eu l’occasion d’aller passer 4 jours (du samedi au mardi) à New York, pour l’occasion du passage des Lúnasa, groupe de Musique celtique dont ma douce est fan :) Bref, levé le samedi à 4H30, avion à 8H30, arrivée vers 11H, et c’est parti pour la visite !
Nous étions dans un petit hôtel dans le “upper est side” (côté est de Manhattan, à 5 minutes de Central Park) On a passé samedi et dimanche à marcher, dans Central Park, un peu partout dans Manhattan sans vraiment savoir où on allait ni où on était, on est passé à la New York Public Library, dans Central Park (à éviter le WE pour les agoraphobes :)) et finalement, un petit tour au 86ème étage de l’Empire State Building. A et quelques arrêts et détours par les boutiques, marchés, magasins et autres buildings impressionnants :)
Lundi, temps pourri, froid et pluie … du coup tentative d’aller jusqu’à Soho à pied qui s’est finalement transformée en Rockfeller Center (grandes galeries commerçantes couvertes) à l’heure du déjeuner … Donc surpeuplé de New Yorkais en costumes en train de manger. Et le soir, concert des Lúnasa. J’ai adoré. Et pourtant, je suis pas fan de musique celtique, mais je sais pas, la salle était bien, et sur scène ça rendait super bien. Bonne ambiance, groupe sympa, super bon souvenir !
Voilou, pour conclure, New York en un mot : “trop”. Trop grand, trop de monde, trop copieux (les plats) trop tout en fait :) Mais faudra qu’on y retourne, j’ai pas pu aller voir la statut de la liberté et 2/3 autres trucs à touriste :)
Pour voir les autres photos, c’est ici : http://gallery.pcitron.fr/2011.03.19.New.York/
C++ et mutable
Petite note à mon blog suite à la découverte du mot clef mutable en C++. Oui, même après 6 ans de développement, je continue de découvrir des trucs qui visiblement font pourtant partie de la base :) C’est plutôt cool de bosser enfin sur des projets développés par des têtes ! Mais trêve de blablah, explication !
On connait tous le mot clef const. Il est là pour garantir qu’un objet ne sera pas altéré / modifié. Un des exemples le plus courant concerne les “getter”, ces petites fonctions souvent inline qui permettent d’accéder à une variable membre en lecture seule. Par exemple :
class SceneNode { public: Matrix GetAbsoluteTransformation(void) const { // root node if (m_Parent == NULL) return m_RelativeTransformation; return m_Parent->GetAbsoluteTransformation() * m_RelativeTransformation; } private: Matrix m_RelativeTransformation; SceneNode * m_Parent; };
Ici, const garantit que GetAbsoluteTransformation ne modifie pas le contenu de l’instance de SceneNode. Ce qui est parfaitement logique et sain conceptuellement parlant.
Imaginons maintenant que l’on veuille optimiser un peu tout ceci en utilisant un cache de la matrice : en gros, on stocke en interne le résultat du calcule et tant qu’il n’y a pas de transformation, on se contente de renvoyer le résultat. Par exemple :
class SceneNode { public: const Matrix & GetAbsoluteTransformation(void) const { if (m_NodeFlags & RECALC_ABSOLUTE_TRANSFORMATION) { if (m_Parent == NULL) m_CachedAbsoluteTransformation = m_RelativeTransformation; else m_CachedAbsoluteTransformation = m_Parent->GetAbsoluteTransformation() * m_RelativeTransformation; // remet le flag a 0 pour ne pas avoir à recalculer au prochain appel m_NodeFlags &= ~RECALC_ABSOLUTE_TRANSFORMATION; } return m_CachedAbsoluteTransformation; } private: Matrix m_CachedAbsoluteTransformation; Matrix m_RelativeTransformation; SceneNode * m_Parent; };
En gros, à chaque fois qu’une modification est apportée à la transformation d’un noeud (que ce soit le parent ou le noeud courant) on active un flag qui indique à la fonction GetAbsoluteTransformation de recalculer la matrice. Et quand ce flag est nul, on renvoie simplement le résultat.
Le problème qui se pose ici (hormis le fait que le code ci-dessus ne compilera très certainement pas à cause du const) c’est que l’on a une fonction qui, conceptuellement, ne modifie pas le contenu de l’instance, mais dans la pratique, si ! En effet, quand on recalcule le cache, on ne modifie pas le contenu logique de la classe : on ne modifie pas sa position, sa rotation, le contenu de ses différents états. MAIS on modifie quand même une variable membre, et donc le compilateur fait chier et on doit virer le const !
Et c’est là qu’intervient notre mot clef mutable : il permet d’autoriser la modification d’une variable membre par une méthode const ! Et notre exemple précédent devient :
class SceneNode { public: const Matrix & GetAbsoluteTransformation(void) const { // le contenu ne change pas } private: mutable Matrix m_CachedAbsoluteTransformation; Matrix m_RelativeTransformation; SceneNode * m_Parent; };
Et là, le compilateur ne râle plus ! On a donc un getter parfaitement sécurisé, qui garantit la constance de l’instance sur laquelle il est appelé, tout en autorisant le caching du résultat !
Une petite note toutefois concernant ce mot clef : attention à son utilisation ! Il existe le risque de l’utiliser pour corriger de façon fonctionnelle un problème conceptuel ! (oui, c’est bizarre comme phrase, mais bon en gros si une méthode const modifie le contenu de sa classe, c’est souvent un défaut de conception qui peut être dangereux, alors en croyant le “corriger” en utilisant mutable, on ne fait en fait que masquer le réel problème :))
Sources :
http://msdn.microsoft.com/en-us/library/4h2h0ktk(v=vs.80).aspx
http://www.highprogrammer.com/alan/rants/mutable.html
Parkour Park
3DMagix et IllusionMage, grosse arnaque …
Petit post “militant” suite à ce que j’ai lu ici : 3DMagix and IllusionMage, scam or open source leeches?
Et ci-dessous le petit lien à copier coller et foutre quelque part sur votre site si vous aussi ce genre de truc vous énerve profondément et que vous voulez y faire quelque chose (la multiplication de ce lien a pour but d’associer les mots clefs 3DMagix, 3DMagixPro et IllusionMage à un lien redirigeant sur le site officiel de Blender)
Daniel Ilabaca Parkour Tour
Rah, après je sais pas combien de temps sans connexion digne de ce nom (clé 3G+ oblige …) je peux enfin regarder à nouveau des vidéos … de PARKOUR !!!! Et je suis tombé sur une petite suite de vidéos featuring Daniel Ilabaca, mon maître, mon idole, ZE king of ze Parkour, etc. Bref, l’homme chat. Première vidéo de la série ci-dessous, mais allez voir la page youtube (en cliquant sur la vidéo je crois) y’en a plein d’autre un peu partout en Europe, avec des making of assez sympa. Et surtout, de la fluidité, du style, du grand Ilabaca :) (oui je fais ma groupie hystérique, et je vous emmerde ! :p)
Neige !
Bon, après tous ces posts de geek, un peu de photo pour changer ! La semaine dernière, c’était le bordel monumental suite aux chutes de neige assez ouf qu’on a eu. Certain aiment, d’autres pas. Perso j’étais bien au chaud sous ma couette, mais je plein tous ceux qui ont galéré à rentrer chez eux. Toujours est-il que le lendemain a donné lieu à une super balade et quelques photos sympas.
Toute la galerie est visible ici : http://gallery.pcitron.fr/2010.12.10.Neige/ et ci-dessous quelques exemples :







