IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Boost C++ Discussion :

Signaux et slot


Sujet :

Boost C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 13
    Par défaut Signaux et slot
    Bonjour à tous,

    Je débute dans l'utilisation de boost::signals2 et j'ai repris les premiers exemples de la documentation pour me faire la main.

    De mes tests, il ressort qu'il est assez facile d'avoir n objets qui écoutent un signal.

    Là ou je ne comprends pas comment faire, c'est quand x objets peuvent émettre un signal ( par exemple, une référence) et comment un objet peut écouter tous ces signaux (pour, par exemple, stocker les références émises)

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 638
    Par défaut
    Salut,

    tu dois te baser à peu de choses près sur l'exemple de la vue document.

    1- Tu crées un typedef par type différent de signal, par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    /* moi, je suis en C++11 ;) */
    class MyClass{
        using signalNoParam_t = boost::signals2::signal<void()>;
        using signalOnParam_t = boost::signals2::signal<void(int i)>;
        /* ... */
        public:
    };
    2- Par facilité, tu crées un typedef sur les slots correspondants et un typedef sur le type "connection":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /* moi, je suis en C++11 ;) */
    class MyClass{
        using signalNoParam_t = boost::signals2::signal<void()>;
        using signalOneParam_t = boost::signals2::signal<void(int)>;
        /* ... */
        public:
            using slotNoParam_t = typename signalNoParam_t::slot_type;
            using slotOneParam_t = typename signalOneParam_t::slot_type;
            using slotOneParam_t = typename signalOneParam_t::slot_type;
            using connection_t = boost::signals2::connection;
    };
    3- Tu crées les différents signaux que tu veux émettre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /* moi, je suis en C++11 ;) */
    class MyClass{
        using signalNoParam_t = boost::signals2::signal<void()>;
        using signalOneParam_t = boost::signals2::signal<void(int)>;
        /* ... */
        public:
            using slotNoParam_t = typename signalNoParam_t::slot_type;
            using slotOneParam_t = typename signalOneParam_t::slot_type;
            using slotOneParam_t = typename signalOneParam_t::slot_type;
            using connection_t = boost::signals2::connection;
        private:
            /* deux signaux qui ne prennent pas de paramètres */
            signalNoParam_t firstSignal;
            signalNoParam_t secondSignal;
            /* et deux signaux qui prennent un int comme paramètre */
            signalOneParam_t thirdSignal;
            signalOneParam_t fourthSignal;
     
    };
    4- Tu permet à "tout et n'importe quoi" de se connecter sur les différents signaux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    class MyClass{
        using signalNoParam_t = boost::signals2::signal<void()>;
        using signalOneParam_t = boost::signals2::signal<void(int)>;
        /* ... */
        public:
            using slotNoParam_t = typename signalNoParam_t::slot_type;
            using slotOneParam_t = typename signalOneParam_t::slot_type;
            using connection_t = boost::signals2::connection;
     
            connection_t onFirstSignal(slotNoParam_ const & subscriber){
                 return firstSignal.connec(subscriber);
            }
            connection_t onSecondSignal(slotNoParam_ const & subscriber){
                 return secondSignal.connec(subscriber);
            }
            connection_t onThirdSignal(slotOneParam_ const & subscriber){
                 return thirdSignal.connec(subscriber);
            }
            connection_t onFourthSignal(slotOneParam_ const & subscriber){
                 return thirdSignal.connec(subscriber);
            }
        private:
            /* deux signaux qui ne prennent pas de paramètres */
            signalNoParam_t firstSignal;
            signalNoParam_t secondSignal;
            /* et deux signaux qui prennent un int comme paramètre */
            signalOneParam_t thirdSignal;
            signalOneParam_t fourthSignal;
     
    };
    6- Tu permet la déconnection:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    class MyClass{
        using signalNoParam_t = boost::signals2::signal<void()>;
        using signalOneParam_t = boost::signals2::signal<void(int)>;
        /* ... */
        public:
            using slotNoParam_t = typename signalNoParam_t::slot_type;
            using slotOneParam_t = typename signalOneParam_t::slot_type;
            using connection_t = boost::signals2::connection;
     
            connection_t onFirstSignal(slotNoParam_ const & subscriber){
                 return firstSignal.connec(subscriber);
            }
            connection_t onSecondSignal(slotNoParam_ const & subscriber){
                 return secondSignal.connec(subscriber);
            }
            connection_t onThirdSignal(slotOneParam_ const & subscriber){
                 return thirdSignal.connec(subscriber);
            }
            connection_t onFourthSignal(slotOneParam_ const & subscriber){
                 return thirdSignal.connec(subscriber);
            }
            void disconnect(connection_t conn){
                conn.disconnect();
            }
        private:
            /* deux signaux qui ne prennent pas de paramètres */
            signalNoParam_t firstSignal;
            signalNoParam_t secondSignal;
            /* et deux signaux qui prennent un int comme paramètre */
            signalOneParam_t thirdSignal;
            signalOneParam_t fourthSignal;
    };
    7- tu émets les signaux qui t'intéressent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    class MyClass{
        using signalNoParam_t = boost::signals2::signal<void()>;
        using signalOneParam_t = boost::signals2::signal<void(int)>;
        /* ... */
        public:
            using slotNoParam_t = typename signalNoParam_t::slot_type;
            using slotOneParam_t = typename signalOneParam_t::slot_type;
            using connection_t = boost::signals2::connection;
     
            connection_t onFirstSignal(slotNoParam_ const & subscriber){
                 return firstSignal.connec(subscriber);
            }
            connection_t onSecondSignal(slotNoParam_ const & subscriber){
                 return secondSignal.connec(subscriber);
            }
            connection_t onThirdSignal(slotOneParam_ const & subscriber){
                 return thirdSignal.connec(subscriber);
            }
            connection_t onFourthSignal(slotOneParam_ const & subscriber){
                 return thirdSignal.connec(subscriber);
            }
            void disconnect(connection_t conn){
                conn.disconnect();
            }
            void doOneThing(){
                /* ... */
                firstSignal();
            }
            void doSecondThing(){
                /* ... */
                secondSignal();
            }
            void doThirdThing(int i){
                /* ... */
                thirdSignal(i);
            }
            void doFourthThing(int j){
                /* ... */
                fourthSignal(j);
            }
        private:
            /* deux signaux qui ne prennent pas de paramètres */
            signalNoParam_t firstSignal;
            signalNoParam_t secondSignal;
            /* et deux signaux qui prennent un int comme paramètre */
            signalOneParam_t thirdSignal;
            signalOneParam_t fourthSignal;
    };
    Pas plus compliqué que cela
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Salut,

    Là ou je ne comprends pas comment faire, c'est quand x objets peuvent émettre un signal ( par exemple, une référence) et comment un objet peut écouter tous ces signaux (pour, par exemple, stocker les références émises)
    Il suffit que ces x objets émettent sur le même slot, et l'objet qui est enregistré à ce signal recevra dans l'ordre les différents signaux émis. Après il faut faire attention si c'est multi-threadé mais c'est un autre débat...

    Pour simplifier l'exemple de Koala, dans le cas où une classe possède n slots, j'ai développé durant cet été quelques classes génériques à ce propos, j'en fait une bref présentation dans l'article cité en signature et tu peux récupérer les sources ici (lit la doc du events.hpp). Tout ça est améliorable évidemment mais ça permet déjà de factoriser pas mal.

Discussions similaires

  1. Signaux et slots comme Qt
    Par b Oo dans le forum Qt
    Réponses: 21
    Dernier message: 11/04/2007, 17h57
  2. [Qt4] Signaux et Slot
    Par gentox dans le forum Qt
    Réponses: 9
    Dernier message: 25/01/2007, 18h35
  3. Réponses: 10
    Dernier message: 09/10/2005, 22h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo