Rési(stance, pas sine … je sors)

Durée: 3H

  • Echauffement
  • Toutes les violettes de la salle

Soit … beaucoup :) Pas eu le temps de compter. On a commencé à 3, puis 2 puis j’ai finit tout seul. Du coup le début a pris plus de temps que quand je fais ça tout seul, et j’ai même pas pu tenter les dernières. En gros, tout fait sauf 3 ou 4 dans le double toit. Mais en ce moment, doit y’en avoir 1590 dans le double toit donc bon … (ouais, je choppe vite la touche marseillaise :p)

Bref, bien pété, mal partout aujourd’hui, et à la fin, j’arrivais pas à faire 2 mouv’ de suite tellement j’étais rincé :p Donc bonne séance. Prochaine séance, j’essaie de faire le maximum de blanche, histoire de rebosser un peu plus dans des filières de force :)

Mini séance pourrie

Durée: 1H45

  • Echauffement lance-pierre
  • Sortie d’un nouveau noir dans le double toit (2 essais, les vrais, pas ceux des falaisistes faux-cul)
  • Glandage

Bon, la loose. Machine qui dure trop longtemps, du coup séance raccourcie, et en plus de ça, mon tibia tout chelou qui m’a fait stresser et flipper … résultat, aucune motivation à grimper. Mercredi dernier au Parkour, je me suis explosé le tibia. J’ai vraiment eu peur, et depuis, j’ai toujours mal, mais bon, vu la profondeur de la plaie et le choc, je pense que c’est normal. Sauf que sans raison, hier soir, j’avais le côté du tibia (au dessus de la cheville extérieure) enflé, et des fourmillements. Et ça m’a fait flipper. Bon, ce matin c’était redevenu normal, mais vivement que tout revienne à la normale. Je vais arrêter le Vovinam et le Parkour quelques temps, le temps que mes jambes retrouvent un état à peu près correct (entre les chevilles défoncées et maintenant les tibias …)

boost.Signals, deuxième partie !

Pouet ! Bon, dans l’article précédent, j’expliquais comment boost a changé ma vie et tout et tout. Après avoir fait mon petit post, je suis retourné sur mon projet et ai commencé à supprimer le code que j’utilisais pour tout remplacer par boost. Tout ce passe bien jusqu’au moment où je tombe sur mon callback de gestion des messages clavier / souris … Et là, le bloquage : dans son utilisation “simple”, boost ne permet pas de gérer une fonctionnalité dont j’ai besoin dans ce cas particulier !

Explication : dans la plupart des cas, on balance un signal, et tous les slots sont appelés. C’est très bien. Mais dans certains cas, on voudrait récupérer la liste des slots et pour chacun, tester la valeur de retour avant d’envoyer le signal au slot suivant. Par exemple, dans mon cas, quand on traite les messages de la souris, à partir du moment où un slot me renvoie une valeur signifiant “hey c’est bon, c’est moi qui gère le message !” j’ai pas besoin de continuer d’envoyer le signal aux suivants, vu que le message a déjà été géré.

Bon, et bien boost a une fonctionnalité un peu plus évoluée qui s’appelle les “combiners” et qui permet d’associer au signal une fonction objet qui définit la manière dont on traite les slots. C’est pas forcément super clair, donc ci-dessous, un petit exemple :

/*
    On définit une structure template qui va ensuite être associée à notre
    signal lors de sa création. Cette structure doit contenir une définition
    de type et un operator ().
*/
template
struct MsgProcStop
{
    /*
        définit le type de retour du combiner. En général, c'est le même
        que le type de retour des slots, mais via les combiners, on peut
        retourner ce qu'on veut. Par exemple, les fonctions de gestion
        des messages retournent en général un entier, mais on peut
        très bien décider de retourner true si le signal a été géré par un
        slot ou false sinon (donc retourner un bool à la place d'un int)
    */
    typedef T result_type;

