diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp index 60d6eddb3db43e02663f17ac4e783a5569e78232..1763d7acab2ba797dce8ca267c9391bdeee5920e 100644 --- a/src/quick/items/qquickspriteengine.cpp +++ b/src/quick/items/qquickspriteengine.cpp @@ -107,12 +107,12 @@ QQuickStochasticEngine::~QQuickStochasticEngine() } QQuickSpriteEngine::QQuickSpriteEngine(QObject *parent) - : QQuickStochasticEngine(parent), m_startedImageAssembly(false) + : QQuickStochasticEngine(parent), m_startedImageAssembly(false), m_loaded(false) { } QQuickSpriteEngine::QQuickSpriteEngine(QList<QQuickSprite*> sprites, QObject *parent) - : QQuickStochasticEngine(parent), m_startedImageAssembly(false) + : QQuickStochasticEngine(parent), m_startedImageAssembly(false), m_loaded(false) { foreach (QQuickSprite* sprite, sprites) m_states << (QQuickStochasticState*)sprite; @@ -156,6 +156,8 @@ int QQuickSpriteEngine::pseudospriteProgress(int sprite, int state, int* rowDura int QQuickSpriteEngine::spriteState(int sprite) { + if (!m_loaded) + return 0; int state = m_things[sprite]; if (!m_sprites[state]->m_generatedCount) return state; @@ -175,7 +177,7 @@ int QQuickSpriteEngine::spriteState(int sprite) int QQuickSpriteEngine::spriteStart(int sprite) { - if (!m_duration[sprite]) + if (!m_duration[sprite] || !m_loaded) return m_timeOffset; int state = m_things[sprite]; if (!m_sprites[state]->m_generatedCount) @@ -189,6 +191,8 @@ int QQuickSpriteEngine::spriteStart(int sprite) int QQuickSpriteEngine::spriteFrames(int sprite) { + if (!m_loaded) + return 1; int state = m_things[sprite]; if (!m_sprites[state]->m_generatedCount) return m_sprites[state]->frames(); @@ -212,7 +216,7 @@ int QQuickSpriteEngine::spriteFrames(int sprite) int QQuickSpriteEngine::spriteDuration(int sprite)//Full duration, not per frame { - if (!m_duration[sprite]) + if (!m_duration[sprite] || !m_loaded) return m_duration[sprite]; int state = m_things[sprite]; if (!m_sprites[state]->m_generatedCount) @@ -230,6 +234,8 @@ int QQuickSpriteEngine::spriteDuration(int sprite)//Full duration, not per frame int QQuickSpriteEngine::spriteY(int sprite) { + if (!m_loaded) + return 0; int state = m_things[sprite]; if (!m_sprites[state]->m_generatedCount) return m_sprites[state]->m_rowY; @@ -250,6 +256,8 @@ int QQuickSpriteEngine::spriteY(int sprite) int QQuickSpriteEngine::spriteX(int sprite) { + if (!m_loaded) + return 0; int state = m_things[sprite]; if (!m_sprites[state]->m_generatedCount) return m_sprites[state]->m_rowStartX; @@ -339,6 +347,7 @@ void QQuickSpriteEngine::startAssemblingImage() { if (m_startedImageAssembly) return; + m_loaded = false; //This could also trigger the start of the image loading in Sprites, however that currently happens in Sprite::setSource @@ -477,6 +486,8 @@ QImage QQuickSpriteEngine::assembledImage() qDebug() << "Assembled image output to: " << fPath.arg(acc); #endif + m_loaded = true; + m_startedImageAssembly = false; return image; } @@ -530,7 +541,7 @@ void QQuickStochasticEngine::restart(int index) void QQuickSpriteEngine::restart(int index) //Reimplemented to recognize and handle pseudostates { bool randomStart = (m_startTimes[index] == NINF); - if (m_sprites[m_things[index]]->frameSync()) {//Manually advanced + if (m_loaded && m_sprites[m_things[index]]->frameSync()) {//Manually advanced m_startTimes[index] = 0; if (randomStart && m_sprites[m_things[index]]->m_generatedCount) m_startTimes[index] += qrand() % m_sprites[m_things[index]]->m_generatedCount; @@ -567,6 +578,11 @@ void QQuickStochasticEngine::advance(int idx) void QQuickSpriteEngine::advance(int idx) //Reimplemented to recognize and handle pseudostates { + if (!m_loaded) { + qWarning() << QLatin1String("QQuickSpriteEngine: Trying to advance sprites before sprites finish loading. Ignoring directive"); + return; + } + if (idx >= m_things.count()) return;//TODO: Proper fix(because this has happened and I just ignored it) if (m_duration[idx] == 0) { diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h index f6ef79ca50982f111f486af42aca7b535a6aff1b..d78a10393ef43882a9e9c171a9b806710c7854fe 100644 --- a/src/quick/items/qquickspriteengine_p.h +++ b/src/quick/items/qquickspriteengine_p.h @@ -294,6 +294,7 @@ private: int pseudospriteProgress(int,int,int*rd=0); QList<QQuickSprite*> m_sprites; bool m_startedImageAssembly; + bool m_loaded; }; //Common use is to have your own list property which is transparently an engine diff --git a/tests/auto/quick/qquickspritesequence/data/crashonstart.qml b/tests/auto/quick/qquickspritesequence/data/crashonstart.qml new file mode 100644 index 0000000000000000000000000000000000000000..67e09e4ace056e73833855928f3131d01fcd9e22 --- /dev/null +++ b/tests/auto/quick/qquickspritesequence/data/crashonstart.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//QTBUG-24797 +import QtQuick 2.0 + +Rectangle { + width: 800 + height: 800 + + SpriteSequence { + id: mysprite + sprites: [s1,s2] + scale: 2 + height: 200 + width: 200 + anchors.centerIn: parent + } + + Component.onCompleted: mysprite.jumpTo("running") + Sprite { + id: s1 + name: "standing" + frameCount: 12 + frameDuration: 80 + source: "squarefacesprite.png" + } + + Sprite { + id: s2 + name: "running" + frameCount: 6 + frameDuration: 80 + source: "squarefacesprite.png" + } +} diff --git a/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp b/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp index 8469a949c6d1939578150f77867fefe1b614a2d1..7a82cbbc65587e5e1a34a68ee73b889e4b8cee82 100644 --- a/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp +++ b/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp @@ -52,6 +52,7 @@ public: private slots: void test_properties(); void test_framerateAdvance();//Separate codepath for QQuickSpriteEngine + void test_jumpToCrash(); }; void tst_qquickspritesequence::test_properties() @@ -93,6 +94,18 @@ void tst_qquickspritesequence::test_framerateAdvance() delete canvas; } +void tst_qquickspritesequence::test_jumpToCrash() +{ + QQuickView *canvas = new QQuickView(0); + + canvas->setSource(testFileUrl("crashonstart.qml")); + canvas->show(); + QTest::qWaitForWindowShown(canvas); + //verify: Don't crash + + delete canvas; +} + QTEST_MAIN(tst_qquickspritesequence) #include "tst_qquickspritesequence.moc"