1/****************************************************************************
2**
3** Copyright (C) 2019 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include <private/qqmlengine_p.h>
41#include <private/qqmlextensionplugin_p.h>
42#include <private/qqmltypeloaderthread_p.h>
43
44#if QT_CONFIG(qml_network)
45#include <private/qqmltypeloadernetworkreplyproxy_p.h>
46#endif
47
48QT_BEGIN_NAMESPACE
49
50QQmlTypeLoaderThread::QQmlTypeLoaderThread(QQmlTypeLoader *loader)
51 : m_loader(loader)
52#if QT_CONFIG(qml_network)
53 , m_networkAccessManager(nullptr), m_networkReplyProxy(nullptr)
54#endif // qml_network
55{
56 // Do that after initializing all the members.
57 startup();
58}
59
60#if QT_CONFIG(qml_network)
61QNetworkAccessManager *QQmlTypeLoaderThread::networkAccessManager() const
62{
63 Q_ASSERT(isThisThread());
64 if (!m_networkAccessManager) {
65 m_networkAccessManager = QQmlEnginePrivate::get(e: m_loader->engine())->createNetworkAccessManager(parent: nullptr);
66 m_networkReplyProxy = new QQmlTypeLoaderNetworkReplyProxy(m_loader);
67 }
68
69 return m_networkAccessManager;
70}
71
72QQmlTypeLoaderNetworkReplyProxy *QQmlTypeLoaderThread::networkReplyProxy() const
73{
74 Q_ASSERT(isThisThread());
75 Q_ASSERT(m_networkReplyProxy); // Must call networkAccessManager() first
76 return m_networkReplyProxy;
77}
78#endif // qml_network
79
80void QQmlTypeLoaderThread::load(QQmlDataBlob *b)
81{
82 b->addref();
83 callMethodInThread(Member: &This::loadThread, arg: b);
84}
85
86void QQmlTypeLoaderThread::loadAsync(QQmlDataBlob *b)
87{
88 b->addref();
89 postMethodToThread(Member: &This::loadThread, arg: b);
90}
91
92void QQmlTypeLoaderThread::loadWithStaticData(QQmlDataBlob *b, const QByteArray &d)
93{
94 b->addref();
95 callMethodInThread(Member: &This::loadWithStaticDataThread, arg: b, arg2: d);
96}
97
98void QQmlTypeLoaderThread::loadWithStaticDataAsync(QQmlDataBlob *b, const QByteArray &d)
99{
100 b->addref();
101 postMethodToThread(Member: &This::loadWithStaticDataThread, arg: b, arg2: d);
102}
103
104void QQmlTypeLoaderThread::loadWithCachedUnit(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
105{
106 b->addref();
107 callMethodInThread(Member: &This::loadWithCachedUnitThread, arg: b, arg2: unit);
108}
109
110void QQmlTypeLoaderThread::loadWithCachedUnitAsync(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
111{
112 b->addref();
113 postMethodToThread(Member: &This::loadWithCachedUnitThread, arg: b, arg2: unit);
114}
115
116void QQmlTypeLoaderThread::callCompleted(QQmlDataBlob *b)
117{
118 b->addref();
119#if !QT_CONFIG(thread)
120 if (!isThisThread())
121 postMethodToThread(&This::callCompletedMain, b);
122#else
123 postMethodToMain(Member: &This::callCompletedMain, arg: b);
124#endif
125}
126
127void QQmlTypeLoaderThread::callDownloadProgressChanged(QQmlDataBlob *b, qreal p)
128{
129 b->addref();
130#if !QT_CONFIG(thread)
131 if (!isThisThread())
132 postMethodToThread(&This::callDownloadProgressChangedMain, b, p);
133#else
134 postMethodToMain(Member: &This::callDownloadProgressChangedMain, arg: b, arg2: p);
135#endif
136}
137
138void QQmlTypeLoaderThread::initializeEngine(QQmlExtensionInterface *iface,
139 const char *uri)
140{
141 callMethodInMain(Member: &This::initializeExtensionMain, arg: iface, arg2: uri);
142}
143
144void QQmlTypeLoaderThread::initializeEngine(QQmlEngineExtensionInterface *iface,
145 const char *uri)
146{
147 callMethodInMain(Member: &This::initializeEngineExtensionMain, arg: iface, arg2: uri);
148}
149
150void QQmlTypeLoaderThread::shutdownThread()
151{
152#if QT_CONFIG(qml_network)
153 delete m_networkAccessManager;
154 m_networkAccessManager = nullptr;
155 delete m_networkReplyProxy;
156 m_networkReplyProxy = nullptr;
157#endif // qml_network
158}
159
160void QQmlTypeLoaderThread::loadThread(QQmlDataBlob *b)
161{
162 m_loader->loadThread(b);
163 b->release();
164}
165
166void QQmlTypeLoaderThread::loadWithStaticDataThread(QQmlDataBlob *b, const QByteArray &d)
167{
168 m_loader->loadWithStaticDataThread(b, d);
169 b->release();
170}
171
172void QQmlTypeLoaderThread::loadWithCachedUnitThread(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
173{
174 m_loader->loadWithCachedUnitThread(blob: b, unit);
175 b->release();
176}
177
178void QQmlTypeLoaderThread::callCompletedMain(QQmlDataBlob *b)
179{
180#ifdef DATABLOB_DEBUG
181 qWarning("QQmlTypeLoaderThread: %s completed() callback", qPrintable(b->urlString()));
182#endif
183 b->completed();
184 b->release();
185}
186
187void QQmlTypeLoaderThread::callDownloadProgressChangedMain(QQmlDataBlob *b, qreal p)
188{
189#ifdef DATABLOB_DEBUG
190 qWarning("QQmlTypeLoaderThread: %s downloadProgressChanged(%f) callback",
191 qPrintable(b->urlString()), p);
192#endif
193 b->downloadProgressChanged(p);
194 b->release();
195}
196
197void QQmlTypeLoaderThread::initializeExtensionMain(QQmlExtensionInterface *iface,
198 const char *uri)
199{
200 Q_ASSERT(m_loader->engine()->thread() == QThread::currentThread());
201 iface->initializeEngine(engine: m_loader->engine(), uri);
202}
203
204void QQmlTypeLoaderThread::initializeEngineExtensionMain(QQmlEngineExtensionInterface *iface,
205 const char *uri)
206{
207 Q_ASSERT(m_loader->engine()->thread() == QThread::currentThread());
208 iface->initializeEngine(engine: m_loader->engine(), uri);
209}
210
211QT_END_NAMESPACE
212

source code of qtdeclarative/src/qml/qml/qqmltypeloaderthread.cpp