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

Langage C++ Discussion :

Quel est la méthode la plus rapide ?


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Quel est la méthode la plus rapide ?
    Salut, je voudrais en fait passer les événements de différentes librairies à une interface commune.

    Alors, j'ai deux solution pour passer les types de événements et les paramètres des événements, cependant je ne sais pas pour laquelle opter.

    1ère solution :

    Je fais un if sur le type de l'événement et en fonction du type de l'événement j'affecte les bons paramètres un exemple :

    Code cpp : 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
     
    SystemEvent popEvent () {
               sf::Event event;
               if (window.pollEvent(event)) {
                   if (event.type == sf::Event::Closed) {
                       SystemEvent sysevent;
                       sysevent.eventID = sf::Event::Closed;
                       sysevent.info.origin = SystemEvent::Origin::Window;
                       sysevent.info.type = SystemEvent::Type::NO_TYPE;
                       sysevent.paramID = SystemEvent::Type::NO_TYPE;
                       return sysevent;
                       //Nothing.
                   } else if (event.type == sf::Event::Resized) {
                       //....
                   }
               }
    }

    La seconde solution est de parcourir tout les états (fenêtre, clavier, souris, etc...) et de générer un événement si il y a un changement d'état. (Ce qui serait plus long si il y a beaucoup d'état à vérifier comme par exemple pour vérifier l'était de chaque touche du clavier. (Mais il y aura moins de if)

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //Exécuter à chaque tout de boucle.
    void produceEvents () {
           for (unsigned int i = 0; i < sf::Keyboard::Key::Count, i++) {
                if (sf::Keyboard::isKeyPressed(i) || keyStates[i] !=(sf::Keyboard::isKeyPressed(i))  {
                    keyStates[i] = !keyStates[i];
                    //On créer l'événement et ou l'ajoute dans la pile.
                }
           }
    }
    //Et on fait la même chose pour la fenêtre, la souris, etc...
    Faut voir avec la complexité maintenant mais, je n'ai jamais très bien compris comment la mesurer.

    Merci d'avance pour votre aide.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Après réflexion je vais opter pour la seconde méthode, le fait que pollEvent n'envoie plus d'event dès qu'une seule touche est relâchée. (ce qui est embêtant si plusieurs touche sont pressées en même temps et qu'on ne veut relâcher qu'une seule touche) me gêne.

    Donc j'aimerais générer les events à ma façon.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    SFML est sensé être un détail d'implémentation, tu as normalement ton propre système. SFML se plug dans l'application principale, et l'idée est juste de le dispatcher.
    Ce qui donne chez moi, dans la boucle principale (ou dans un thread à part qui push pour le main thread)
    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
    sf::Event event;
    		while (window.pollEvent(event))
    		{
    			switch (event.type)
    			{
    			case sf::Event::Closed:
    				window.close();
    				break;
    			case sf::Event::TextEntered:
    				theGame.GetController().OnTextEntered(event.text.unicode);
    				break;
    			case sf::Event::KeyPressed:
    				theGame.GetController().OnKeyPressed(event.key.code);
    				break;
    			case sf::Event::KeyReleased:
    				if (event.key.code == sf::Keyboard::F12)
    					theGame.GetRenderer()->Screenshot(BouSdK::Time::FormatTimestamp(BouSdK::Time::CurrentTimestamp(), "./Screens/%Y-%m-%d_%H-%M-%S.png").c_str());
     
    				theGame.GetController().OnKeyReleased(event.key.code);
    				break;
    			case sf::Event::MouseWheelMoved:
    				theGame.GetController().OnWheel(event.mouseWheel.delta);
    				break;
    			case sf::Event::MouseButtonPressed:
    				theGame.GetController().OnClick(event.mouseButton.button);
    				break;
    			case sf::Event::MouseButtonReleased:
    				theGame.GetController().OnClickReleased(event.mouseButton.button);
    				break;
    			case sf::Event::MouseMoved:
    				theGame.GetController().OnMove(event.mouseMove.x, event.mouseMove.y);
    				break;
    			case sf::Event::MouseEntered:
    				theGame.GetController().OnMouseEnter();
    				break;
    			case sf::Event::MouseLeft:
    				theGame.GetController().OnMouseLeft();
    				break;
    			}
    		}
    Le GetController est une classe sur laquelle j'enregistre mes controlleurs d'évènements (GuiManager, Gameplay, ScriptManager, ...) qui dispatch à leurs acteurs si nécessaire.

    le fait que pollEvent n'envoie plus d'event dès qu'une seule touche est relâchée. (ce qui est embêtant si plusieurs touche sont pressées en même temps et qu'on ne veut relâcher qu'une seule touche) me gêne
    T'es sur que t'as compris comment ça marche ?
    que pollEvent ne retourne rien quand il ne se passe rien c'est.. normal
    à chaque frame tu vas boucler sur l'ensemble des touches du clavier, manette, souris, ... ? bonjour les perfs

    pour avoir régulièrement un évènement lors du maintien d'une touche il faut utiliser RenderWindow::setKeyRepeatEnabledta solution est le meilleur moyen de rater des évènements : je relache et rappuye une touche dans la même frame -> tu le détectes pas
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    pour avoir régulièrement un évènement lors du maintien d'une touche il faut utiliser RenderWindow::setKeyRepeatEnabledta solution est le meilleur moyen de rater des évènements : je relache et rappuye une touche dans la même frame -> tu le détectes pas
    C'est encore pire .
    Non seulement tu va générer un événement à chaque "tour" (au lieu d'avoir un évent de début et de fin), bonjour les perfs .
    Mais en plus, tu peux louper pas mal d'événements si tu as déjà plusieurs touches d'enfoncées sans compter que tu attaques le principe d'encapsulation à grands coups de hache.

    Le tout serait de savoir si on a une garantie que les événements d'appuis et de relâchements sont bien générés même s'il y a déjà plusieurs touches d'enfoncées.
    Si c'est bien générés, alors cela ne sert à rien de parcourir l'état du clavier.

    Pour en revenir à ton switch, je ne sais pas si la complexité d'un switch est en O(n) ou en O(log(n) ) sachant qu'avec un tableau de std::function, on passe en O(1).
    Après, de créer une structure au lieu d'appeler une fonction, il y a des inconvéniants et des avantages.
    • inconvénients
      • il faudra deux évaluations, 1 pour SFML -> structure et 1 pour structure -> action ;

    • avantages
      • les mapping sont un peu plus dynamiques et simples.
      • on a qu'une seule méthode au lieu de ~8, on évite donc de la duplication de code ;
      • on peut aussi transmettre une structure sans apriori sur son contenu (encapsulation), imagine de devoir ajouter un nouveau type d'événement .
      • entre créer une structure et appeler une méthode virtuelle, je pense que la création de la structure est beaucoup plus rapide.


  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Neckara Voir le message
    C'est encore pire .
    Non seulement tu va générer un événement à chaque "tour" (au lieu d'avoir un évent de début et de fin), bonjour les perfs .
    Mais en plus, tu peux louper pas mal d'événements si tu as déjà plusieurs touches d'enfoncées sans compter que tu attaques le principe d'encapsulation à grands coups de hache.
    Quel rapport avec l'encapsulation ?
    Non justement tu ne loupes rien puisque c'est juste fait pour ça. C'est de cette manière que tu gères très simplement le fait que maintenir la touche "a" enfoncée permet d'écrire plusieurs fois aaaaa dans une zone de texte. Et il s'agit de la configuration système. Sinon tu dois te prendre la tête sévère pour gérer un cooldown interne etc... autant dire que tu le gèreras pas tant la complexité est grande.
    Ca ne génère pas un évènement à chaque tour, ça génère un évènement à chaque fois.. que le système en génère un.
    Il suffit de comboter ça avec un set et tu sais trivialement s'il s'agit d'un repeat ou d'un start.

    Citation Envoyé par Neckara Voir le message
    Le tout serait de savoir si on a une garantie que les événements d'appuis et de relâchements sont bien générés même s'il y a déjà plusieurs touches d'enfoncées.
    Encore heureux que oui

    le fait que pollEvent n'envoie plus d'event dès qu'une seule touche est relâchée. (ce qui est embêtant si plusieurs touche sont pressées en même temps et qu'on ne veut relâcher qu'une seule touche) me gêne
    As-tu fait un seul test ?
    Tu appuyes et maintiens 3 touches, tu relâches n'importe laquelle et tu as bien un évènement qui l'indique.

    on a qu'une seule méthode au lieu de ~8, on évite donc de la duplication de code ;
    méthode dans laquelle (lesquelles) tu vas devoir faire 8 if ou.. un switch pour faire la bonne action
    on peut aussi transmettre une structure sans apriori sur son contenu (encapsulation), imagine de devoir ajouter un nouveau type d'événement .
    tu rajoutes une méthode, si personne n'utilise cet évènement il ne la redéfinit pas et laisse son implémentation par défaut qui ne fait rien
    complexité : nulle
    je suppose que c'est ça le rapport avec l'encapsulation plus haut ? avoir une structure magique qui contient tout et n'importe quoi, j'appelle pas vraiment ça de l'encapsulation
    c'est peut-être nécessaire à bas niveau, comme le fait SFML mais pas obligatoire : GLFW fait autrement et ça marche tout aussi bien
    entre créer une structure et appeler une méthode virtuelle, je pense que la création de la structure est beaucoup plus rapide.
    les méthodes listées ici ne sont pas du tout virtuelles, celles dans les acteurs oui, mais entre appeler une méthode spécifique qui indique qu'il s'agit d'un click de souris et devoir dans la méthode traduire l'évènement afin de savoir s'il s'agit d'un click de souris ou d'un appui sur une touche, j'ai un autre avis sur la "plus rapide"
    tu as 4 acteurs qui doivent faire le test, alors que seul l'un d'eux agit sur le click vs 3 implémentations par défaut et 1 qui fera une action
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Non justement tu ne loupes rien puisque c'est juste fait pour ça. C'est de cette manière que tu gères très simplement le fait que maintenir la touche "a" enfoncée permet d'écrire plusieurs fois aaaaa dans une zone de texte. Et il s'agit de la configuration système.
    Prend un éditeur de texte, enfonce A, puis enfonce E. Tu vas voir :
    AAAEEEEEEE et non AAAAAEAEAEAEAEAEAEAEA.

    Dès qu'il y a plusieurs touches enfoncées, ce n'est plus fiable. Normalement il y a une raison au niveau du hardware du clavier.

    Sinon tu dois te prendre la tête sévère pour gérer un cooldown interne etc...
    Donc laisser le nombre d'attaques par seconde (exemple) dépendant du nombre d'events envoyé par seconde par le système ?

    autant dire que tu le gèreras pas tant la complexité est grande.
    En quoi serait-ce complexe d'avoir uniquement un événement "start" et "stop" ?

    Ca ne génère pas un évènement à chaque tour, ça génère un évènement à chaque fois.. que le système en génère un.
    Il suffit de comboter ça avec un set et tu sais trivialement s'il s'agit d'un repeat ou d'un start.
    Pourquoi ne pas tout simplement faire simple et attendre d'avoir l'événement de key release ?


    méthode dans laquelle (lesquelles) tu vas devoir faire 8 if ou.. un switch pour faire la bonne action
    Pas du tout.
    Surtout que la fonction n'est pas obligée de traiter l'événement et peut se contenter de la rediriger.
    Utiliser un std::map est bien plus efficace et pourra mapper n'importe quel évent en O(log2), les comparaisons se faisant en une seule instruction.

    tu rajoutes une méthode, si personne n'utilise cet évènement il ne la redéfinit pas et laisse son implémentation par défaut qui ne fait rien
    complexité : nulle
    Déjà la classe qui recevra l'événement devra être recompilée.
    Et ensuite, tu pars du postula que la classe recevant l'événement saura que personne n'en aura besoin ?
    Déjà, si tel est le cas, ce n'est pas la peine d'ajouter cet événement.
    Ensuite, tu brises l'encapsulation, la classe qui reçoit l'événement ne sait pas nécessairement si les autres classes aux-quelles elle peut éventuellement redirigé l'événement en aurait besoin ou non.

    les méthodes listées ici ne sont pas du tout virtuelles, celles dans les acteurs oui, mais entre appeler une méthode spécifique qui indique qu'il s'agit d'un click de souris et devoir dans la méthode traduire l'évènement afin de savoir s'il s'agit d'un click de souris ou d'un appui sur une touche, j'ai un autre avis sur la "plus rapide"
    Faudra que tu m'explique là .

    tu as 4 acteurs qui doivent faire le test, alors que seul l'un d'eux agit sur le click vs 3 implémentations par défaut et 1 qui fera une action
    Je ne comprend pas ce que tu essayes de nous dire.

Discussions similaires

  1. Quel est le parcours le plus rapide
    Par Atsibat dans le forum WinDev
    Réponses: 14
    Dernier message: 12/02/2013, 22h03
  2. [Firebird] Quel est le code le plus rapide ?
    Par ILP dans le forum Bases de données
    Réponses: 8
    Dernier message: 26/10/2009, 13h01
  3. Réponses: 2
    Dernier message: 27/01/2009, 19h01
  4. PGCD: quelle est la méthode la plus rapide
    Par progfou dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 05/03/2008, 18h26
  5. Réponses: 16
    Dernier message: 19/05/2005, 16h20

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