mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-01-26 02:07:26 +00:00
attempt to fix crash when loading a saved game on a map with an already collected health upgrade
This problem might have been introduced in 06270eaac0
but not sure.
The crash could happen due to a use-after-free memory access:
When deleting an entity with skel in postInit(), deletion would be
delayed by 1 frame because that is how entity_delete() works.
During deletion, RenderObject::children were removed and deleted
but SkeletalSprite::bones still had those pointers.
Additionally an object would delete its children in onUpdate() after
safeKill(), and still proceed to run scripts, which would then possibly
access freed memory too.
This fix causes children to not be deleted until we're out of the update()
cycle, and instead delete children together with the root object.
This commit is contained in:
parent
008574d913
commit
9e2c640b51
4 changed files with 18 additions and 3 deletions
|
@ -781,7 +781,8 @@ void RenderObject::onUpdate(float dt)
|
|||
{
|
||||
if (isDead()) return;
|
||||
|
||||
updateLife(dt);
|
||||
if(!updateLife(dt))
|
||||
return;
|
||||
|
||||
// FIXME: We might not need to do lifetime checks either; I just
|
||||
// left that above for safety since I'm not certain. --achurch
|
||||
|
@ -863,7 +864,7 @@ void RenderObject::onUpdate(float dt)
|
|||
}
|
||||
}
|
||||
|
||||
void RenderObject::updateLife(float dt)
|
||||
bool RenderObject::updateLife(float dt)
|
||||
{
|
||||
if (decayRate > 0)
|
||||
{
|
||||
|
@ -871,6 +872,7 @@ void RenderObject::updateLife(float dt)
|
|||
if (life<=0)
|
||||
{
|
||||
safeKill();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (fadeAlphaWithLife && !alpha.isInterpolating())
|
||||
|
@ -878,6 +880,7 @@ void RenderObject::updateLife(float dt)
|
|||
|
||||
alpha = life/maxLife;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderObject::unloadDevice()
|
||||
|
|
|
@ -295,7 +295,7 @@ protected:
|
|||
virtual void deathNotify(RenderObject *r);
|
||||
virtual void onEndOfLife() {}
|
||||
|
||||
void updateLife(float dt);
|
||||
bool updateLife(float dt);
|
||||
|
||||
// Is this object or any of its children rendered in pass "pass"?
|
||||
bool hasRenderPass(const int pass) const;
|
||||
|
|
|
@ -87,6 +87,10 @@ Bone::Bone() : CollideQuad()
|
|||
stripVert = false;
|
||||
}
|
||||
|
||||
Bone::~Bone()
|
||||
{
|
||||
}
|
||||
|
||||
ParticleEffect *Bone::getEmitter(unsigned slot) const
|
||||
{
|
||||
return slot < emitters.size() ? emitters[slot] : NULL;
|
||||
|
@ -807,6 +811,12 @@ SkeletalSprite::~SkeletalSprite()
|
|||
{
|
||||
}
|
||||
|
||||
void SkeletalSprite::destroy()
|
||||
{
|
||||
bones.clear(); // they are added as children too, so the next call will do the actual deletion
|
||||
RenderObject::destroy();
|
||||
}
|
||||
|
||||
void SkeletalSprite::setAnimationKeyNotify(RenderObject *r)
|
||||
{
|
||||
animKeyNotify = r;
|
||||
|
|
|
@ -47,6 +47,7 @@ class Bone : public CollideQuad
|
|||
friend class SkeletalSprite;
|
||||
public:
|
||||
Bone();
|
||||
virtual ~Bone();
|
||||
void setAnimated(int a);
|
||||
|
||||
enum {
|
||||
|
@ -227,6 +228,7 @@ public:
|
|||
|
||||
SkeletalSprite();
|
||||
virtual ~SkeletalSprite();
|
||||
virtual void destroy();
|
||||
|
||||
void loadSkeletal(const std::string &fn);
|
||||
bool saveSkeletal(const std::string &fn);
|
||||
|
|
Loading…
Reference in a new issue