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

Auteur Sujet: [RESOLU]Plantage au niveau des threads.  (Lu 2666 fois)

0 Membres et 1 Invité sur ce sujet

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
[RESOLU]Plantage au niveau des threads.
« le: Juillet 02, 2012, 03:04:47 pm »
Salut!

Alors je m'explique j'essaye d'afficher des animations et de les supprimer dans mon éditeur, j'ai d'abord essayer de le faire sans utiliser un thread et la ça marche :

    vector<Anim*> anims = map->gridMap->getAnims();
    for (int i = 0; i < anims.size(); i++) {
        if (anims[i]->isRunning() && anims[i]->getElapsedTime() > anims[i]->getFrameRate()) {
            Tile *prev = anims[i]->getCurrentTile();
            anims[i]->nextImage();
            Tile *newTile = anims[i]->getCurrentTile();
            Vec2f centerView (centerView.x, centerView.y);
            map->gridMap->changeAnimTile(centerView, prev, newTile);
            anims[i]->resetClock();
        }
    }
 

Mes animations comme toutes mes tiles sont ajouté dans une grille virtuelle pour des question d'optimisation, bref voici la méthode qui les efface :

void GridMap::removeAnim (Anim *anim) {

    Vec2f tCorners[4];
    Vec2f position (anim->getPosition().x, anim->getPosition().y);
    Vec2f center (anim->getCenter().x, anim->getCenter().y);
    tCorners[0] = Vec2f (position.x - center.x, position.y - center.y);
    tCorners[1] = Vec2f (position.x + center.x, position.y - center.y);
    tCorners[2] = Vec2f (position.x - center.x, position.y + center.y);
    tCorners[3] = Vec2f (position.x + center.x, position.y + center.y);
    int s = sizeof(tCorners) / sizeof (Vec2f);
    for (int i = 0; i < s; i++) {

        CellMap *cellMap = getGridCellAt(tCorners[i]);
        if (cellMap != NULL) {
           cellMap->removeEntity(anim, anim->getZOrder());
           if (!cellMap->isEntityInside())
                removeCellMap(cellMap);
        }
    }
}
 

Après j'ai essayer de changer les tiles des animations avec un thread, donc j'ai créer une classe qui hérite de thread et j'ai mis le code dans la méthode run :

void AnimListener::Run () {
    while (running) {
        globalMutex.Lock();
        vector<Anim*> anims = canvas->getMap().gridMap->getAnims ();
        for (int i = 0; i < anims.size(); i++) {

            if (anims[i]->isRunning() && anims[i]->getElapsedTime() > anims[i]->getFrameRate()) {
                Tile *prev = anims[i]->getCurrentTile();
                anims[i]->nextImage();
                Tile *newTile = anims[i]->getCurrentTile();
                Vec2f centerView (canvas->getCenterView().x, canvas->getCenterView().y);
                canvas->getMap().gridMap->changeAnimTile(centerView, prev, newTile);
                anims[i]->resetClock();
            }
        }
        globalMutex.Unlock();
    }
}
 
Malheureusement l'application plante et se termine en renvoyant comme erreur un std::bad_alloc dès que je veux effacer une animation.

Il m'indique que ça plante à cet endroit :

vector<Anim*> GridMap::getAnims () {
    vector<Anim*> allAnims;
    for (int i = 0; i < casesMap.size(); i++) {
        CellMap *cell = casesMap[i];
        for (int l = 0; l < 20; l++) {

            for (int n = 0; n < [s][color=red]cell->getEntitiesInside()[l].size()[/color][/s]; n++) {
                 if (cell->getEntityInside(n, l)->getType() == Entity::E_ANIMATION) {
                    bool contains = false;
                    for (int k = 0; k < allAnims.size(); k++) {
                        if (allAnims[k] == cell->getEntityInside(n, l))
                            contains = true;
                    }
                    if (!contains) {

                        allAnims.push_back(dynamic_cast<Anim*>(cell->getEntityInside(n, l)));
                    }
                 }

            }
        }

    }
    return allAnims;
}
 

Il me renvoie a la méthode size de la classe vector :
 size() const
      { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
 

Et je ne trouves pas l'erreur. =/ (que j'essaye avec ou sans Mutex cela plante. =/)

Merci d'avance pour votre aide.
« Modifié: Juillet 03, 2012, 10:00:41 am par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Plantage au niveau des threads.
« Réponse #1 le: Juillet 02, 2012, 03:37:06 pm »
Sûrement un problème d'accès concurrent. Mais là avec tout ce code c'est difficile à voir. Cependant je vois que tu as un mutex à un seul endroit, alors que logiquement il devrait y avoir deux parties verrouillées (à moins que tu ne montres pas tout).

Sinon essaye de degrossir le code, là c'est assez indigeste on n'arrive pas trop à se concentrer sur le vrai problème. Si tu arrivais à écrire un code minimal qui reproduit le problème mais sans ton code original avec lagestion de map etc. ce serait top.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Plantage au niveau des threads.
« Réponse #2 le: Juillet 02, 2012, 03:45:11 pm »
Oui un problème d'accès concurrent je ne vois que ça.

Au niveau du code, je vais voir pour essayer d'en faire un plus simple, et de tester..., parce que j'avoue que je débute un peut dans se domaine avec se système de mutex.

Edit : Bah je viens de déclarer mon mutex dans le main et le passer à mes 2 classes, en faisant des appelle à Lock et Unlock dans mes 2 fonctions. (celle qui efface l'animation et l'autre qui change les tiles des animations.) et ça marche.

J'avais en effet fait une bêtise, je n'avais pas bien regarder le tutoriel du coup j'ai utiliser le mutex uniquement dans un seul thread..., merci Laurent maintenant ça marche.  :D
« Modifié: Juillet 02, 2012, 05:08:12 pm par Lolilolight »

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Plantage au niveau des threads.
« Réponse #3 le: Juillet 03, 2012, 10:00:09 am »
Bon bah j'ai trouvé le problème technique. :)
Donc je passe le sujet en résolu.