aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/animations/qabstractanimationjob.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/animations/qabstractanimationjob.cpp')
-rw-r--r--src/qml/animations/qabstractanimationjob.cpp111
1 files changed, 60 insertions, 51 deletions
diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp
index 9e82b63771..a50685ba50 100644
--- a/src/qml/animations/qabstractanimationjob.cpp
+++ b/src/qml/animations/qabstractanimationjob.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/qthreadstorage.h>
@@ -44,6 +8,7 @@
#include "private/qanimationjobutil_p.h"
#include "private/qqmlengine_p.h"
#include "private/qqmlglobal_p.h"
+#include "private/qdoubleendedlist_p.h"
QT_BEGIN_NAMESPACE
@@ -65,6 +30,35 @@ QQmlAnimationTimer::QQmlAnimationTimer() :
{
}
+void QQmlAnimationTimer::unsetJobTimer(QAbstractAnimationJob *animation)
+{
+ if (!animation)
+ return;
+ if (animation->m_timer == this)
+ animation->m_timer = nullptr;
+
+ if (animation->m_isPause)
+ runningPauseAnimations.removeOne(animation);
+
+ if (animation->isGroup()) {
+ QAnimationGroupJob *group = static_cast<QAnimationGroupJob *>(animation);
+ if (const auto children = group->children()) {
+ for (auto *child : *children)
+ unsetJobTimer(child);
+ }
+ }
+}
+
+QQmlAnimationTimer::~QQmlAnimationTimer()
+{
+ for (const auto &animation : std::as_const(animations))
+ unsetJobTimer(animation);
+ for (const auto &animation : std::as_const(animationsToStart))
+ unsetJobTimer(animation);
+ for (const auto &animation : std::as_const(runningPauseAnimations))
+ unsetJobTimer(animation);
+}
+
QQmlAnimationTimer *QQmlAnimationTimer::instance(bool create)
{
QQmlAnimationTimer *inst;
@@ -102,7 +96,7 @@ void QQmlAnimationTimer::updateAnimationsTime(qint64 delta)
//when the CPU load is high
if (delta) {
insideTick = true;
- for (currentAnimationIdx = 0; currentAnimationIdx < animations.count(); ++currentAnimationIdx) {
+ for (currentAnimationIdx = 0; currentAnimationIdx < animations.size(); ++currentAnimationIdx) {
QAbstractAnimationJob *animation = animations.at(currentAnimationIdx);
int elapsed = animation->m_totalCurrentTime
+ (animation->direction() == QAbstractAnimationJob::Forward ? delta : -delta);
@@ -110,7 +104,7 @@ void QQmlAnimationTimer::updateAnimationsTime(qint64 delta)
}
if (animationTickDump()) {
qDebug() << "***** Dumping Animation Tree ***** ( tick:" << lastTick << "delta:" << delta << ")";
- for (int i = 0; i < animations.count(); ++i)
+ for (int i = 0; i < animations.size(); ++i)
qDebug() << animations.at(i);
}
insideTick = false;
@@ -216,16 +210,16 @@ void QQmlAnimationTimer::registerRunningAnimation(QAbstractAnimationJob *animati
void QQmlAnimationTimer::unregisterRunningAnimation(QAbstractAnimationJob *animation)
{
+ unsetJobTimer(animation);
if (animation->userControlDisabled())
return;
if (animation->m_isGroup)
return;
- if (animation->m_isPause)
- runningPauseAnimations.removeOne(animation);
- else
+ if (!animation->m_isPause)
runningLeafAnimations--;
+
Q_ASSERT(runningLeafAnimations >= 0);
}
@@ -280,8 +274,10 @@ QAbstractAnimationJob::~QAbstractAnimationJob()
Q_ASSERT(m_state == Stopped);
if (oldState == Running) {
- Q_ASSERT(QQmlAnimationTimer::instance() == m_timer);
- m_timer->unregisterAnimation(this);
+ if (m_timer) {
+ Q_ASSERT(QQmlAnimationTimer::instance(false) == m_timer);
+ m_timer->unregisterAnimation(this);
+ }
}
Q_ASSERT(!m_hasRegisteredTimer);
}
@@ -306,8 +302,9 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState)
if (m_loopCount == 0)
return;
- if (!m_timer)
- m_timer = QQmlAnimationTimer::instance();
+ if (!m_timer) // don't create a timer just to stop the animation
+ m_timer = QQmlAnimationTimer::instance(newState != Stopped);
+ Q_ASSERT(m_timer || newState == Stopped);
State oldState = m_state;
int oldCurrentTime = m_currentTime;
@@ -335,8 +332,9 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState)
if (oldState == Running) {
if (newState == Paused && m_hasRegisteredTimer)
m_timer->ensureTimerUpdate();
- //the animation, is not running any more
- m_timer->unregisterAnimation(this);
+ // the animation is not running any more
+ if (m_timer)
+ m_timer->unregisterAnimation(this);
} else if (newState == Running) {
m_timer->registerAnimation(this, isTopLevel);
}
@@ -482,8 +480,11 @@ void QAbstractAnimationJob::setCurrentTime(int msecs)
RETURN_IF_DELETED(updateCurrentTime(m_currentTime));
- if (m_currentLoop != oldLoop)
- currentLoopChanged();
+ if (m_currentLoop != oldLoop) {
+ // CurrentLoop listeners may restart the job if e.g. from has changed. Stopping a job will
+ // destroy it, so account for that here.
+ RETURN_IF_DELETED(currentLoopChanged());
+ }
// All animations are responsible for stopping the animation when their
// own end state is reached; in this case the animation is time driven,
@@ -521,6 +522,14 @@ void QAbstractAnimationJob::stop()
setState(Stopped);
}
+void QAbstractAnimationJob::complete()
+{
+ // Simulate the full animation cycle
+ setState(Running);
+ setCurrentTime(m_direction == Forward ? duration() : 0);
+ setState(Stopped);
+}
+
void QAbstractAnimationJob::pause()
{
if (m_state == Stopped) {