Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: sf::Drawable et virutal method/destructeur  (Lu 5624 fois)

0 Membres et 2 Invités sur ce sujet

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
sf::Drawable et virutal method/destructeur
« le: Janvier 06, 2015, 04:49:38 pm »
Bonjour.

J'ai encore un soucis avec sf::Drawable...Il semblerait qu'il ait une virtual methode pure...autrement dit, si j'ai bien compris, une methode qu'il faut impérativement construire dans l'objet hérité, ici sf::Drawable.
Résultat, quand je détruit une EI (Entite Image, hérité de sf::Drawable ), il plante...

J'ai bien essayé avec le destructeur basic


~EI(){}

 

mais il plante toujours

lors de la destruction d'objet qui contient une EI, il me dit, en console :

" pure virtual method called // terminate called without an active exception "

voici ma sf::Drawable:




class EI : public sf::Drawable
{
public:


    friend struct MonFoncteur;

    void recoitTexture(sf::Texture *texture)
    {
        m_texture = texture;
        m_actif = true;
    }
    void recoitVertex(sf::Vertex vertex[4])
    {
        m_tableauVertex[0] = vertex[0];
        m_tableauVertex[1] = vertex[1];
        m_tableauVertex[2] = vertex[2];
        m_tableauVertex[3] = vertex[3];

    }
    void active(bool actif)
    {
        m_actif = actif;
    }
    void recoitZ(int z)
    {
        m_z = z;
    }

private:

    virtual void draw(sf::RenderTarget& cible, sf::RenderStates states) const
    {
        if(m_actif)
        {
        cible.draw(m_tableauVertex,4, sf::Quads, m_texture);
        }
    }

    bool m_actif;
    float m_z;
    sf::Vertex m_tableauVertex[4];
    sf::Texture *m_texture;

};

struct MonFoncteur
{
   bool operator() (const EI* un, const EI* deux) const
   {
        return un->m_z < deux->m_z;
   }
};


 



Merci si vous pouvez m'aider  :D


Cmdu76

  • Full Member
  • ***
  • Messages: 194
    • Voir le profil
Re : sf::Drawable et virutal method/destructeur
« Réponse #1 le: Janvier 06, 2015, 05:46:01 pm »
Salut !

Je crois que ton erreur est ici :

cible.draw(m_tableauVertex,4, sf::Quads, m_texture);

Essaye plutôt comme ça :

virtual void draw(sf::RenderTarget& cible, sf::RenderStates states) const
{
    if (m_actif)
    {  
        states.texture = &m_texture;
        cible.draw(m_tableauVertex,4,sf::Quads,states);
    }
}

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #2 le: Janvier 06, 2015, 06:59:25 pm »
non. (mais merci quand même ;) )

En fait ca vient plutôt d'une fonction virtual pure que je ne trouve pas dans la doc, et que je n'ose pas farfouiller...Ca pourrait peut être venir de mes pointeurs intélligents, mais j'en doute...

Pour moi la preuve absolu que ça vient du constructeur/destructeur que je n'ai pas du implémenté correctement , c'est le fait que si je construit une entité Image sans même lui demander d'afficher ou quoi que ce soit, (bien qu'elle puisse s'afficher sans problème ),  il ne plante qu'a sa destruction, me parlant de virual method...Je continue donc a chercher dans ce sens. 

également lors d'une allocation dynamique de nouvelles EI, durant le jeux, il me sort la même erreur(probablement donc, le même probleme, mais avec le constructeur...). Pourant cette même allocation dynamique d'EI marche bien dans un chargement...

Bref. Je vais continuer a cherche, espérant trouver, et merci si vous pouvez m'aider   :P

ps : depuis que j'ai suivis vos conseils, J'ai pu réussir a afficher plus de 16000 objets avec collisions etc.., sans que ca rame, soit 30 fois plus qu'avant !
donc merci, je suis sur la bonne voie...mais encore et toujours des embûches viennent se mettre sur la route :'(

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #3 le: Janvier 06, 2015, 07:06:53 pm »
Utilise ton debugger pour trouver l'appel qui plante. N'essaye pas de deviner ;)
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #4 le: Janvier 07, 2015, 09:15:01 am »
J'ai essayé avec le debugger, mais il n'est pas très causant. (il m'a quand même confirmé des choses )

je suis certain en tout cas que la destruction d'une EI fait bien planter le programme.Un simple test le confirme:




void NiveauTest::charger()
{
     m_testEI = new EI;
     m_testEI->recoitTexture(&textureTest);
     m_testEI->recoitVertex(m_vertex);

}


void NiveauTest::jouer() //ca tourne
{
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::R))
        {
        delete[]m_test;//ca plante
        }
}

 

J'appuie sur R et...plantage non négociable.
Pourtant je ne lui demande rien d'autre que d'être crée (pas d'affichage, ni d'uptade) et détruit. C'est bien une preuve, il me semble non ?  ???

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #5 le: Janvier 07, 2015, 09:23:10 am »
Ce morceau de code crée une variable nommée m_testEI, et détruit un tableau nommé m_test. On ne peut pas vraiment t'aider dans ces conditions.
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #6 le: Janvier 07, 2015, 10:13:35 am »
Oui, pardon, j'avais d'abord essayé ainsi, mais ca plantait pareil...

void NiveauTest::jouer() //ca tourne
{
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::R))
        {
        delete m_test;//ca plante
        }
}
 

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #7 le: Janvier 07, 2015, 10:26:11 am »
Ce quelques lignes de code sont correctes, c'est autre chose qui fait planter.

Il faut que tu reproduises le problème dans un code complet et minimal. Sinon on n'y arrivera jamais, à moins de lire la totalité de ton code source, chose que personne ne va s'amuser à faire ;)
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #8 le: Janvier 07, 2015, 10:36:19 am »
OK. je vais continuer a chercher, je reviendrais peut être avec un code minimal...
« Modifié: Janvier 07, 2015, 12:05:22 pm par mazertys17 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #9 le: Janvier 07, 2015, 12:13:36 pm »
Mon conseil : fais le code minimal tout de suite, c'est le meilleur moyen pour toi de trouver le problème, et pour nous de t'aider. Sinon tu vas potentiellement scruter ton code pendant des heures pour rien.

De manière générale, quand un bug semble trop compliqué à débusquer, simplifier le code est toujours un bon procédé, car en réduisant le contexte tu finis toujours par tomber sur l'élément qui est en cause. C'est mathématique.
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #10 le: Janvier 07, 2015, 03:49:20 pm »
Je pense avoir résolu le problème, mais d'une façon dangereuse, et sans pour autant en avoir déterminer la réel cause. Peut être saurez vous plus, d'expérience, ce qui peut en être.

Il se trouve qu'en remplacant mes EI contenus dans les objets a détruire, par des *EI (alloué dynamiquement au fur a mesur), ca fonctionne.
Je peux également les "delete monEI" sans que ca plante.

Problème plutot contourné que résolu, donc...

Merci en tout cas pour vos conseils.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #11 le: Janvier 07, 2015, 03:54:38 pm »
Citer
Il se trouve qu'en remplacant mes EI contenus dans les objets a détruire, par des *EI (alloué dynamiquement au fur a mesur),
C'est pas déjà le cas dans le code que tu nous as montré précédemment ?
Peux-tu détailler (montrer) la modif en question ?
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #12 le: Janvier 07, 2015, 04:18:20 pm »
C'est exactement ce que tu nous as montré avant :

m_testEI = new EI;
delete m_testEI;

Si tu veux une vraie explication (et une vraie solution), il va falloir fournir un petit effort pour nous montrer quelque chose de complet et minimal, ou au moins cohérent. Sinon tant pis...
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #13 le: Janvier 07, 2015, 04:29:28 pm »
Oui...Je m'étais planté...désolé :-[

...En faisant un test en minimal, j'ai vu que ca plantait parce que tout bêtement, en appuyant sur une touche, il delete le même objet plusieurs fois...en utilisant un bool, pour le faire qu'une fois, ca plante plus...logique...
Vraiment idio... :-X
dsl...

En revanche, il plantait toujours dés qu'il s'agissait d'un objet normal, utilisé dans les attributs d'une class. C'est d'ailleurs toujours un mystère pour moi...mais bon...tant que ca marche. Voici ma nouvelle version de l'objet qui plantait, mais marche bien maintenant depuis que j'ai remplacé EI m_EI par EI *m_EI...

