diff options
author | Alan Alpert <aalpert@rim.com> | 2012-11-26 21:29:32 (GMT) |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-11-28 20:38:05 (GMT) |
commit | c370a6c7fe1965157fa47380bfe7fb4da5eae96b (patch) | |
tree | db70e20a9415de7a2e863c50080681dc556c9438 | |
parent | 31fee4444587e043413393f1c5df1b6c8c7da5aa (diff) | |
download | Qt-c370a6c7fe1965157fa47380bfe7fb4da5eae96b.zip Qt-c370a6c7fe1965157fa47380bfe7fb4da5eae96b.tar.gz Qt-c370a6c7fe1965157fa47380bfe7fb4da5eae96b.tar.bz2 |
QML file loading: honor synchronous requests made through QNAM
So that it can skip loading state when the underlying
QNetworkReply is already finished.
Parts-of-the-patch-by: Jeremy Nicholl
Task-number: QTBUG-27723
backport of e5783b79887299d094e6976630373a4899bd7074 from qtquick1
Change-Id: I8f5ee61a754ddec81ec70f82eb39e727534a6049
Reviewed-by: Alan Alpert <aalpert@rim.com>
-rw-r--r-- | src/declarative/qml/qdeclarativetypeloader.cpp | 34 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativetypeloader_p.h | 2 | ||||
-rw-r--r-- | tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp | 50 |
3 files changed, 78 insertions, 8 deletions
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp index b92883e..5cce995 100644 --- a/src/declarative/qml/qdeclarativetypeloader.cpp +++ b/src/declarative/qml/qdeclarativetypeloader.cpp @@ -552,21 +552,28 @@ void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob) blob->m_manager = this; QNetworkReply *reply = m_engine->networkAccessManager()->get(QNetworkRequest(blob->m_url)); - QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), - this, SLOT(networkReplyProgress(qint64,qint64))); - QObject::connect(reply, SIGNAL(finished()), - this, SLOT(networkReplyFinished())); - m_networkReplies.insert(reply, blob); + m_networkReplies.insert(reply, blob); blob->addref(); + + if (reply->isFinished()) { + // Short-circuit synchronous replies. + qint64 size = reply->size(); + networkReplyProgress(reply, size, size); + networkReplyFinished(reply); + } else { + QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(networkReplyProgress(qint64,qint64))); + QObject::connect(reply, SIGNAL(finished()), + this, SLOT(networkReplyFinished())); + } } } #define DATALOADER_MAXIMUM_REDIRECT_RECURSION 16 -void QDeclarativeDataLoader::networkReplyFinished() +void QDeclarativeDataLoader::networkReplyFinished(QNetworkReply *reply) { - QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); reply->deleteLater(); QDeclarativeDataBlob *blob = m_networkReplies.take(reply); @@ -598,9 +605,14 @@ void QDeclarativeDataLoader::networkReplyFinished() blob->release(); } -void QDeclarativeDataLoader::networkReplyProgress(qint64 bytesReceived, qint64 bytesTotal) +void QDeclarativeDataLoader::networkReplyFinished() { QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); + networkReplyFinished(reply); +} + +void QDeclarativeDataLoader::networkReplyProgress(QNetworkReply *reply, qint64 bytesReceived, qint64 bytesTotal) +{ QDeclarativeDataBlob *blob = m_networkReplies.value(reply); Q_ASSERT(blob); @@ -611,6 +623,12 @@ void QDeclarativeDataLoader::networkReplyProgress(qint64 bytesReceived, qint64 b } } +void QDeclarativeDataLoader::networkReplyProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); + networkReplyProgress(reply, bytesReceived, bytesTotal); +} + /*! Load the provided \a blob with \a data. The blob's URL is not used by the data loader in this case. */ diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h index 03e79ad..12b65ed 100644 --- a/src/declarative/qml/qdeclarativetypeloader_p.h +++ b/src/declarative/qml/qdeclarativetypeloader_p.h @@ -172,6 +172,8 @@ private slots: private: void setData(QDeclarativeDataBlob *, const QByteArray &); + void networkReplyFinished(QNetworkReply *); + void networkReplyProgress(QNetworkReply *, qint64, qint64); QDeclarativeEngine *m_engine; typedef QHash<QNetworkReply *, QDeclarativeDataBlob *> NetworkReplies; diff --git a/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp b/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp index c4d0ab1..9c389c4 100644 --- a/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp +++ b/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp @@ -43,6 +43,7 @@ #include <QDeclarativeEngine> #include <QDeclarativeContext> #include <QNetworkAccessManager> +#include <QNetworkReply> #include <QPointer> #include <QDir> #include <QDesktopServices> @@ -70,6 +71,7 @@ private slots: void clearComponentCache(); void outputWarningsToStandardError(); void objectOwnership(); + void synchronousNetworkReply(); }; void tst_qdeclarativeengine::rootContext() @@ -328,6 +330,54 @@ void tst_qdeclarativeengine::objectOwnership() } +class MyReply : public QNetworkReply { + + Q_OBJECT + +public: + MyReply() { + setFinished(true); + } + virtual qint64 readData(char* buffer, qint64 number) { + return 0; + } + virtual void abort() { } +}; + +class MyManager : public QNetworkAccessManager { + + Q_OBJECT + +public: + MyManager(QObject *parent = 0) : QNetworkAccessManager(parent) { + } + + QNetworkReply *createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0) { + return new MyReply; + } +}; + +class MyFactory : public QDeclarativeNetworkAccessManagerFactory { + +public: + QNetworkAccessManager *create(QObject *parent) { + return new MyManager; + } +}; + +void tst_qdeclarativeengine::synchronousNetworkReply() +{ + MyFactory factory; + QDeclarativeEngine engine; + engine.setNetworkAccessManagerFactory(&factory); + QDeclarativeComponent c(&engine, QUrl("myScheme://test.qml")); + // we get an error, but we only care about whether we are finished or not in this test + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready"); + c.create(); + // reply is finished, so should not be in loading state. + QVERIFY(!c.isLoading()); +} + QTEST_MAIN(tst_qdeclarativeengine) #include "tst_qdeclarativeengine.moc" |