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(m_loader->engine())->createNetworkAccessManager(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(&This::loadThread, b);
84}
85
86void QQmlTypeLoaderThread::loadAsync(QQmlDataBlob *b)
87{
88 b->addref();
89 postMethodToThread(&This::loadThread, b);
90}
91
92void QQmlTypeLoaderThread::loadWithStaticData(QQmlDataBlob *b, const QByteArray &d)
93{
94 b->addref();
95 callMethodInThread(&This::loadWithStaticDataThread, b, d);
96}
97
98void QQmlTypeLoaderThread::loadWithStaticDataAsync(QQmlDataBlob *b, const QByteArray &d)
99{
100 b->addref();
101 postMethodToThread(&This::loadWithStaticDataThread, b, d);
102}
103
104void QQmlTypeLoaderThread::loadWithCachedUnit(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
105{
106 b->addref();
107 callMethodInThread(&This::loadWithCachedUnitThread, b, unit);
108}
109
110void QQmlTypeLoaderThread::loadWithCachedUnitAsync(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
111{
112 b->addref();
113 postMethodToThread(&This::loadWithCachedUnitThread, b, 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(&This::callCompletedMain, 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(&This::callDownloadProgressChangedMain, b, p);
135#endif
136}
137
138void QQmlTypeLoaderThread::initializeEngine(QQmlExtensionInterface *iface,
139 const char *uri)
140{
141 callMethodInMain(&This::initializeEngineMain, iface, uri);
142}
143
144void QQmlTypeLoaderThread::shutdownThread()
145{
146#if QT_CONFIG(qml_network)
147 delete m_networkAccessManager;
148 m_networkAccessManager = nullptr;
149 delete m_networkReplyProxy;
150 m_networkReplyProxy = nullptr;
151#endif // qml_network
152}
153
154void QQmlTypeLoaderThread::loadThread(QQmlDataBlob *b)
155{
156 m_loader->loadThread(b);
157 b->release();
158}
159
160void QQmlTypeLoaderThread::loadWithStaticDataThread(QQmlDataBlob *b, const QByteArray &d)
161{
162 m_loader->loadWithStaticDataThread(b, d);
163 b->release();
164}
165
166void QQmlTypeLoaderThread::loadWithCachedUnitThread(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
167{
168 m_loader->loadWithCachedUnitThread(b, unit);
169 b->release();
170}
171
172void QQmlTypeLoaderThread::callCompletedMain(QQmlDataBlob *b)
173{
174#ifdef DATABLOB_DEBUG
175 qWarning("QQmlTypeLoaderThread: %s completed() callback", qPrintable(b->urlString()));
176#endif
177 b->completed();
178 b->release();
179}
180
181void QQmlTypeLoaderThread::callDownloadProgressChangedMain(QQmlDataBlob *b, qreal p)
182{
183#ifdef DATABLOB_DEBUG
184 qWarning("QQmlTypeLoaderThread: %s downloadProgressChanged(%f) callback",
185 qPrintable(b->urlString()), p);
186#endif
187 b->downloadProgressChanged(p);
188 b->release();
189}
190
191void QQmlTypeLoaderThread::initializeEngineMain(QQmlExtensionInterface *iface,
192 const char *uri)
193{
194 Q_ASSERT(m_loader->engine()->thread() == QThread::currentThread());
195 iface->initializeEngine(m_loader->engine(), uri);
196}
197
198QT_END_NAMESPACE
199