    /*
        L'operator () Celui-ci adment 2 iterateurs, tout simplement sur
        le premier et le dernier slot du signal. C'est appelé une seule fois,
        et du coup, on fait ce qu'on veut à l'intérieur.
    */
    template < typename InputIterator >
    T operator()(InputIterator first, InputIterator last) const
    {
        /* cette ligne vérifie simplement qu'il y a au moins un slot à traiter. */
        if (first == last)
            return(T());

        /*
            on initialise la boucle : cette ligne récupère la valeur de retour
            du slot, et déplace celui-ci d'un cran. Je ne sais pas si c'est
            l'opérateur ++ ou * qui exécute implicitement le slot, mais bon,
            l'important, c'est qu'il est appelé :)
        */
        T returnCode = *first++;

        /* Ensuite, on se déplace jusqu'à la fin de la liste de slots */
        while (first != last)
        {
            /*
                dans notre cas, on teste si la valeur de retour est différente
                de zéro. Si c'est le cas, ça veut dire que le message a été géré,
                et donc on s'arrête là, et on retourne le résultat (on pourrait
                retourner true ou false si on choisit bool comme type de retour
                du combiner ...)
            */
            if (returnCode != 0)
                return(returnCode);

            /* on passe au slot suivant */
            returnCode = *first++;
        }

        /* si on arrive là, on peut retourner la dernière valeure, ou un truc */
        /* par défaut ... on s'en fout. */
        return(returnCode);
    }

};


/* le signal est définit comme suit (le constructeur du signal peut être laissé vide */
/* dans ce cas, car par défaut il appelle le constructeur vide du combiner) */
boost::signal< int (), MsgProc< int > > signal(MsgProc< int >());

Bon, si vous avez lu les commentaires, vous devriez à peut près comprendre comment ça marche. Le combiner est en fait la fonction objet qui définit comment sont appelés les slots, et quoi faire avec leurs valeurs de retour. Donc ici, chaque slot va recevoir le signal, exécuter la fonction qui lui est associée, et dès qu’un slot retourne une valeur différente de zéro, hop, on arrête d’envoyer le signal ! C’est pil poil ce qu’on voulait faire.

Mais ! Problème : le test est codé en dur … ce qui est pète couilles, vu que si on veut tester une égalité, ou tester contre une autre valeur que 0, il faudrait dupliquer toute la classe … pas glop. Donc en cherchant dans mon pitit cerveau tout moisi (oui, ça fait longtemps que je ne l’utilise plus beaucoup, du coup …) j’ai trouvé la parade ultime ! boost::function !

Il y a deux choses à gérer pour rendre notre combiner vraiment portable : l’opérateur de test (le != dans notre exemple) et la valeur testée (0 dans notre exemple) Pour gérer la valeur, pas compliqué, on la stocke en variable membre dans le combiner, et on l’initialise via un constructeur. Et pour l’opérateur … et bien il suffit d’utiliser une fonction objet que l’on stocke aussi en variable membre ! Bon, démonstration passque c’est pas très clair tout ça :

template
struct MsgProcStop
{
    /*
        on créer un constructeur qui permet de spécifier la fonction de
        comparaison, et la valeur de référence. Voir plus bas pour la définition
        de ces fonctions, et pour l'utilisation des 2
    */
    MsgProcStop(const T & compareValue,
                      const boost::function< bool (T, T) > & compareFunction) :
        CompareValue(compareValue),
        CompareFunction(compareFunction)
    {
    }

    typedef T result_type;

    template < typename InputIterator >
    T operator()(InputIterator first, InputIterator last) const
    {
        if (first == last)
            return(T());

        T returnCode = *first++;
        while (first != last)
        {
            /*
                Et hop ! C'est ici que ça se passe ! Au lieu d'avoir le test et la
                valeur de référence en dur, on appelle maintenant la fonction
                objet de comparaison, et on lui donne la valeur de référence,
                et le code de retour du slot.
            */
            if (CompareFunction(returnCode, CompareValue) == true)
                return(returnCode);

            returnCode = *first++;
        }

        return(returnCode);
    }

