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

Farfelue Discussion :

quelques petites questions


Sujet :

Farfelue

  1. #1
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut quelques petites questions
    Bonjour,

    ce projet m'intéresse énormément. Cependant, pour des raisons personnelles, je ne pense pas pouvoir participer à long terme, mais j'ai déjà eu à me pencher de très près sur les problèmes d'IHM (par exemple j'ai fais une petite lib d'IHM pour mon jeu YaTuS), et peut-être pourrais-je apporter quelques contributions intéressantes.

    Mais je ne sais pas si c'est moi qui ne sais pas chercher, mais il me manque quelques éléments pour cerner le projet:

    Dans ce forum vous faites référence à openGL. Voulez-vous utiliser openGL?

    A noter que l'utilisation d'openGL comme renderer graphique est une idée qui est loin d'être ridicule, car avec les chipset graphique d'aujourd'hui, il est bien souvent plus rapide d'afficher un sprite via openGL que directement un buffer 2D.

    Comment pensez-vous gérer les notions de fenêtre et d'événements? Voulez-vous utilisez les libs natives (win32, X)?

    Quels sont les OS cibles?

    Pensez-vous gérer les fenêtre non-rectangulaire? (C'est une question "dans l'air du temps" et apparemment il faut prendre en compte cette question le plus tôt possible).

    Avez-vous discuté de l'utilisation d'un super-object à la Qt?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 69
    Points : 142
    Points
    142
    Par défaut
    Concernant l'utilisation, d'un super-objet c'est : NIET.

    C'est ce que j'ai surtout retenu des propos de Koala01.

  3. #3
    Membre émérite
    Inscrit en
    Avril 2010
    Messages
    1 495
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 1 495
    Points : 2 274
    Points
    2 274
    Par défaut
    Salut,

    En guise de réponse, je vais te faire un résumé. En fait, l'objectif de cette interface est de pouvoir fonctionner sur Windows, Linux et probablement sur Mac tout en étant le plus proche possible des primitives des OS cibles. Ainsi, le recours à des librairies externes se doit d'être réduit au strict minimum. Quant à OpenGL ou Direct3D, se sera peut-être envisagé, mais pas dans l'immédiat. L'interface en elle-même devra donner la possibilité à ses utilisateurs de gérer des formes variées dans le rendu visuel.
    Enfin, pour l'histoire du super-objet à la sauce Qt, comme vient de le rappeler obliveon, elle est définitivement écartée, même en changeant de sauce d'ailleurs.

    Voilà, j'espère que ça te permettra de mieux cerner l'ensemble. Tu peux également lire la draft si tu ne l'as pas encore fait.

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 176
    Points
    1 176
    Par défaut
    Et sur les threads il y a un avis? En utiliser dans la librairie, ne pas en utiliser, laisser l'utilisateur faire ce qu'il veut, mettre tout les composants thread-safes, système de message?

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,

    Ben, il semblerait que toutes les réponses aient été données

    Effectivement, le recours à un super objet en tant que tel est exclu, bien que l'on ne puisse pas éviter un minimum de recours à certaines hiérarchie de classes (comment mettre le pattern "composite" en œuvre si les nœuds et les feuilles n'ont pas une base commune )

    Pour ce qui est des threads et des signaux (au minimum, vu que c'est ce dont il est question), mon idée serait de déléguer ce que la STL sous sa forme C++11 ne propose pas à boost.

    Sauf erreur, boost.thread et boost.signals2 ont déjà fait le travail de raccord avec les primitives des OS envisagés, et nous serions assez bêtes de ne pas en profiter
    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

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 176
    Points
    1 176
    Par défaut
    ma question nétait pas tellement qu'est ce qu'on utilise pour les threads/signaux (ça c'est ok, boost, on est d'accord), mais quelle est la politique de leur utilisation?

    Je m'explique.

    On a des interfaces comme celles de Delphi/C++ Builder qui sont entièrement thread safe. Si je me souviens bien, elles sont protégées par un mutex donc toute modification de différents threads ne pose aucun problème. Par contre c'est assez lent. Mais pratique pour les débutants.

    Avec GTK, gtkmm etc.. il n'y a pas de gestion de threads. Si on modifie le même widget avec deux threads différents, on a toutes les chances de se prendre un bon vieux seg fault. Pour palier à ça, il y a soit une macro qui crée un mutex englobant les parties critiques. Soit ils conseillent d'utiliser un système de messages queue où les éléments dépilent les messages. Mais c'est au client de se le cogner.

    J'espère que je n'ai pas trop dit de bétise, mais c'est peut être un aspect à étudier ( sachant qu'on veut un truc performant, portable etc..)

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Au temps pour moi...

    La politique est donc la suivante:

    Si on fait du multi-threading, ce doit être thread safe.

    L'idéal, pour autant que faire se peut, serait de permettre l'activation / la désactivation du multi-threading, s'il est possible de créer des politiques efficaces sur le sujet

    Je me demande si on ne pourrait pas s'inspirer de loki sur ce coup là...
    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

  8. #8
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Bonjour, et merci pour vos réponses.
    Jusqu'ici je partage vos choix.

    Mais sinon, j'ai l'impression qu'il reste un flou à propos du gestionnaire de fenêtres et d'événements, alors que c'est vraiment un aspect primordial du problème.

    Je développerai en 2 points:
    1. Le gestionnaire de fenêtres

    C'est la base de tout, car avant de pouvoir afficher un contrôle, il nous faut une fenêtre. Sur ce point j'avoue mon ignorance, mais c'est la base. Généralement, les événements de l'OS sont également gérés par le gestionnaire de fenêtres (voir glut par exemple).

    2. Les événements

    Il y a deux types d'événements à gérer:

    A. Les événements de l'OS. Typiquement, ce sont les clics souris(up, down, différents boutons), touches claviers (up, down), mais aussi les événements concernant les fenêtre (activation/désactivation de fenêtre, focus, minimisation/maximisation, etc.)

    B. Les événements "internes" à la lib. Par exemple: clic bouton, les "OnChange" (événement qui précise que l'état d'un contrôle a changé), scrolls, etc.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par r0d Voir le message
    Bonjour, et merci pour vos réponses.
    Jusqu'ici je partage vos choix.

    Mais sinon, j'ai l'impression qu'il reste un flou à propos du gestionnaire de fenêtres et d'événements, alors que c'est vraiment un aspect primordial du problème.
    Ce sont, effectivement, deux aspects primordiaux du problème, et il est effectivement pas mal de déjà commencer à y réfléchir.

    Je développerai en 2 points:
    1. Le gestionnaire de fenêtres

    C'est la base de tout, car avant de pouvoir afficher un contrôle, il nous faut une fenêtre. Sur ce point j'avoue mon ignorance, mais c'est la base. Généralement, les événements de l'OS sont également gérés par le gestionnaire de fenêtres (voir glut par exemple).
    Tout à fait...

    Mais pour savoir comment gérer une fenêtre, il faudrait déjà ... savoir ce qu'est une fenêtre, et de quoi elle est composée.

    Nous avons déjà la composante "visuelle" au travers de formes (bien que nous n'ayons pas encore le rendu de cette composante) d'une fenêtre, mais nous ne disposons d'aucun autre aspects, comme l'éventuelle unicité, l'aspect nodal ou non, la possibilité d'ajouter des menus, de boites à outils, ...

    Nous pourrions, bien sur, envisager de partir d'un modèle template de singleton et d'avoir une spécialisation pour une TWindow qui fournirait le comportement de base (createWindow, destroyWindow, ...), mais nous serions rapidement limité par le fait que... l'on ignore encore tout de cette classe TWindow

    Et je ne suis d'ailleurs même pas sur que l'approche basée sur un singleton soit la meilleure possible.

    Personnellement, je me demande si nous n'aurions pas intérêt à avoir une classe ("TApplication") qui agirait comme (selon les cas et les besoins)
    • un gestionnaire de fenêtre
    • un gestionnaire d'événement
    • un gestionnaire de thread
    • les gestionnaire que j'ai oubliés...

    et qui permettrait au développeur "basique" d'écrire un simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main()
    {
        nonThreadedApplication ap("My app");
        return app.run();
    }
    et au développeur plus évolué d'avoir un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main()
    {
        TApplication< threadModel, mainWindowModel, ...> app("My App");
        return app.run();
    }
    D'ailleurs, le problème se pose avec l'ensemble des éléments visuels (menus, éléments de menu, bouton, "label", champs divers et variés,
    2. Les événements

    Il y a deux types d'événements à gérer:

    A. Les événements de l'OS. Typiquement, ce sont les clics souris(up, down, différents boutons), touches claviers (up, down), mais aussi les événements concernant les fenêtre (activation/désactivation de fenêtre, focus, minimisation/maximisation, etc.)

    B. Les événements "internes" à la lib. Par exemple: clic bouton, les "OnChange" (événement qui précise que l'état d'un contrôle a changé), scrolls, etc.
    [/QUOTE]Effectivement, les événements et les signaux qu'ils impliquent sont une partie assez ardue à laquelle il faut réfléchir un très sérieux coup...

    La grosse difficulté étant que les signaux qu'ils occasionnent peuvent se transmettre de manière "montante" (de l'OS vers le dernier enfant d'un élément) ou de manière "descendante" (de l'élément actif vers ses parent... voir jusqu'à l'OS)

    Mais, là encore, nous n'avons pas la base minimale qui nous permette d'y réfléchir de manière concrète
    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

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par nikko34 Voir le message
    Avec GTK, gtkmm etc.. il n'y a pas de gestion de threads. Si on modifie le même widget avec deux threads différents, on a toutes les chances de se prendre un bon vieux seg fault. Pour palier à ça, il y a soit une macro qui crée un mutex englobant les parties critiques. Soit ils conseillent d'utiliser un système de messages queue où les éléments dépilent les messages. Mais c'est au client de se le cogner.
    Normalement, Gtk permet de rendre les widget threadsafe. Mais c'est pas conseillé.
    http://library.gnome.org/devel/gdk/u...k-Threads.html

  11. #11
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par r0d Voir le message
    B. Les événements "internes" à la lib. Par exemple: clic bouton, les "OnChange" (événement qui précise que l'état d'un contrôle a changé), scrolls, etc.
    Ceci n'est pas forcément un évènement: c'est un callback, c'est à dire un pointeur membre sur fonction, qui peut être appelé par le "code métier" du widget (ou même du code client, d'ailleurs). En gros, c'est comme ca qu'on paramètre les instances de nos widgets : en leur affectant des fonctions membres.

    Il va généralement être implémenté de la façon suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class MonWidget {
    private :
      CallBack FOnChange; 
      // avec le getter, le setter qui vont bien, initialisé à NULL à l'instanciation
    public : 
      void OnChange(...) {  // liste de paramètre variable
         if(FOnChange) FOnChange(...);
      }
    };
    La difficulté est que FOnChange est en théorie un pointeur sur fonction membre, qu'il faut "démembrer", c'est à dire désassocier de sa classe d'origine, pour pouvoir l'affecter, tout en lui donnant accès aux membres de la classe... C'est un des avantages des architectures de superObjet, soit dit en passant.

    Pour ça, on n'est pas du tout obligés d'avoir des évènements ou des signaux. Je ne suis même pas sur que ce soit une bonne idée de trop suivre les évènements de l'OS.

    Koala et les autres, je sais qu'il y a des solutions à ce pb, je pense que ca vaudrait probablement la peine de les lister et d'en causer sur un fil à part : on va avoir besoin de ce genre de callbacks, ce n'est pas horriblement difficile à implémenter, mais ce n'est pas trivial non plus. Parlons en!

    Francois
    Dernière modification par Invité ; 26/04/2010 à 23h59.

  12. #12
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Citation Envoyé par fcharton Voir le message
    La difficulté est que FOnChange est en théorie un pointeur sur fonction membre, qu'il faut "démembrer", c'est à dire désassocier de sa classe d'origine, pour pouvoir l'affecter, tout en lui donnant accès aux membres de la classe... C'est un des avantages des architectures de superObjet, soit dit en passant.
    Je vois pas pourquoi on aurait besoin du superObjet ?

    En utilisant l'abstraction fonctionnelle (au sens programmation fonctionnelle), fournie par std::function, un pointeur sur fonction membre à N paramètres peut se considérer comme une fonction à N+1 paramètres (le pointeur this venant en plus).

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 176
    Points
    1 176
    Par défaut
    les callbacks, ce sera pas à coup de boost::signals?

  14. #14
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par nikko34 Voir le message
    les callbacks, ce sera pas à coup de boost::signals?
    es ce que l'on peut considérer boost::signal comme une callback? contrairement à std::function ?

  15. #15
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par yan Voir le message
    es ce que l'on peut considérer boost::signal comme une callback? contrairement à std::function ?
    Dans un certain sens, pourquoi pas

    En gros, un élément envoie un signal qui est récupéré par un ou plusieurs autre(s) éléments qui y sont connectés, et, ces éléments "récepteurs" réagissent en fonction du signal reçu...

    N'est-ce pas, d'une certaine manière, le principe du callback, avec la souplesse en plus

    J'ai, en tout cas, l'impression que l'on peut se passer des callback dés que l'on a quitté la partie dépendante du système, non
    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

  16. #16
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Dans un certain sens, pourquoi pas
    parceque c'est une décision pas aussi simple que cela
    au niveau fonctionnel pour faire une callback c'est assez proche, mais un signal peut être connecté à plusieurs fonctions. Sans avoir de lien entre eux (apriori)

    Par exemple on as un ensemble de callback qui va dessiner le widget. Avec boost::signal elles seront toutes appelées. Ne serai ce pas intéressant d'avoir une notion de filtrage?
    l'ordre est important.


    Y un aspect qui peut être intéressant de réfléchir, c'est justement le filtrage des events.

    En Qt, on peut installer un filtre qui va récupérer en premier l'events, pouvoir faire un traitement dessus et si besoin stopper sa progression.
    boost::signal ne permettra pas cela, non? alors qu'avec un vector de callback si.

    Autre aspect trés pratique. Chaque events partent du même endroit. Sous Qt QApplication est celui qui reçois tous les events et va les dispatcher. On peut donc les filtrers à ce niveau.

  17. #17
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Justement, si, cela peut être aussi simple que ca...

    Boost signals2 permet de créer des groupes.

    Je reprend en cela l'exemple de boost "him self":
    les foncteurs utilisés
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    struct Hello
    {
      void operator()() const
      {
        std::cout << "Hello";
      }
    };
    struct World
    {
      void operator()() const
      {
        std::cout << ", World!" << std::endl;
      }
    };
    les connections
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    boost::signals2::signal<void ()> sig;
     
      sig.connect(1, World());  // connect with group 1
      sig.connect(0, Hello());  // connect with group 0
    Et je ne serais pas étonné qu'il y ait moyen de connecter un signal à un autre ...

    Si tel est bien le cas(faudrait tester ), il est possible de faire des groupes "atomiques" de signaux, et de les connecter entre eux pour obtenir des groupes de réactions complexes (onLoad, qui appelle le chargement du fichier, puis qui envoie le signal "changed" qui réagit par un "onUpdate", qui... appelle resize, ou que sais-je )
    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

  18. #18
    Invité
    Invité(e)
    Par défaut
    Bon, là c'est moi qui ne suis plus...

    A mon avis, les signaux et les callbacks, même s'ils sont généralement associés, sont des choses très différentes.

    Un signal, c'est un système de communication (asynchrone et décentralisé), au lieu d'appeler une fonction, ou de créer un lien entre deux parties du systèmes, on envoie un signal à un répartiteur, qui se charge de le transmettre à un destinataire, qui a une fonction "maitresse" (une WindowProc chez nos amis de Microsoft) qui appelle la fonction membre idoine.

    Un callback, c'est une facon de paramétrer une instance d'une classe. Tous les boutons "font quelque chose" quand on les clique, mais chaque instance fait une chose différente, cette chose différente, c'est le callback. Un callback, c'est une fonction membre, définie au niveau de l'instance, et hors de la classe...

    Mélanger les deux (sous prétexte qu'ils sont associés chez Qt ou Borland), c'est, je crois, une grosse erreur. Il y a des signaux sans callbacks (toutes les "actions standard" de nos widgets : on clique sur un combo, la liste se déroule, ce n'est pas paramétrable, pas de callback), et des callback sans signaux, par exemple, les évènements de type OnCreate, OnDestroy, déclenchés par le constructeur/destructeur. On peut ajouter un signal, mais c'est parfaitement gratuit.

    Francois

  19. #19
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Cette histoire de [signal][event][callback] (choisissez l'option que vous voulez, de toutes façon ce sont des notions différentes mais dans notre cas l'objectif est le même) n'est en effet pas si simple. Techniquement il n'y a rien de compliqué, je pense qu'on peut même s'en sortir avec boost::function (avec une map de boost::fonction par exemple si on veut plusieurs observeurs), mais c'est au niveau de la conception qu'il ne faut pas se planter.

    Je crois que la meilleure solution dépends de ce que l'on veut faire, et qu'une fois qu'on aura bien déterminé ce que l'on veut faire, le choix nous paraitra évident.

    Quelques remarques d'ordre général sur le problème:

    En fait, au niveau le plus abstrait, ce qu'il nous faut c'est que nos contrôles soient observables (DP observer), et que les observeurs puissent être implémentés par l'utilisateur. Il y a différentes techniques pour implémenter un observer (callback, signal/slot, événement), chacune ayant ses avantages et ses inconvénients. Par exemple, avec un système d'événement avec une FIFO de gestion de ces events, l'avantage est la souplesse et la facilité pour implémenter des animations. L'inconvénient c'est que c'est plus complexe à mettre en place (et donc à maintenir etc.).

    Je pense qu'il faut commencer par répondre à des questions du style:
    - Comment gérer les animations (par exemple une liste déroulante - combo - qui s'ouvre). Répondre à cette question nécessite répondre à la questions suivante:
    - Va-t-on avoir besoin d'une boucle principale? Personnellement, je ne vois pas comment s'en passer.


    Ha, et une précision: les événements de l'OS on ne peut pas s'en passer. C'est eux qui nous disent ce qu'il se passe (clic souris, touche clavier, etc.)
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  20. #20
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    [NOTA]J'avais commencé la réponse à fcharton... Tout ceci est donc à mettre en relation avec sa remarque

    Tout à fait d'accord, mais boost signals a ceci de bien que tu peux parfaitement traiter un callback (qui n'est qu'un pointeur de fonction ) exactement de la même manière que tu traiterais un signal.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void foo(){/* do something */}
    void bar() {/* do other thing */}
    boost::signals2::signal<void()> sig;
    sig.connect(&bar); // ce n'est qu'un pointeur sur fonction :D
    sig.connect(&foo); // bar sera par défaut appelé avant foo
    A partir de là, j'ai envie de dire que, le fait que le signal soit adaptable ou non dépend de la politique (ou plutôt du trait de politique) adapté à l'élément qui envoie le signal.

    En très gros, parce que écrit "en free style", on pourrait avoir une politique proche de
    Code C++ : 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
    struct adaptableSignal_flag{};
    struct unAdaptableSignal_flag{};
    template <class adaptable,class ... flags>
    class TSignalHolder;
    /* une classe utilisant des signaux renvoyant un type de retour donné
     * et prenant deux arguments, mais pour laquelle on ne peut pas 
     * adapter le comportement du signal
     */
    template<class Return, Arg1, Arg2>
    class TSignalHolder<unAdaptableSignal, Return, Arg1, Arg2>
    {
        public:
            typedef std::boost::signals2::signal<return(Arg1,Arg2) signal_type;
            TSignalHolder(signal_type const & s): sig_(s)
        private:
            signal_type sig_;
    };
    /* La même classe, mais à au signal de laquelle on peut
     * connecter d'autre fonctions / foncteur
     */
    template<class Return, Arg1, Arg2>
    class TSignalHolder<unAdaptableSignal, Return, Arg1, Arg2>
    {
        public:
            typedef std::boost::signals2::signal<return(Arg1,Arg2)> signal_type;
            typedef signal_type::signature_type signature_type;
            TSignalHolder(signal_type const & s): sig_(s)
            void connect(signature_type & fun){sig_.connect(fun);}
        private:
            signal_type sig_;
    };
    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

Discussions similaires

  1. [Séparer son code] quelques petites questions.
    Par echantillon dans le forum C
    Réponses: 33
    Dernier message: 07/03/2007, 18h29
  2. quelques petites questions
    Par la debutante dans le forum Windows
    Réponses: 1
    Dernier message: 20/12/2006, 10h08
  3. quelques petites questions sur les windows form
    Par natasha84 dans le forum C++/CLI
    Réponses: 22
    Dernier message: 25/05/2006, 23h14
  4. Quelques petites questions sur le shell
    Par Badaboumpanpan dans le forum Linux
    Réponses: 8
    Dernier message: 01/04/2006, 01h09
  5. [Tk] Quelques petites questions
    Par Damian dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 06/02/2006, 17h34

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