D'ailleurs, pensez vous qu'il serait judicieux, d'en faire un pointeur Intelligent, ou pas forcément necessaire vu mon cas...(une utilisation assez simple )..?


voici l'objet avec les changements:


class CharbonPetit2
{
public:
    CharbonPetit2();
    ~CharbonPetit2();
    ...
    void                                        recoitPtrAfficheur(boost::shared_ptr<Afficheur> ptr_afficheur);
    void                                        cree(string nom, sf::Texture *texture, int tailleImageL, int tailleImageH );
    ...
    void                                        initialise();
    void                                        rafraichi();
    void                                        detruit();
   ...
private:
   ...
    boost::shared_ptr<Afficheur>          m_ptr_afficheur;
    sf::Texture                                       *m_texture;
    sf::Vertex                                         m_vertex[4];
    EI                                                     *m_EI;//ici au lieu de simplement m_EI
   ...
 


void CharbonPetit::cree(string nom, sf::Texture *texture, int tailleImageL, int tailleImageH)
{
    ...
    m_texture = texture ;//du coup je doit mémoriser l'adresse de la texture...
    ...
}


void CharbonPetit::initialise()
{

    m_vertex[0] = sf::Vector2f(m_x                              ,m_y );
    m_vertex[1] = sf::Vector2f(m_x + m_tailleImageL             ,m_y );
    m_vertex[2] = sf::Vector2f(m_x + m_tailleImageL             ,m_y + m_tailleImageH);
    m_vertex[3] = sf::Vector2f(m_x                              ,m_y + m_tailleImageH);

    m_vertex[0].texCoords = sf::Vector2f(0                       , 0);
    m_vertex[1].texCoords = sf::Vector2f(m_tailleImageL          , 0);
    m_vertex[2].texCoords = sf::Vector2f(m_tailleImageL          , m_tailleImageH);
    m_vertex[3].texCoords = sf::Vector2f(0                       , m_tailleImageH);

    m_EI = new EI;
    m_EI->recoitTexture(m_texture);
    m_EI->recoitVertex(m_vertex);
    m_EI->recoitZ(m_y + m_colY);

    m_ptr_afficheur->recoitEI(m_EI); //j'envoi l'adresse a mon afficheur.

    m_collisionSimple.deplace(m_x, m_y);
    m_collisionSimpleDeclencheur.deplace(m_x, m_y);
}


//il tourne avec ses collisions etc...
...


void CharbonPetit2::detruit()
{
    m_ptr_afficheur->efface(m_EI);// je l'enlève du std::multiset de l'afficheur pour plus qu'il soit pris
                                                      //en compte dans l'affichage.
    delete m_EI;//puis il est détruit sans broncher...
}

 

et le tout en vector:


    for(vector<CharbonPetit2>::iterator it = m_charbonPetit2.begin() ; it != m_charbonPetit2.end() ; it++)
    {
        it->rafraichi();
        if(!it->renvoiVie())
        {
           it->detruit();
           m_charbonPetit2.erase(it); //cette fois ci ca marche sans pb...
        }
    }

 

plus aucun problème, ca marche sans planter, et je peux en faire tourner plus de 25 000 sans que ca rame...(au dessus j'ai test qu'avec 1000000, mais la il est pas d'accord  ;D mais j'ai pas besoin d'autant ;) )

voila...Merci pour votre aide, et désolé pour l'erreur  :-[

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : sf::Drawable et virutal method/destructeur
« Réponse #14 le: Janvier 07, 2015, 04:42:43 pm »
Le problème c'est que tu as un std::vector<CharbonPetit2> : dedans les instances de CharbonPetit2 sont copiées de multiples fois. Donc les adresses de EI que tu passes à ton afficheur finissent par ête invalidées. Alors que si tu les alloues dynamiquement, ces adresses ne changent jamais.

A mon avis, c'est sur le tableau d'entités haut-niveau que tu devrait penser à utiliser des allocations dynamiques et des pointeurs intelligents. Puis rendre tes classes d'entités non-copiables (pour éviter les copies implicites accidentelles).

std::vector<std::unique_ptr<CharbonPetit2>>
Laurent Gomila - SFML developer