    /*
        Ici, on définit des fonction objet qui reprennent simplement les
        différents opérateurs de test que l'on veut gérer.
    */
    struct Equal        { bool operator()(T & lVal, T & rVal) { return(lVal == rVal); } };
    struct Different    { bool operator()(T & lVal, T & rVal) { return(lVal != rVal); } };
    struct Less         { bool operator()(T & lVal, T & rVal) { return(lVal < rVal); } };
    struct Greater      { bool operator()(T & lVal, T & rVal) { return(lVal > rVal); } };
    struct LessEqual    { bool operator()(T & lVal, T & rVal) { return(lVal <= rVal); } };
    struct GreaterEqual { bool operator()(T & lVal, T & rVal) { return(lVal >= rVal); } };

    /* une fonction objet qui retourne un bool et prend en argument */
    /* 2 valeurs de type T */
    boost::function< bool (T, T) > CompareFunction;

    /* la valeur contre laquelle on effectue le test */
    T CompareValue;
};

/* maintenant, la définition des signaux est un chouilla plus complexe, mais */
/* complètement "libre : */
boost::signal< int (), MsgProcStop< int > > signal(MsgProcStop< int >(10,
                                   MsgProcStop< int >::OperatorEqual()));
boost::signal< int (), MsgProcStop< int > > signal(MsgProcStop< int >(0,
                                   MsgProcStop< int >::OperatorDifferent()));

Ouf, on arrive à la fin. Bon, les 2 signaux créés à la fin de l’exemple ci-dessus utilisent notre nouveau combiner : le premier utilise la valeur 10 et l’operateur ==, donc dès qu’un slot renvoie 10, le signal est stoppé. Le deuxième s’arrête dès qu’un slot renvoie une valeur différente de 0. Et on peut combiner tout ce qu’on veut lors de la création des signaux. Dingue non ? Bon, là, mon combiner s’appelle MsgProcStop … maintenant qu’il est parfaitement portable et configurable, je devrais plutôt l’appeler StopSignal ou un truc du genre, vu qu’il permet de stopper un signal sous certaines conditions.

Donc voilà tout, maintenant, via boost::signal, boost::bind, boost::function et cette petite classe combiner toute con, on a un système de gestion d’évènement configurable à volonté, facile d’utilisation et tout et tout. Et si la syntaxe est un peu pourrite lors de la création d’un signal utilisant un combiner, c’est pas trop grave vu que ça n’arrive pas souvent, et que de toute manière, la connexion d’un slot se fait de la même manière que sans combiner, donc c’est transparent pour l’utilisation !

Bobo

Mal aux doigts, au dos … partout en fait T_T

Durée: 3H

  • Echauffement
  • Travail force : nouvelles blanches, et re-sortage (oui c’est français !) de 3 blanches
  • Conti

Bon, hier c’était dur. C’était le deuxième jour de suite que je grimpais, et ça se sentait. Mal à la peau des doigts, mal aux doigts tout court, des courbatures, manque de force, la totale :) Mais bon, y’avait Adrien, Antoine et Damien donc j’suis quand même resté jusqu’à la fin (ah et Romain qui est arrivé assez tard et avec qui j’ai terminé la séance)

Donc après un échauffement appliqué, j’ai bossé un peu une nouvelle blanche du double toit (super dure …) j’ai rebossé celle d’hier, mais je bougeais encore moins bien … et ensuite j’ai refait des blanches que j’avais déjà sorties. 3 pour être précis. Et pour les trois quart d’heures restant de la séance, j’ai fait de la conti.

Bon, j’avais mal partout, j’ai toujours mal partout, mais globalement, c’est mieux passé que la dernière fois où j’ai essayé de grimper 2 jours de suites :p

boost.Signals, boost.Bind et gestion d’évènements en C++

Pouet ! Une fois n’est pas coutume, un peu de programmation (ouais, ça change du Parkour et de la grimpe :) Bon, ici, je vais faire une petite démonstration de l’utilisation des librairies boost pour gérer les évènements en C++.

