Closed KelvinShadewing closed 1 year ago
So I followed the chain of functions that get called starting from sqDeleteSprite, and fortunately the issue in question is pretty easy to fix. That said, probably best to start from the top, as I'm unsure of where the mix-up stems from.
SQInteger sqDeleteSprite(HSQUIRRELVM v) {
SQInteger i;
sq_getinteger(v, 2, &i);
if(i >= vcSprites.size()) return 0;
//pretty straight-forward, delete is used to invoke the destructor for the sprite
if(vcSprites[i] != 0) delete vcSprites[i];
return 0;
};
...then since there is a destructor defined for the xySprite class, it jumps to here:
xySprite::~xySprite() {
//again pretty simple, the memory is made inaccessible by removing the pointer to the object
if(numero == vcSprites.size() - 1) vcSprites.pop_back(); else vcSprites[numero] = 0;
xyDeleteImage(tex);
};
...and now we wind up where the problem is at, in xyDeleteImage:
void xyDeleteImage(Uint32 tex) {
if(tex > vcSprites.size()) return;
//the associated vcTexture is deleted here
SDL_DestroyTexture(vcTextures[tex]);
//but then it's the vcSprites vector that gets modified, again
if(tex < vcSprites.size() - 1) vcSprites[tex] = 0;
else vcSprites.pop_back();
};
So yeah, seems like the problem was just that the wrong pointers are getting removed after deleting the texture. It's a little surprising that this didn't creep up sooner, but based on where this issue stemmed from, my guess is that it only worked out by chance, as typically sprites were only deleted when they were also stored at the end of vector. Which combined with textures also typically being in 1-to-1 relation with the sprites, would cause the initial if-statement in xyDeleteImage to trigger.
That last part being said, I would be mindful of just outright deleting the texture in response to the sprite being deleted. Primarily because of the newSpriteFT bind, which opens the door for one texture to be used in multiple sprites. So if any of one of those sprites were to get deleted, then the texture would be corrupted for the others. You would most likely need some form of associative container (i.e. a map) to track which textures are used by which sprites, and then use that to determine when it's actually safe to delete them.
Should be fixed by https://github.com/KelvinShadewing/brux-gdk/pull/44, thus making this closeable
Using
deleteSprite()
will sometimes delete the wrong image. Here's the Valgrind output: