[ImageManager] Images qui ne sont pas chargées ? Pb mémoire?

Bonjour 4ian,

je travaille encore sur l’objet Tableaux, et j’ai ajouté la possibilité d’afficher une image à la place d’un texte.
Pour afficher une image, l’utilisateur met en texte d’une des case :

Array::Picture=UNEIMAGE.png

J’ai crée une fonction qui affiche le texte ou qui mets l’image si l’utilisateur met ce qu’il y a ci-dessus :

[code]void ArrayShowerObject::DrawText(sf::RenderWindow& window,
std::string text,
float PosX,
float PosY,
sf::Color color,
sf::Font font,
int fontSize)
{
if(text.size() >= 15 && text.substr(0, 15) == “Array::Picture=”)
{
//On veut afficher une image
int imageNameSize = text.size() - 15;
std::string imageName = text.substr(15, imageNameSize);

    if(actualScene->game->imageManager->HasImage(imageName) == true)
    {
        //actualScene est un pointeur initialisé dans la fonction "LoadRessources" et qui renvoi à la scène actuelle.
        sf::Image imageToShow = *(actualScene->game->imageManager->GetSFMLImage(imageName));
        sf::Sprite spriteToShow(imageToShow);
        spriteToShow.SetPosition(PosX, PosY);
        window.Draw(spriteToShow);
    }
}
else
{
    //Affichage d'un texte
    sf::Text texte(text, sf::Font::GetDefaultFont(), fontSize);
    texte.SetPosition(PosX, PosY);
    texte.SetColor(color);

    window.Draw(texte);
}

}[/code]

Ca marche très bien, sauf quand plusieurs cases (côte à côte) ont une image (pas forcément la même) : certaines cases affichent leur image, d’autre non, c’est assez aléatoire.
Si il y a qu’une case de mon tableau qui demande à avoir une image, l’image s’affiche dans tous les cas, mais c’est quand plusieurs cases qui demande des images, elles s’affichent pas toute.

Un petit speech sur les pointeurs intelligents pour commencer :
Voilà le prototype de GetSFMLImage :

boost::shared_ptr<sf::Image> GetSFMLImage(std::string name) const;

Note le fait qu’on utilise boost::shared_ptr. Regardons la description de la classe :

En fait, l’image manager te renvoie un pointeur intelligent ( boost::shared_ptr ) vers l’image voulue.
Ces pointeurs intelligents sont très pratiques :
-Quand plus aucun pointeur intelligent ne pointe sur une image ( C’est à dire, quand personne n’utilise l’image ), celle ci est détruite.
-Quand plusieurs objets demandent la même image, l’ImageManager renvoie toujours un pointeur intelligent qui point sur la même image.
Ainsi, les pointeurs intelligents me permettent d’éviter facilement les copies tout en détruisant l’image si elle n’est plus utilisée.

C’est là qu’arrive notre petit soucis : Pour signaler à l’Image manager que tu utilise son image, il faut que tu garde en vie le pointeur intelligent qu’il t’a renvoyé. Sinon, vu que tu aura laissé tombé le pointeur intelligent, plus personne n’utilisera l’image, et donc celle ci sera déchargée de la mémoire.

Bon, le truc est qu’ici, tu fais une copie de l’image avant de l’afficher, donc normalement, ça devvvvvvrrait marcher. Mais je pense que justement, le pointeur intelligent est détruit dès que tu le déréference ( avec l’étoile * ) : A ce moment là, si t’a du bol, les pixels sont toujours en mémoire, sinon il disparaissent. Enfin, sur ce point je suis pas trop spur.

Question performance justement, c’est pas l’idéal de demander l’image à chaque réaffichage. Enfin, ce qui va prendre du temps, c’est de la recharger : Il vaut donc mieux indiquer à l’utilisateur de cocher la case comme quoi l’image doit être gardée en mémoire ! Question performance, c’est pas l’idéal non plus de faire la copie. Essaie ceci :

boost::shared_ptr<sf::Image> imageToShow = actualScene->game->imageManager->GetSFMLImage(imageName); sf::Sprite spriteToShow(*imageToShow);

On règle pas le soucis du “Il vaut donc mieux indiquer à l’utilisateur de cocher la case comme quoi l’image doit être gardée en mémoire” mais on évite une copie d’un tableau entier de pixel, et ça, c’est bien et en plus, on garde le pointeur intelligent en vie le temps de l’affichage. Avec un peu de bol, ça va régler le soucis.

Ok, merci, ça marche beaucoup mieux et rapidement (il faut demander que les images soient conservé en mémoire également). :smiley: