aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmltypeloader.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-10-16 17:21:55 +0200
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-11-03 09:00:11 +0000
commit164af37710e5721cbc7d79a0af20f2387181c59c (patch)
tree90949e65a650c6f10a968e83e83dbf7574c518b5 /src/qml/qml/qqmltypeloader.cpp
parent051684f125bbc31bd882c4cd313c3482bcd145a0 (diff)
Load component synchronously in method_createQmlObject
setData() is not guaranteed to synchronously load the type. In fact, most of the time, it doesn't. However, by adding a private Synchronous mode to QQmlTypeLoader we can prefetch the type synchronously and then inject it into the component. Task-number: QTBUG-45418 Change-Id: I640f12ad20c01b778b5bc41f43574d8aea504195 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/qml/qml/qqmltypeloader.cpp')
-rw-r--r--src/qml/qml/qqmltypeloader.cpp149
1 files changed, 84 insertions, 65 deletions
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 270c28c399..29f1ca7959 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -911,97 +911,116 @@ void QQmlTypeLoader::unlock()
m_thread->unlock();
}
-/*!
-Load the provided \a blob from the network or filesystem.
+struct PlainLoader {
+ void loadThread(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
+ {
+ loader->loadThread(blob);
+ }
+ void load(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
+ {
+ loader->m_thread->load(blob);
+ }
+ void loadAsync(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
+ {
+ loader->m_thread->loadAsync(blob);
+ }
+};
-The loader must be locked.
-*/
-void QQmlTypeLoader::load(QQmlDataBlob *blob, Mode mode)
+struct StaticLoader {
+ const QByteArray &data;
+ StaticLoader(const QByteArray &data) : data(data) {}
+
+ void loadThread(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
+ {
+ loader->loadWithStaticDataThread(blob, data);
+ }
+ void load(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
+ {
+ loader->m_thread->loadWithStaticData(blob, data);
+ }
+ void loadAsync(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
+ {
+ loader->m_thread->loadWithStaticDataAsync(blob, data);
+ }
+};
+
+struct CachedLoader {
+ const QQmlPrivate::CachedQmlUnit *unit;
+ CachedLoader(const QQmlPrivate::CachedQmlUnit *unit) : unit(unit) {}
+
+ void loadThread(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
+ {
+ loader->loadWithCachedUnitThread(blob, unit);
+ }
+ void load(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
+ {
+ loader->m_thread->loadWithCachedUnit(blob, unit);
+ }
+ void loadAsync(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
+ {
+ loader->m_thread->loadWithCachedUnit(blob, unit);
+ }
+};
+
+template<typename Loader>
+void QQmlTypeLoader::doLoad(const Loader &loader, QQmlDataBlob *blob, Mode mode)
{
#ifdef DATABLOB_DEBUG
- qWarning("QQmlTypeLoader::load(%s): %s thread", qPrintable(blob->m_url.toString()),
+ qWarning("QQmlTypeLoader::doLoad(%s): %s thread", qPrintable(blob->m_url.toString()),
m_thread->isThisThread()?"Compile":"Engine");
#endif
blob->startLoading();
if (m_thread->isThisThread()) {
unlock();
- loadThread(blob);
+ loader.loadThread(this, blob);
lock();
- } else if (mode == PreferSynchronous) {
+ } else if (mode == Asynchronous) {
+ blob->m_data.setIsAsync(true);
unlock();
- m_thread->load(blob);
+ loader.loadAsync(this, blob);
lock();
- if (!blob->isCompleteOrError())
- blob->m_data.setIsAsync(true);
} else {
- Q_ASSERT(mode == Asynchronous);
- blob->m_data.setIsAsync(true);
unlock();
- m_thread->loadAsync(blob);
+ loader.load(this, blob);
lock();
+ if (mode == PreferSynchronous) {
+ if (!blob->isCompleteOrError())
+ blob->m_data.setIsAsync(true);
+ } else {
+ Q_ASSERT(mode == Synchronous);
+ while (!blob->isCompleteOrError()) {
+ unlock();
+ m_thread->waitForNextMessage();
+ lock();
+ }
+ }
}
}
/*!
-Load the provided \a blob with \a data. The blob's URL is not used by the data loader in this case.
+Load the provided \a blob from the network or filesystem.
The loader must be locked.
*/
-void QQmlTypeLoader::loadWithStaticData(QQmlDataBlob *blob, const QByteArray &data, Mode mode)
+void QQmlTypeLoader::load(QQmlDataBlob *blob, Mode mode)
{
-#ifdef DATABLOB_DEBUG
- qWarning("QQmlTypeLoader::loadWithStaticData(%s, data): %s thread", qPrintable(blob->m_url.toString()),
- m_thread->isThisThread()?"Compile":"Engine");
-#endif
+ doLoad(PlainLoader(), blob, mode);
+}
- blob->startLoading();
+/*!
+Load the provided \a blob with \a data. The blob's URL is not used by the data loader in this case.
- if (m_thread->isThisThread()) {
- unlock();
- loadWithStaticDataThread(blob, data);
- lock();
- } else if (mode == PreferSynchronous) {
- unlock();
- m_thread->loadWithStaticData(blob, data);
- lock();
- if (!blob->isCompleteOrError())
- blob->m_data.setIsAsync(true);
- } else {
- Q_ASSERT(mode == Asynchronous);
- blob->m_data.setIsAsync(true);
- unlock();
- m_thread->loadWithStaticDataAsync(blob, data);
- lock();
- }
+The loader must be locked.
+*/
+void QQmlTypeLoader::loadWithStaticData(QQmlDataBlob *blob, const QByteArray &data, Mode mode)
+{
+ doLoad(StaticLoader(data), blob, mode);
}
void QQmlTypeLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode)
{
-#ifdef DATABLOB_DEBUG
- qWarning("QQmlTypeLoader::loadWithUnitFcatory(%s, data): %s thread", qPrintable(blob->m_url.toString()),
- m_thread->isThisThread()?"Compile":"Engine");
-#endif
-
- blob->startLoading();
-
- if (m_thread->isThisThread()) {
- unlock();
- loadWithCachedUnitThread(blob, unit);
- lock();
- } else if (mode == PreferSynchronous) {
- unlock();
- m_thread->loadWithCachedUnit(blob, unit);
- lock();
- if (!blob->isCompleteOrError())
- blob->m_data.setIsAsync(true);
- } else {
- Q_ASSERT(mode == Asynchronous);
- blob->m_data.setIsAsync(true);
- unlock();
- m_thread->loadWithCachedUnitAsync(blob, unit);
- lock();
- }
+ doLoad(CachedLoader(unit), blob, mode);
}
void QQmlTypeLoader::loadWithStaticDataThread(QQmlDataBlob *blob, const QByteArray &data)
@@ -1618,7 +1637,7 @@ QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode)
} else {
QQmlTypeLoader::load(typeData, mode);
}
- } else if ((mode == PreferSynchronous) && QQmlFile::isSynchronous(url)) {
+ } else if ((mode == PreferSynchronous || mode == Synchronous) && QQmlFile::isSynchronous(url)) {
// this was started Asynchronous, but we need to force Synchronous
// completion now (if at all possible with this type of URL).
@@ -1643,12 +1662,12 @@ QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode)
Returns a QQmlTypeData for the given \a data with the provided base \a url. The
QQmlTypeData will not be cached.
*/
-QQmlTypeData *QQmlTypeLoader::getType(const QByteArray &data, const QUrl &url)
+QQmlTypeData *QQmlTypeLoader::getType(const QByteArray &data, const QUrl &url, Mode mode)
{
LockHolder<QQmlTypeLoader> holder(this);
QQmlTypeData *typeData = new QQmlTypeData(url, this);
- QQmlTypeLoader::loadWithStaticData(typeData, data);
+ QQmlTypeLoader::loadWithStaticData(typeData, data, mode);
return typeData;
}