From 4a1e2b6a68095e6bb7c212be57abb5a1509739b9 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 2 May 2018 22:22:23 +0300 Subject: [PATCH] Fix a stale pointer issue with Animation Now that keyframe information is stored in a vector it's no longer guaranteed that pointers to them stay valid after push_back. Re-link all TimedKeyFrames if the vector gets reallocated. --- source/animation.cpp | 33 ++++++++++++++++++++++----------- source/animation.h | 1 + 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/source/animation.cpp b/source/animation.cpp index 61c21ce8..ccd37bca 100644 --- a/source/animation.cpp +++ b/source/animation.cpp @@ -42,16 +42,33 @@ const string &Animation::get_uniform_name(unsigned i) const } void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame &kf) +{ + RefPtr kfr(&kf); + kfr.keep(); + add_keyframe(t, kfr); +} + +void Animation::add_keyframe(const Time::TimeDelta &t, const RefPtr &kf) { if(!keyframes.empty() && t=keyframes.capacity()); + + keyframes.push_back(TimedKeyFrame(*this)); + TimedKeyFrame &tkf = keyframes.back(); tkf.time = t; - tkf.keyframe = &kf; - tkf.keyframe.keep(); + tkf.keyframe = kf; + + if(realloc) + { + for(unsigned i=1; i1) + tkf.prev = &tkf-1; + prepare_keyframe(tkf); - keyframes.push_back(tkf); } void Animation::set_looping(bool l) @@ -61,8 +78,6 @@ void Animation::set_looping(bool l) void Animation::prepare_keyframe(TimedKeyFrame &tkf) { - tkf.prev = (keyframes.empty() ? 0 : &keyframes.back()); - const KeyFrame::UniformMap &kf_uniforms = tkf.keyframe->get_uniforms(); for(KeyFrame::UniformMap::const_iterator i=kf_uniforms.begin(); i!=kf_uniforms.end(); ++i) { @@ -334,11 +349,7 @@ void Animation::Loader::keyframe_inline() else load_sub(*kf); - TimedKeyFrame tkf(obj); - tkf.time = current_time; - tkf.keyframe = kf; - obj.prepare_keyframe(tkf); - obj.keyframes.push_back(tkf); + obj.add_keyframe(current_time, kf); } void Animation::Loader::interval(float t) diff --git a/source/animation.h b/source/animation.h index 929cb13f..a5f77b46 100644 --- a/source/animation.h +++ b/source/animation.h @@ -120,6 +120,7 @@ public: void add_keyframe(const Time::TimeDelta &, const KeyFrame &); private: + void add_keyframe(const Time::TimeDelta &, const RefPtr &); void prepare_keyframe(TimedKeyFrame &); public: -- 2.45.2