Prenons un exemple tout con : on a un programme dans lequel nous avons un gestionnaire de resource, et une zoulie interface graphique. Le gestionnaire est capable de créer, modifier, supprimer des resources. Bien. Maintenant imaginons que nous ayons une fenêtre de notre interface qui affiche en continue toutes les resources actuellement gérées par notre programme, et qu’en même temps, nous ayons une fenêtre dans laquelle s’affiche en temps réel les actions effectuée sur les resources (ce qu’on appelle un log :)

La plupart des mauvais développeurs ne se prendraient pas la tête et mixeraient allègrement les différentes classes du programme, pour mettre en dur la mise à jour de l’interface dans le gestionnaire, ou vice versa … ce qui est TRES TRES PORCASSE ! Au lieu de tout mélanger, y’a un système très intéressant qu’on pourrait désigner par “gestion d’évènements” ou callbacks, ou delegates … j’ai jamais trop bien compris les légères / subtiles différences entre toutes les appellations de la même chose. En gros, dans ce monde, le gestionnaire de ressource se contente juste de gueuler “j’ai créé une ressource !!” et les autres parties, genre le log et l’interface se contentent d’écouter, et quand ça les intéresse (genre là, y’a “ressource dans le message, ça m’intéresse !) pouf on récupère l’évènement.

C’est très bisounours land, donc ci-dessous un exemple :

#include
#include
#include

using namespace std;

/*
    Un gestionnaire de resources.
*/
class ResourceManager
{
public:

    /*
        Ce signal permet à d'autres parties du programme de "s'enregistrer"
        afin d'être notifiées lorsque le ResourceManager effectue une action.
        Ici, il stock des fonctions ayant la signature "void (int, const char *)"
        C'est à dire des fonctions retournant void, et acceptant 2 paramètres : un
        int et une chaine de caractère. On peut spécifier le nombre d'argument que
        l'on veut, le type que l'on veut.
    */
    boost::signal < void (int, const char * ) > Signal;

    /*
        Ci dessous 2 méthodes d'exemple. Chaque méthode lance le signal avec les
        paramètres que l'on veut. Ici, l'id de la resource et un message indiquant
        l'action ayant été effectuée.
    */
    void CreateResource(int id) { Signal(id, "Resource created"); }
    void DeleteResource(int id) { Signal(id, "deleted resource"); }
};

/*
    Cette classe est un exemple de log. Elle écrit simplement tout ce qui
    se passe dans la sortie texte. Elle possède une méthode ayant la même
    signature que celle du signal ResourceManager::ResourceSignal.
*/
class Log
{
public:
    void ResourceEvent(int id, const char * msg)
    {
        cout << msg << "  : " << id << endl;
    }
};

/*
    Un deuxième exemple de classe qui aurait besoin d'être notifiée des actions
    sur les resources : une interface utilisateur qui affiche l'état actuel
    des resources. Comme la classe de log, cette classe possède une méthode
    ayant la bonne signature pour recevoir les signaux de
    ResourceManager::ResourceSignal.
*/
class ResourceUI
{
public:
    void Event(int id, const char * msg)
    {
        cout << "updating UI ..." << endl;
    }
};

int main(int argc, char* argv[])
{
    // 1 instance de chacune des classes
    ResourceManager resourceMgr;
    Log log;
    ResourceUI ui;

    /*
        on connecte le tout via boost::bind. Le premier argument est le pointeur de
        la méthode à appeler. Le deuxième est le pointeur sur l'instance dont on veut
        appeler la méthode. Les 2 derniers paramètres signifient juste que lors de
        l'appelle du signal, les paramètres 1 et 2 du signal seront reroutés sur
        la méthode. Voir plus bas dans l'article pour la doc de boost::bind
    */
    resourceMgr.Signal.connect(boost::bind(&Log::ResourceEvent, &log, _1, _2));
    resourceMgr.Signal.connect(boost::bind(&ResourceUI::Event, &ui, _1, _2));

    // et pour tester, on créer une resource, et on en détruit une autre :
    resourceMgr.CreateResource(1);
    resourceMgr.DeleteResource(2);

    /*
        le résultat qui s'affiche est :

        Resource created : 1
        updating UI ...
        deleted resource : 2
        updating UI ...
    */

    // on peut aisément déconnecter un slot (ici, on arrête le log)
    resourceMgr.Signal.disconnect(boost::bind(&Log::ResourceEvent, &log, _1, _2));

    // on reteste :
    resourceMgr.CreateResource(1);
    resourceMgr.DeleteResource(2);

    /*
        le résultat qui s'affiche est :

        updating UI ...
        updating UI ...
    */

    // pause
    string str;
    getline(cin, str);

    return 0;
}

Wouhou ça fait un gros paté de code. Mais si vous avez pris le temps de lire les commentaires, et regarder un peu ces 3 classes, le truc de ouf, c'est que aucune classe ne fait appelle à aucune autre ! Chacune gère simplement son bazard sans rien savoir de ce qui se passe autour d'elle ! Et c'est ça qui est bien. Je peux rajouter un nouveau système de log et le connecter à mon resource manager sans avoir à toucher la moindre ligne de code de la classe ResourceManager !

Voilou, tout cet article, c'était pour partager ma découverte de boost::signal et boost::bind, qui permettent de créer un système de callbacks très simple d'utilisation est très puissant.

Ou l’importance d’un échauffement bien fait …

Durée: 3H

  • Echauffement trop rapide
  • Tentative de répétition d’une blanche … 2 fois sur la prise de fin …
  • Travail d’une nouvelle blanche
  • Conti

Les boules. En arrivant, j’étais super motivé, j’avais une blanche quasiment dans la poche, et une nouvelle dans le double toit à essayer : “je m’échauffe, j’torche ma blanche, et je bosse l’autre !!” Motivé le Citron. Sauf que du coup, il a torché son échauffement. Et s’est choppé les bouteilles en allant 2 fois sur la prise de fin de sa blanche, mais sans la tenir.

Du coup, travailler la nouvelle avec les bouteilles, c’est assez mal passé, et quand Morgan est arrivé, hop, conti. Bref, un peu deg’ de pas avoir sortie cette voie, mais ce sera pour la prochaine fois. Et finalement, on a bossé la conti assez longtemps, donc tout n’est pas perdu :)

Moralité : si tu veux perfer, échauffe toi sans te presser :)

Gymnase, ô mon gymnase …

Un pur tracasse d'Antho !Trop bieng ! Hier soir, reprise des entrainements de Parkour en gymnase. Bon, un peu moins bieng, ma cheville est encore un peu douloureuse, donc je n’ai pas pu faire d’accros. Mais le praticable était … de nouveau praticable, et finalement, même si j’ai pas fait des saltos dans tous les sens (ou plutôt devrais-je dire “même si je ne me suis pas crouté dans tous les sens”) c’était une trop bonne session. C’est partie pour le compte-rendu !

Comme d’habitude, échauffement, sur le praticable tout beau tout neuf. Mais plus long que d’habitude, et avec quelques éléments de conditionnement, comme le fameux : 5 pompes, roulade, 5 pompes, roulades, etc. Quelques exercices pour travailler les jambes aussi : on se met par trois, 2 se mettent à genoux et se tiennent l’avant bras pour faire une sorte de barrière, et le troisième saute par dessus, pieds joints, détente sèche, et dès la réception, on se retourne, et roulade en passant en dessous. Marrant.

Ensuite, pendant quasiment toute la séance, on a fait un truc que je trouve trop bien, et que j’avais vu dans une vidéo que m’avait envoyé Pierre, sur une interview de Stephane Vigroux. Ce “truc” consiste à choisir un mouvement, ou dans notre cas, un enchainement de quelques mouvements, et de réussir à faire N fois ce(s) mouvement(s) sans tomber / perdre Petit enchainement "freestyle" autour du cheval.l’équilibre / etc. Dès que l’on foire, on repart à zéro. Pour cette reprise des entrainements, on a fait des trucs assez simple, comme un saut de chat par dessus un cheval d’arson, réception sur une marche, et saut de précision sur une poutre (avec un banc entre les 2 pour obliger à prendre un peu de hauteur) Exercice en apparence très simple. Sauf qu’on a du dépasser la centaine de répétitions pour arriver à en passer 10 de suite sans perdre l’équilibre arrivé sur la poutre :)

Après 2 ou 3 exercices de ce type, Antho et Billel sont allés faire des accros, et moi je suis allé bosser l’équilibre, et essayé de trouver des trucs à faire aux barres assymétriques. Mais tout seul, pas trop motivant, donc j’ai un peu tourné en rond. Faut que je trouve des trucs à faire pas trop dur pour progresser sur les barres assymétriques, y’a trop moyen de faire de bons exos, mais tout ce qu’on voit en vidéo est hyper dur … va falloir faire bosser l’imagination et l’impro :)

Et pour finir, on a remit un exercice où faire 10 répétitions, histoire de bien se finir, et étirement. Et ouais, une fois n’est pas coutume, on était tellement morts qu’on a arrêté avant 22H, du coup, en attendant le mec qui vient fermer, étirements (et blablatage accessoirement :)

2 nouvelles blanches

Durée: 3H

  • Echauffement
  • Travail et enchainement de 2 nouvelles pas blanches pas trop dures (ou alors j’ai la caisse : 4 essais ou moins pour chacune)
  • Force (travail de blanches pas encore sorties)
  • Conti / Rési

Je dois être dans une période où j’ai la patate en ce moment : chaque semaine une ou plusieurs blanche sortent, ce WE à Bleau, 2 belles croix, et ce soir, 2 blanches sorties en 4 essais environ. Le pire, la deuxième, ça a fait ça : premier essai : mauvaise méthode. Deuxième essai, encore mauvaise méthode. Troisième essai, j’avais vu quelqu’un passer, sortie … en gros, j’aurais vu la méthode avant de commencé, je l’aurais flashé. Pas courant pour une blanche, ç’aurait été ma première.

Bref, c’est plutôt cool pour le moral, en plus j’ai faillit sortir une blanche ultra pète couilles qui me résiste depuis sacrément longtemps. Ce sera pour jeudi :)

Croitage du 95.2

Le test de Turing et Victor qui tate les prises.Bon, ce secteur doit être celui où j’ai le plus perfé à Fontainebleau, si ça continue, il ne va quasiment plus rien me rester de faisable (reste encore une bonne floppée de blocs, mais dans des cotations encore inaccessibles :) Samedi donc, journée ensoleillée, fraiche, très fraiche. J’arrive un peu à la bourre rejoindre Charly et Victor. Je les retrouve dans la fosse aux ours, et après un échauffement vraiment minimaliste (3 ou 4 blocs entre bleu et rouge …) on bosse donc La Fosse aux Ours, un 7a en 2 mouvements sur des crougnes infâmes … très bien pour finir de bien se chauffer les doigts :D

3 grimpeurs en train de comploter.Bah finalement c’est sorti ! Bien content, c’était pas la première fois que je posais les doigts sur les réglettes de ce bloc, et j’aurais jamais pensé le sortir aussi “facilement” ! Charlouze aussi est sorti, se débarassant de sa bête noire du secteur :D Bon, Victor, à vue comme d’hab … on en parlera pas ! Ensuite, direction le Test de Turing, un 7a+ … en 2 mouvements aussi :) Et aussi à doigts, en tout cas le premier mouvement. Victor enchaine à l’aise, Charly en un peu plus d’essai, mais ça sort bien, et moi … je galère ! Mais je m’obstine … et hop ça sort ! Content.

Pour finir, on va se re-tenter RudeBoy pour Charly et le confirmer pour moi (j’avais déjà fait y’a 1 ou 2 ans) Après un peu de tatonnage pour retrouver le mouvement de sorti, ça le refait. Par contre, Charly, toujours autant à son aise dans les sorties dynamiques … ne le passera pas :( Va falloir bosser le dynamisme mon gars ! Finalement, on rejoint Matthieu, le responsable de New Sea Roc qu’on avait connu à Mada, et qui était de passage ici pour quelques jours, et après avoir enchainé une espèce de proue toute chelou et super dure, rentrage de fesse à la maison. Voilou, une super bonne journée, et pour une fois, des croix ! Ca faisait longtemps :D