summaryrefslogtreecommitdiffstats
path: root/src/animation
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2017-06-29 16:31:49 +0200
committerSean Harmer <sean.harmer@kdab.com>2017-06-30 17:29:43 +0000
commit513b4fbcabfb6c8e67c09c99ab0f1b7f7753a50e (patch)
treed18ed0222b3ec7fc0a08ef2f7f68f83303459526 /src/animation
parentdee403c691233657f636bd8dc40fab65cc0e0f3b (diff)
Fix ClipAnimator crash when removing animators
When passing around animator handles, care must be taken before actually using them since the animator component may have been destroyed in the meantime. Change-Id: Ib963d1422e1626b5a06e5bb157a0b6aab76b961d Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/animation')
-rw-r--r--src/animation/backend/findrunningclipanimatorsjob.cpp1
-rw-r--r--src/animation/backend/handler.cpp26
-rw-r--r--src/animation/backend/handler_p.h3
3 files changed, 30 insertions, 0 deletions
diff --git a/src/animation/backend/findrunningclipanimatorsjob.cpp b/src/animation/backend/findrunningclipanimatorsjob.cpp
index 80739a02b..a8349eb91 100644
--- a/src/animation/backend/findrunningclipanimatorsjob.cpp
+++ b/src/animation/backend/findrunningclipanimatorsjob.cpp
@@ -64,6 +64,7 @@ void FindRunningClipAnimatorsJob::run()
ClipAnimatorManager *clipAnimatorManager = m_handler->clipAnimatorManager();
for (const auto clipAnimatorHandle : qAsConst(m_clipAnimatorHandles)) {
ClipAnimator *clipAnimator = clipAnimatorManager->data(clipAnimatorHandle);
+ Q_ASSERT(clipAnimator);
const bool canRun = clipAnimator->canRun();
m_handler->setClipAnimatorRunning(clipAnimatorHandle, canRun);
diff --git a/src/animation/backend/handler.cpp b/src/animation/backend/handler.cpp
index 04c46b40a..33bc8c9f4 100644
--- a/src/animation/backend/handler.cpp
+++ b/src/animation/backend/handler.cpp
@@ -140,6 +140,29 @@ void Handler::setBlendedClipAnimatorRunning(const HBlendedClipAnimator &handle,
}
}
+// The vectors may get outdated when the application removes/deletes an
+// animator component in the meantime. Recognize this. This should be
+// relatively infrequent so in most cases the vectors will not change at all.
+void Handler::cleanupHandleList(QVector<HClipAnimator> *animators)
+{
+ for (auto it = animators->begin(); it != animators->end(); ) {
+ if (!m_clipAnimatorManager->data(*it))
+ animators->erase(it);
+ else
+ ++it;
+ }
+}
+
+void Handler::cleanupHandleList(QVector<HBlendedClipAnimator> *animators)
+{
+ for (auto it = animators->begin(); it != animators->end(); ) {
+ if (!m_blendedClipAnimatorManager->data(*it))
+ animators->erase(it);
+ else
+ ++it;
+ }
+}
+
QVector<Qt3DCore::QAspectJobPtr> Handler::jobsToExecute(qint64 time)
{
// Store the simulation time so we can mark the start time of
@@ -164,6 +187,7 @@ QVector<Qt3DCore::QAspectJobPtr> Handler::jobsToExecute(qint64 time)
if (!m_dirtyClipAnimators.isEmpty()) {
qCDebug(HandlerLogic) << "Added FindRunningClipAnimatorsJob";
m_findRunningClipAnimatorsJob->removeDependency(QWeakPointer<Qt3DCore::QAspectJob>());
+ cleanupHandleList(&m_dirtyClipAnimators);
m_findRunningClipAnimatorsJob->setDirtyClipAnimators(m_dirtyClipAnimators);
jobs.push_back(m_findRunningClipAnimatorsJob);
if (jobs.contains(m_loadAnimationClipJob))
@@ -182,6 +206,7 @@ QVector<Qt3DCore::QAspectJobPtr> Handler::jobsToExecute(qint64 time)
// If there are any running ClipAnimators, evaluate them for the current
// time and send property changes
+ cleanupHandleList(&m_runningClipAnimators);
if (!m_runningClipAnimators.isEmpty()) {
qCDebug(HandlerLogic) << "Added EvaluateClipAnimatorJobs";
@@ -209,6 +234,7 @@ QVector<Qt3DCore::QAspectJobPtr> Handler::jobsToExecute(qint64 time)
}
// BlendClipAnimator execution
+ cleanupHandleList(&m_runningBlendedClipAnimators);
if (!m_runningBlendedClipAnimators.isEmpty()) {
// Ensure we have a job per clip animator
const int oldSize = m_evaluateBlendClipAnimatorJobs.size();
diff --git a/src/animation/backend/handler_p.h b/src/animation/backend/handler_p.h
index 52892f9d0..97adfdc13 100644
--- a/src/animation/backend/handler_p.h
+++ b/src/animation/backend/handler_p.h
@@ -116,6 +116,9 @@ public:
QVector<Qt3DCore::QAspectJobPtr> jobsToExecute(qint64 time);
+ void cleanupHandleList(QVector<HClipAnimator> *animators);
+ void cleanupHandleList(QVector<HBlendedClipAnimator> *animators);
+
private:
QScopedPointer<AnimationClipLoaderManager> m_animationClipLoaderManager;
QScopedPointer<ClipAnimatorManager> m_clipAnimatorManager;