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

C++ Discussion :

Problème de pointeur ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Par défaut Problème de pointeur ?
    Bonjour tout le monde actuellement j'ai coder plusieurs "outils" pour prochainement la création d'un simple jeu. Là j'en suis à l'étape des input ( Boutons, Champs, Champs multiligne, case, etc... ). Pour éviter d'avoir trop de ressources à charger, j'ai créer un manager qui s'occupe :
    - De charger les textures dans la cg
    - De l'ajouts de différents input tel que les boutons
    - De l’affichage de ceux ci (je leur donne les pointeurs des textures à utiliser)
    - Du test pour savoir si l'on à cliqué dessus
    - Et cetera...
    Pour créer les boutons et autres, je n'ai pas eu de problèmes. Mais depuis que j'utilise le Manager que j'ai créé, j'ai pus me rendre compte que cela ne fonctionne pas très bien.
    En faite je crée trois bouton.
    Les trois s'affiche sans problème mais seul le premier bouton fonctionne, si je clique dessus il change d'état et de textures. Les autres ne réagisse pas du tout !

    Voici le code actuel :

    La classe Button
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
    class Button : public sf::Drawable, public sf::Transformable
        {
        public:
     
        Button( std::string name, bs::Vector4f def, sf::Texture *texture ) : b_name{name}, b_array(sf::Quads, 4), b_state{State::DEFAULT}
        {
            b_texture = texture;
     
            b_array[0].position = sf::Vector2f(0,0);
            b_array[1].position = sf::Vector2f(def.a.x,0);
            b_array[2].position = sf::Vector2f(def.a.x,def.a.y);
            b_array[3].position = sf::Vector2f(0,def.a.y);
     
            b_array[0].texCoords = sf::Vector2f(0,0);
            b_array[1].texCoords = sf::Vector2f(def.a.x,0);
            b_array[2].texCoords = sf::Vector2f(def.a.x,def.a.y);
            b_array[3].texCoords = sf::Vector2f(0,def.a.y);
     
            this->setPosition(def.b);
            b_size = def.a;
        }
     
        void setTextureOnPress( sf::Texture *texture )
        {
            b_texturePress = texture;
        }
     
        void setTextureOnHover( sf::Texture *texture )
        {
            b_textureHover = texture;
        }
     
        sf::Vector2f size() const
        {
            return b_size;
        }
     
        bool isTouch( sf::Vector2f pos )
        {
            if( pos.x < this->getPosition().x + size().x && pos.x > this->getPosition().x )
                if( pos.y < this->getPosition().x + size().y && pos.y > this->getPosition().y )
                    return true;
     
            return false;
        }
     
        void press()
        {
            b_state = State::PRESSED;
        }
     
        void release()
        {
            b_state = State::DEFAULT;
        }
     
        bool tried()
        {
            if( b_state == State::PRESSED )
                return true;
            return false;
        }
     
        std::string name() const
        {
            return b_name;
        }
     
        private:
     
        virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
        {
            states.transform *= getTransform();
            if( b_state == State::HOVER )
                states.texture = b_textureHover;
            else if ( b_state == State::PRESSED )
                states.texture = b_texturePress;
            else
                states.texture = b_texture;
            target.draw(b_array, states);
        }
     
        std::string const b_name;
        sf::Texture *b_texture;
        sf::Texture *b_textureHover;
        sf::Texture *b_texturePress;
        sf::VertexArray b_array;
        State b_state;
        sf::Vector2f b_size;
     
        };
    La classe Manager

    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    class Manager : public sf::Drawable, public sf::Transformable
        {
        public:
     
            Manager(){this->load();}
     
            void add( std::string name, ButtonType type, bs::Vector4f shape )
            {
                switch(type)
                {
                case ButtonType::NORMAL:
                    {
                        std::map<ButtonType,sf::Texture>::iterator it;
                        it = m_textures.find(ButtonType::NORMAL);
                        m_buttons.push_back(new Button(name,shape,&it->second));
                    }
     
                    break;
                default:
                    break;
                }
     
            }
     
            std::string trigger( sf::Vector2f pos )
            {
                std::string rsl;
     
                for( size_t i{0}; i < m_buttons.size(); i++ )
                {
                    if( m_buttons[i]->isTouch(pos) )
                    {
                        if( m_buttons[i]->tried() )
                        {
                            m_buttons[i]->release();
                            rsl = m_buttons[i]->name();
                        }
                        else
                        {
                            m_buttons[i]->press();
                        }
                    }
                }
     
                return rsl;
            }
     
        private:
     
        void load()
        {
            sf::Texture t;
            m_textures[ButtonType::NORMAL] = t;
     
            if(!m_textures[ButtonType::NORMAL].loadFromFile("C:/Test/f.png"))
                std::cout << "Erreur";
        }
     
        virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
        {
            for( size_t i{0}; i < m_buttons.size(); i++ )
            {
                target.draw(*m_buttons[i]);
            }
        }
     
        std::map<ButtonType,sf::Texture> m_textures;
        std::vector<Button*> m_buttons;
     
        };
    Le code qui crée les boutons

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void load( Loadable l, Input::Manager &manager )
        {
            manager.add("Play", Input::ButtonType::NORMAL, bs::Vector4f(120,30,100,100));
            manager.add("Quit", Input::ButtonType::NORMAL, bs::Vector4f(120,30,100,150));
            manager.add("Options", Input::ButtonType::NORMAL, bs::Vector4f(120,30,100,200));
        }
    bs::Vector4f, ButtonType, State, Loadable

    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
     
    enum Loadable{ MENU, HUD };
     
    enum ButtonType{NORMAL, PLAY, VALID, CANCEL, QUIT, BUY, SELL};
     
    enum State{DEFAULT,PRESSED,HOVER};
     
    struct Vector4f
        {
            Vector4f(){}
            Vector4f( float x, float y, float z, float w)
            {
                sf::Vector2f v(x,y);
                a = v;
                v.x = z; v.y = w;
                b = v;
            }
     
            sf::Vector2f a;
            sf::Vector2f b;
        };
    Un code pour tester l'ensemble

    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
     
    sf::RenderWindow window;
        window.create(sf::VideoMode(640,480), "Test", sf::Style::Default);
     
        Input::Manager *m = new Input::Manager();
        bs::load(Loadable::MENU, *m);
     
        while(window.isOpen())
        {
            sf::Event e;
            while( window.pollEvent(e))
            {
                if( e.type == sf::Event::MouseButtonPressed )
                    if( m->trigger(sf::Vector2f( sf::Mouse::getPosition(window).x, sf::Mouse::getPosition(window).y )  ) != "" )
                    {
                       //st
                    }
                if( e.type == sf::Event::MouseButtonReleased )
                    if( m->trigger(sf::Vector2f( sf::Mouse::getPosition(window).x, sf::Mouse::getPosition(window).y )  ) != "" )
                    {
                       //st
                    }
            }
     
            window.clear(sf::Color(230,230,230));
            window.draw(*m);
            window.display();
        }
    Merci de votre aide, je suis un peu perplexe pour le coup x)

    Ps: Pour le moment le code n'est pas du tout "sécurisé" mais j'aimerais déjà qu'il fonctionne avant de plus m'avancer

  2. #2
    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
    if( pos.y < this->getPosition().x + size().y && pos.y > this->getPosition().y ) ?
    les passages de paramètre en copie à tout va
    une conception qui a l'air un peu étrange
    un manager drawable et transformable ça sonne faux
    une const-correctness pas toujours respectée
    une allocation dynamique inutile de Inputs::Manager dans le main
    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.

  3. #3
    Membre très actif
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Par défaut
    Citation Envoyé par Bousk Voir le message
    if( pos.y < this->getPosition().x + size().y && pos.y > this->getPosition().y ) ?
    les passages de paramètre en copie à tout va
    une conception qui a l'air un peu étrange
    un manager drawable et transformable ça sonne faux
    une const-correctness pas toujours respectée
    une allocation dynamique inutile de Inputs::Manager dans le main
    Pour les paramètres en copie à chaque fois je ne sais pas si c'est réellement utile de faire une const& donc soit je ne fait que des copies et on me dit que c'est inutile, soit j'en fait pas et on me dit que ça ne vas pas non plus x)
    Le manager drawable ne vas pas le rester longtemps, c'est complètement illogique donc je ferais une méthode draw() ?
    Pour l'alloc dynamique en soit ce n'est pas faux, c'est juste inutile pour le moment mais je ne ferais pas non plus Inuput::manager manager car je veux en faire un singleton une fois mes problèmes et le code corrigé
    Je précise aussi que je n'ai jamais fait ce genre de chose donc mon code change littéralement à chaque fois que je remarque/apprend que je fait mal certaine choses.
    Pour ce qui en est le la const-correctness et bien comme dit rien n'est sécurisé, j'ai vu pas mal d'endroit où ça n'allait pas du tout mais pour le moment je me penche sur le fonctionnement ( cela dit ce n'est peut-être pas la meilleur méthode, j'en conçoit )
    Er merci pour l'erreur que j'avais pas vu, donc ça fonctionne mais c'est pas propre comme code x) Je vais le corrigé et reposté le code corrigé pour savoir si il y à encore des problème de conception, des erreurs...

    Peut-tu m'expliquer comment savoir quand il faut faire ou ne pas faire une copie ? ( Normalement je ne fait jamais de copie car je trouve que rien ne doit être copié, sauf qu'on ma fait pas mal de réflexion par rapport à ça, que le gain été trop minime pour être nécessaire... )

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Citation Envoyé par Disixlis Voir le message
    Peut-tu m'expliquer comment savoir quand il faut faire ou ne pas faire une copie ? ( Normalement je ne fait jamais de copie car je trouve que rien ne doit être copié, sauf qu'on ma fait pas mal de réflexion par rapport à ça, que le gain été trop minime pour être nécessaire... )
    En effet, en général on doit éviter de faire une copie et préférer les passages par référence constante. Cette règle est suffisante pour respecter un code sérieux et optimum. En peaufinant on peut trouver des exceptions.
    int f( char x ) semble préférable à int f( char const& x ) car un char est petit (mais avec un processeur type ARM en mode ARM, pourrait mieux optimiser le second!)
    Curieusement Objet operator+( Objet o1 , Objet const& o2 ) est souvent mieux que Objet operator+( Objet const& o1 , Objet const& o2 ), avec un paramètre copié et l'autre passé par référence! Si on écrit le code des fonctions dans les 2 cas, on en voit la raison
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Complexe operator+(Complexe c1, Complexe const& c2) noexcept {
       // il y a eu copie du 1er, ou bien optimisation du passage par RVO 
       c1.real += c2.real;  // on modifie le premier objet
       c1.imag+= c2.imag;
       return c1; // retour par RVO, copie ou move (NRVO rarement)
    }
    Complexe operator+(Complexe const& c1, Complexe const& c2) {
       Complexe x; // nécessité de créer un objet + ou - gros
       x.real = c1.real + c2.real;
       y.imag = c1.imag + c2.imag;
       return x; // retour par NRVO, RVO, copie ou move
    }
    Le second code est statistiquement moins optimal.
    On peut trouver d'autres exemples discutables.

  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
    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
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    J'appuie la réponse de dalfab

    En général (sauf pour les types primitifs), les paramètres sont passés par référence constante.

    Cependant, lorsque dans la fonction ou méthode appelée, si on effectue de toutes façons une copie de paramètre, alors il se peut qu'il soit optimal de faire un passage par valeur.
    Faire une recherche sur "copy and swap idiom"; ici par exemple
    http://stackoverflow.com/questions/3...and-swap-idiom
    il est proposé une bonne explication avec un exemple détaillé.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de pointeurs..embrouillé
    Par Frenchy dans le forum C++
    Réponses: 11
    Dernier message: 10/03/2005, 16h33
  2. Problème de pointeur avec un TQuery
    Par Oluha dans le forum Bases de données
    Réponses: 3
    Dernier message: 25/01/2005, 13h57
  3. Problème de pointeur
    Par toma_lille dans le forum C++
    Réponses: 1
    Dernier message: 07/12/2004, 21h26
  4. [MFC] Problème de pointeur !!
    Par acastor dans le forum MFC
    Réponses: 7
    Dernier message: 19/03/2004, 15h50
  5. TBitmap et problèmes de pointeurs...
    Par benj63 dans le forum C++Builder
    Réponses: 8
    Dernier message: 28/07/2003, 13h39

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