Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/qml/types/qquickworkerscript.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||||||||
2 | ** | - | ||||||||||||
3 | ** Copyright (C) 2016 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 "qtqmlglobal_p.h" | - | ||||||||||||
41 | #include "qquickworkerscript_p.h" | - | ||||||||||||
42 | #if QT_CONFIG(qml_list_model) | - | ||||||||||||
43 | #include "qqmllistmodel_p.h" | - | ||||||||||||
44 | #include "qqmllistmodelworkeragent_p.h" | - | ||||||||||||
45 | #endif | - | ||||||||||||
46 | #include <private/qqmlengine_p.h> | - | ||||||||||||
47 | #include <private/qqmlexpression_p.h> | - | ||||||||||||
48 | - | |||||||||||||
49 | #include <QtCore/qcoreevent.h> | - | ||||||||||||
50 | #include <QtCore/qcoreapplication.h> | - | ||||||||||||
51 | #include <QtCore/qdebug.h> | - | ||||||||||||
52 | #include <QtQml/qjsengine.h> | - | ||||||||||||
53 | #include <QtCore/qmutex.h> | - | ||||||||||||
54 | #include <QtCore/qwaitcondition.h> | - | ||||||||||||
55 | #include <QtCore/qfile.h> | - | ||||||||||||
56 | #include <QtCore/qdatetime.h> | - | ||||||||||||
57 | #include <QtQml/qqmlinfo.h> | - | ||||||||||||
58 | #include <QtQml/qqmlfile.h> | - | ||||||||||||
59 | #if QT_CONFIG(qml_network) | - | ||||||||||||
60 | #include <QtNetwork/qnetworkaccessmanager.h> | - | ||||||||||||
61 | #include "qqmlnetworkaccessmanagerfactory.h" | - | ||||||||||||
62 | #endif | - | ||||||||||||
63 | - | |||||||||||||
64 | #include <private/qv8engine_p.h> | - | ||||||||||||
65 | #include <private/qv4serialize_p.h> | - | ||||||||||||
66 | - | |||||||||||||
67 | #include <private/qv4value_p.h> | - | ||||||||||||
68 | #include <private/qv4functionobject_p.h> | - | ||||||||||||
69 | #include <private/qv4script_p.h> | - | ||||||||||||
70 | #include <private/qv4scopedvalue_p.h> | - | ||||||||||||
71 | #include <private/qv4jscall_p.h> | - | ||||||||||||
72 | - | |||||||||||||
73 | QT_BEGIN_NAMESPACE | - | ||||||||||||
74 | - | |||||||||||||
75 | class WorkerDataEvent : public QEvent | - | ||||||||||||
76 | { | - | ||||||||||||
77 | public: | - | ||||||||||||
78 | enum Type { WorkerData = QEvent::User }; | - | ||||||||||||
79 | - | |||||||||||||
80 | WorkerDataEvent(int workerId, const QByteArray &data); | - | ||||||||||||
81 | virtual ~WorkerDataEvent(); | - | ||||||||||||
82 | - | |||||||||||||
83 | int workerId() const; | - | ||||||||||||
84 | QByteArray data() const; | - | ||||||||||||
85 | - | |||||||||||||
86 | private: | - | ||||||||||||
87 | int m_id; | - | ||||||||||||
88 | QByteArray m_data; | - | ||||||||||||
89 | }; | - | ||||||||||||
90 | - | |||||||||||||
91 | class WorkerLoadEvent : public QEvent | - | ||||||||||||
92 | { | - | ||||||||||||
93 | public: | - | ||||||||||||
94 | enum Type { WorkerLoad = WorkerDataEvent::WorkerData + 1 }; | - | ||||||||||||
95 | - | |||||||||||||
96 | WorkerLoadEvent(int workerId, const QUrl &url); | - | ||||||||||||
97 | - | |||||||||||||
98 | int workerId() const; | - | ||||||||||||
99 | QUrl url() const; | - | ||||||||||||
100 | - | |||||||||||||
101 | private: | - | ||||||||||||
102 | int m_id; | - | ||||||||||||
103 | QUrl m_url; | - | ||||||||||||
104 | }; | - | ||||||||||||
105 | - | |||||||||||||
106 | class WorkerRemoveEvent : public QEvent | - | ||||||||||||
107 | { | - | ||||||||||||
108 | public: | - | ||||||||||||
109 | enum Type { WorkerRemove = WorkerLoadEvent::WorkerLoad + 1 }; | - | ||||||||||||
110 | - | |||||||||||||
111 | WorkerRemoveEvent(int workerId); | - | ||||||||||||
112 | - | |||||||||||||
113 | int workerId() const; | - | ||||||||||||
114 | - | |||||||||||||
115 | private: | - | ||||||||||||
116 | int m_id; | - | ||||||||||||
117 | }; | - | ||||||||||||
118 | - | |||||||||||||
119 | class WorkerErrorEvent : public QEvent | - | ||||||||||||
120 | { | - | ||||||||||||
121 | public: | - | ||||||||||||
122 | enum Type { WorkerError = WorkerRemoveEvent::WorkerRemove + 1 }; | - | ||||||||||||
123 | - | |||||||||||||
124 | WorkerErrorEvent(const QQmlError &error); | - | ||||||||||||
125 | - | |||||||||||||
126 | QQmlError error() const; | - | ||||||||||||
127 | - | |||||||||||||
128 | private: | - | ||||||||||||
129 | QQmlError m_error; | - | ||||||||||||
130 | }; | - | ||||||||||||
131 | - | |||||||||||||
132 | class QQuickWorkerScriptEnginePrivate : public QObject | - | ||||||||||||
133 | { | - | ||||||||||||
134 | Q_OBJECT | - | ||||||||||||
135 | public: | - | ||||||||||||
136 | enum WorkerEventTypes { | - | ||||||||||||
137 | WorkerDestroyEvent = QEvent::User + 100 | - | ||||||||||||
138 | }; | - | ||||||||||||
139 | - | |||||||||||||
140 | QQuickWorkerScriptEnginePrivate(QQmlEngine *eng); | - | ||||||||||||
141 | - | |||||||||||||
142 | class WorkerEngine : public QV8Engine | - | ||||||||||||
143 | { | - | ||||||||||||
144 | public: | - | ||||||||||||
145 | WorkerEngine(QQuickWorkerScriptEnginePrivate *parent); | - | ||||||||||||
146 | ~WorkerEngine(); | - | ||||||||||||
147 | - | |||||||||||||
148 | void init(); | - | ||||||||||||
149 | - | |||||||||||||
150 | #if QT_CONFIG(qml_network) | - | ||||||||||||
151 | QNetworkAccessManager *networkAccessManager() override; | - | ||||||||||||
152 | #endif | - | ||||||||||||
153 | - | |||||||||||||
154 | QQuickWorkerScriptEnginePrivate *p; | - | ||||||||||||
155 | - | |||||||||||||
156 | QV4::ReturnedValue sendFunction(int id); | - | ||||||||||||
157 | - | |||||||||||||
158 | QV4::PersistentValue onmessage; | - | ||||||||||||
159 | private: | - | ||||||||||||
160 | QV4::PersistentValue createsend; | - | ||||||||||||
161 | #if QT_CONFIG(qml_network) | - | ||||||||||||
162 | QNetworkAccessManager *accessManager; | - | ||||||||||||
163 | #endif | - | ||||||||||||
164 | }; | - | ||||||||||||
165 | - | |||||||||||||
166 | WorkerEngine *workerEngine; | - | ||||||||||||
167 | static QQuickWorkerScriptEnginePrivate *get(QV8Engine *e) { | - | ||||||||||||
168 | return static_cast<WorkerEngine *>(e)->p; executed 8 times by 1 test: return static_cast<WorkerEngine *>(e)->p; Executed by:
| 8 | ||||||||||||
169 | } | - | ||||||||||||
170 | - | |||||||||||||
171 | QQmlEngine *qmlengine; | - | ||||||||||||
172 | - | |||||||||||||
173 | QMutex m_lock; | - | ||||||||||||
174 | QWaitCondition m_wait; | - | ||||||||||||
175 | - | |||||||||||||
176 | struct WorkerScript { | - | ||||||||||||
177 | WorkerScript(); | - | ||||||||||||
178 | ~WorkerScript(); | - | ||||||||||||
179 | - | |||||||||||||
180 | int id; | - | ||||||||||||
181 | QUrl source; | - | ||||||||||||
182 | bool initialized; | - | ||||||||||||
183 | QQuickWorkerScript *owner; | - | ||||||||||||
184 | QV4::PersistentValue qmlContext; | - | ||||||||||||
185 | }; | - | ||||||||||||
186 | - | |||||||||||||
187 | QHash<int, WorkerScript *> workers; | - | ||||||||||||
188 | QV4::ReturnedValue getWorker(WorkerScript *); | - | ||||||||||||
189 | - | |||||||||||||
190 | int m_nextId; | - | ||||||||||||
191 | - | |||||||||||||
192 | static QV4::ReturnedValue method_sendMessage(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc); | - | ||||||||||||
193 | - | |||||||||||||
194 | signals: | - | ||||||||||||
195 | void stopThread(); | - | ||||||||||||
196 | - | |||||||||||||
197 | protected: | - | ||||||||||||
198 | bool event(QEvent *) override; | - | ||||||||||||
199 | - | |||||||||||||
200 | private: | - | ||||||||||||
201 | void processMessage(int, const QByteArray &); | - | ||||||||||||
202 | void processLoad(int, const QUrl &); | - | ||||||||||||
203 | void reportScriptException(WorkerScript *, const QQmlError &error); | - | ||||||||||||
204 | }; | - | ||||||||||||
205 | - | |||||||||||||
206 | QQuickWorkerScriptEnginePrivate::WorkerEngine::WorkerEngine(QQuickWorkerScriptEnginePrivate *parent) | - | ||||||||||||
207 | : QV8Engine(new QV4::ExecutionEngine), p(parent) | - | ||||||||||||
208 | #if QT_CONFIG(qml_network) | - | ||||||||||||
209 | , accessManager(nullptr) | - | ||||||||||||
210 | #endif | - | ||||||||||||
211 | { | - | ||||||||||||
212 | m_v4Engine->v8Engine = this; | - | ||||||||||||
213 | } executed 1110 times by 5 tests: end of block Executed by:
| 1110 | ||||||||||||
214 | - | |||||||||||||
215 | QQuickWorkerScriptEnginePrivate::WorkerEngine::~WorkerEngine() | - | ||||||||||||
216 | { | - | ||||||||||||
217 | #if QT_CONFIG(qml_network) | - | ||||||||||||
218 | delete accessManager; | - | ||||||||||||
219 | #endif | - | ||||||||||||
220 | delete m_v4Engine; | - | ||||||||||||
221 | } executed 1110 times by 5 tests: end of block Executed by:
| 1110 | ||||||||||||
222 | - | |||||||||||||
223 | void QQuickWorkerScriptEnginePrivate::WorkerEngine::init() | - | ||||||||||||
224 | { | - | ||||||||||||
225 | initQmlGlobalObject(); | - | ||||||||||||
226 | #define CALL_ONMESSAGE_SCRIPT \ | - | ||||||||||||
227 | "(function(object, message) { "\ | - | ||||||||||||
228 | "var isfunction = false; "\ | - | ||||||||||||
229 | "try { "\ | - | ||||||||||||
230 | "isfunction = object.WorkerScript.onMessage instanceof Function; "\ | - | ||||||||||||
231 | "} catch (e) {}" \ | - | ||||||||||||
232 | "if (isfunction) "\ | - | ||||||||||||
233 | "object.WorkerScript.onMessage(message); "\ | - | ||||||||||||
234 | "})" | - | ||||||||||||
235 | - | |||||||||||||
236 | #define SEND_MESSAGE_CREATE_SCRIPT \ | - | ||||||||||||
237 | "(function(method, engine) { "\ | - | ||||||||||||
238 | "return (function(id) { "\ | - | ||||||||||||
239 | "return (function(message) { "\ | - | ||||||||||||
240 | "if (arguments.length) method(engine, id, message); "\ | - | ||||||||||||
241 | "}); "\ | - | ||||||||||||
242 | "}); "\ | - | ||||||||||||
243 | "})" | - | ||||||||||||
244 | - | |||||||||||||
245 | QV4::Scope scope(m_v4Engine); | - | ||||||||||||
246 | QV4::ExecutionContext *globalContext = scope.engine->rootContext(); | - | ||||||||||||
247 | onmessage.set(scope.engine, QV4::Script(globalContext, QV4::Compiler::ContextType::Global, QString::fromUtf8(CALL_ONMESSAGE_SCRIPT)).run()); // do not use QStringLiteral here, MSVC2012 cannot apply this cleanly to the macro | - | ||||||||||||
248 | Q_ASSERT(!scope.engine->hasException); | - | ||||||||||||
249 | QV4::Script createsendscript(globalContext, QV4::Compiler::ContextType::Global, QString::fromUtf8(SEND_MESSAGE_CREATE_SCRIPT)); // do not use QStringLiteral here, MSVC2012 cannot apply this cleanly to the macro | - | ||||||||||||
250 | QV4::ScopedFunctionObject createsendconstructor(scope, createsendscript.run()); | - | ||||||||||||
251 | Q_ASSERT(!scope.engine->hasException); | - | ||||||||||||
252 | QV4::ScopedString name(scope, m_v4Engine->newString(QStringLiteral("sendMessage"))); executed 1110 times by 5 tests: return qstring_literal_temp; Executed by:
| 1110 | ||||||||||||
253 | QV4::ScopedValue function(scope, QV4::FunctionObject::createBuiltinFunction(m_v4Engine, name, method_sendMessage, 1)); | - | ||||||||||||
254 | QV4::JSCallData jsCallData(scope, 1); | - | ||||||||||||
255 | jsCallData->args[0] = function; | - | ||||||||||||
256 | *jsCallData->thisObject = m_v4Engine->global(); | - | ||||||||||||
257 | createsend.set(scope.engine, createsendconstructor->call(jsCallData)); | - | ||||||||||||
258 | } executed 1110 times by 5 tests: end of block Executed by:
| 1110 | ||||||||||||
259 | - | |||||||||||||
260 | // Requires handle and context scope | - | ||||||||||||
261 | QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(int id) | - | ||||||||||||
262 | { | - | ||||||||||||
263 | QV4::ExecutionEngine *v4 = createsend.engine(); | - | ||||||||||||
264 | if (!v4)
| 0-1152 | ||||||||||||
265 | return QV4::Encode::undefined(); never executed: return QV4::Encode::undefined(); | 0 | ||||||||||||
266 | - | |||||||||||||
267 | QV4::Scope scope(v4); | - | ||||||||||||
268 | QV4::ScopedFunctionObject f(scope, createsend.value()); | - | ||||||||||||
269 | - | |||||||||||||
270 | QV4::ScopedValue v(scope); | - | ||||||||||||
271 | QV4::JSCallData jsCallData(scope, 1); | - | ||||||||||||
272 | jsCallData->args[0] = QV4::Primitive::fromInt32(id); | - | ||||||||||||
273 | *jsCallData->thisObject = m_v4Engine->global(); | - | ||||||||||||
274 | v = f->call(jsCallData); | - | ||||||||||||
275 | if (scope.hasException())
| 0-1152 | ||||||||||||
276 | v = scope.engine->catchException(); never executed: v = scope.engine->catchException(); | 0 | ||||||||||||
277 | return v->asReturnedValue(); executed 1152 times by 5 tests: return v->asReturnedValue(); Executed by:
| 1152 | ||||||||||||
278 | } | - | ||||||||||||
279 | - | |||||||||||||
280 | #if QT_CONFIG(qml_network) | - | ||||||||||||
281 | QNetworkAccessManager *QQuickWorkerScriptEnginePrivate::WorkerEngine::networkAccessManager() | - | ||||||||||||
282 | { | - | ||||||||||||
283 | if (!accessManager) {
| 0 | ||||||||||||
284 | if (p->qmlengine && p->qmlengine->networkAccessManagerFactory()) {
| 0 | ||||||||||||
285 | accessManager = p->qmlengine->networkAccessManagerFactory()->create(p); | - | ||||||||||||
286 | } else { never executed: end of block | 0 | ||||||||||||
287 | accessManager = new QNetworkAccessManager(p); | - | ||||||||||||
288 | } never executed: end of block | 0 | ||||||||||||
289 | } | - | ||||||||||||
290 | return accessManager; never executed: return accessManager; | 0 | ||||||||||||
291 | } | - | ||||||||||||
292 | #endif | - | ||||||||||||
293 | - | |||||||||||||
294 | QQuickWorkerScriptEnginePrivate::QQuickWorkerScriptEnginePrivate(QQmlEngine *engine) | - | ||||||||||||
295 | : workerEngine(nullptr), qmlengine(engine), m_nextId(0) | - | ||||||||||||
296 | { | - | ||||||||||||
297 | } executed 1110 times by 5 tests: end of block Executed by:
| 1110 | ||||||||||||
298 | - | |||||||||||||
299 | QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::FunctionObject *b, | - | ||||||||||||
300 | const QV4::Value *, const QV4::Value *argv, int argc) | - | ||||||||||||
301 | { | - | ||||||||||||
302 | QV4::Scope scope(b); | - | ||||||||||||
303 | WorkerEngine *engine = static_cast<WorkerEngine *>(scope.engine->v8Engine); | - | ||||||||||||
304 | - | |||||||||||||
305 | int id = argc > 1 ? argv[1].toInt32() : 0;
| 0-976 | ||||||||||||
306 | - | |||||||||||||
307 | QV4::ScopedValue v(scope, argc > 2 ? argv[2] : QV4::Primitive::undefinedValue()); | - | ||||||||||||
308 | QByteArray data = QV4::Serialize::serialize(v, scope.engine); | - | ||||||||||||
309 | - | |||||||||||||
310 | QMutexLocker locker(&engine->p->m_lock); | - | ||||||||||||
311 | WorkerScript *script = engine->p->workers.value(id); | - | ||||||||||||
312 | if (script && script->owner)
| 0-976 | ||||||||||||
313 | QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, data)); executed 972 times by 4 tests: QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, data)); Executed by:
| 972 | ||||||||||||
314 | - | |||||||||||||
315 | return QV4::Encode::undefined(); executed 976 times by 4 tests: return QV4::Encode::undefined(); Executed by:
| 976 | ||||||||||||
316 | } | - | ||||||||||||
317 | - | |||||||||||||
318 | QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *script) | - | ||||||||||||
319 | { | - | ||||||||||||
320 | if (!script->initialized) {
| 2-1152 | ||||||||||||
321 | script->initialized = true; | - | ||||||||||||
322 | - | |||||||||||||
323 | QV4::ExecutionEngine *v4 = QV8Engine::getV4(workerEngine); | - | ||||||||||||
324 | QV4::Scope scope(v4); | - | ||||||||||||
325 | QV4::ScopedValue v(scope, workerEngine->sendFunction(script->id)); | - | ||||||||||||
326 | script->qmlContext.set(v4, QV4::QmlContext::createWorkerContext(v4->rootContext(), script->source, v)); | - | ||||||||||||
327 | } executed 1152 times by 5 tests: end of block Executed by:
| 1152 | ||||||||||||
328 | - | |||||||||||||
329 | return script->qmlContext.value(); executed 1154 times by 5 tests: return script->qmlContext.value(); Executed by:
| 1154 | ||||||||||||
330 | } | - | ||||||||||||
331 | - | |||||||||||||
332 | bool QQuickWorkerScriptEnginePrivate::event(QEvent *event) | - | ||||||||||||
333 | { | - | ||||||||||||
334 | if (event->type() == (QEvent::Type)WorkerDataEvent::WorkerData) {
| 1182-4526 | ||||||||||||
335 | WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event); | - | ||||||||||||
336 | processMessage(workerEvent->workerId(), workerEvent->data()); | - | ||||||||||||
337 | return true; executed 1182 times by 5 tests: return true; Executed by:
| 1182 | ||||||||||||
338 | } else if (event->type() == (QEvent::Type)WorkerLoadEvent::WorkerLoad) {
| 1154-3372 | ||||||||||||
339 | WorkerLoadEvent *workerEvent = static_cast<WorkerLoadEvent *>(event); | - | ||||||||||||
340 | processLoad(workerEvent->workerId(), workerEvent->url()); | - | ||||||||||||
341 | return true; executed 1154 times by 5 tests: return true; Executed by:
| 1154 | ||||||||||||
342 | } else if (event->type() == (QEvent::Type)WorkerDestroyEvent) {
| 1110-2262 | ||||||||||||
343 | emit stopThread(); | - | ||||||||||||
344 | return true; executed 1110 times by 5 tests: return true; Executed by:
| 1110 | ||||||||||||
345 | } else if (event->type() == (QEvent::Type)WorkerRemoveEvent::WorkerRemove) {
| 1110-1152 | ||||||||||||
346 | WorkerRemoveEvent *workerEvent = static_cast<WorkerRemoveEvent *>(event); | - | ||||||||||||
347 | QHash<int, WorkerScript *>::iterator itr = workers.find(workerEvent->workerId()); | - | ||||||||||||
348 | if (itr != workers.end()) {
| 0-1152 | ||||||||||||
349 | delete itr.value(); | - | ||||||||||||
350 | workers.erase(itr); | - | ||||||||||||
351 | } executed 1152 times by 5 tests: end of block Executed by:
| 1152 | ||||||||||||
352 | return true; executed 1152 times by 5 tests: return true; Executed by:
| 1152 | ||||||||||||
353 | } else { | - | ||||||||||||
354 | return QObject::event(event); executed 1110 times by 5 tests: return QObject::event(event); Executed by:
| 1110 | ||||||||||||
355 | } | - | ||||||||||||
356 | } | - | ||||||||||||
357 | - | |||||||||||||
358 | void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &data) | - | ||||||||||||
359 | { | - | ||||||||||||
360 | WorkerScript *script = workers.value(id); | - | ||||||||||||
361 | if (!script)
| 0-1182 | ||||||||||||
362 | return; never executed: return; | 0 | ||||||||||||
363 | - | |||||||||||||
364 | QV4::ExecutionEngine *v4 = QV8Engine::getV4(workerEngine); | - | ||||||||||||
365 | QV4::Scope scope(v4); | - | ||||||||||||
366 | QV4::ScopedFunctionObject f(scope, workerEngine->onmessage.value()); | - | ||||||||||||
367 | - | |||||||||||||
368 | QV4::ScopedValue value(scope, QV4::Serialize::deserialize(data, v4)); | - | ||||||||||||
369 | QV4::Scoped<QV4::QmlContext> qmlContext(scope, script->qmlContext.value()); | - | ||||||||||||
370 | Q_ASSERT(!!qmlContext); | - | ||||||||||||
371 | - | |||||||||||||
372 | QV4::JSCallData jsCallData(scope, 2); | - | ||||||||||||
373 | *jsCallData->thisObject = v4->global(); | - | ||||||||||||
374 | jsCallData->args[0] = qmlContext->d()->qml(); // ### | - | ||||||||||||
375 | jsCallData->args[1] = value; | - | ||||||||||||
376 | f->call(jsCallData); | - | ||||||||||||
377 | if (scope.hasException()) {
| 4-1178 | ||||||||||||
378 | QQmlError error = scope.engine->catchExceptionAsQmlError(); | - | ||||||||||||
379 | reportScriptException(script, error); | - | ||||||||||||
380 | } executed 4 times by 1 test: end of block Executed by:
| 4 | ||||||||||||
381 | } executed 1182 times by 5 tests: end of block Executed by:
| 1182 | ||||||||||||
382 | - | |||||||||||||
383 | void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url) | - | ||||||||||||
384 | { | - | ||||||||||||
385 | if (url.isRelative())
| 0-1154 | ||||||||||||
386 | return; never executed: return; | 0 | ||||||||||||
387 | - | |||||||||||||
388 | QString fileName = QQmlFile::urlToLocalFileOrQrc(url); | - | ||||||||||||
389 | - | |||||||||||||
390 | QV4::ExecutionEngine *v4 = QV8Engine::getV4(workerEngine); | - | ||||||||||||
391 | QV4::Scope scope(v4); | - | ||||||||||||
392 | QScopedPointer<QV4::Script> program; | - | ||||||||||||
393 | - | |||||||||||||
394 | WorkerScript *script = workers.value(id); | - | ||||||||||||
395 | if (!script)
| 0-1154 | ||||||||||||
396 | return; never executed: return; | 0 | ||||||||||||
397 | script->source = url; | - | ||||||||||||
398 | - | |||||||||||||
399 | QV4::Scoped<QV4::QmlContext> qmlContext(scope, getWorker(script)); | - | ||||||||||||
400 | Q_ASSERT(!!qmlContext); | - | ||||||||||||
401 | - | |||||||||||||
402 | QString error; | - | ||||||||||||
403 | program.reset(QV4::Script::createFromFileOrCache(v4, qmlContext, fileName, url, &error)); | - | ||||||||||||
404 | if (program.isNull()) {
| 0-1154 | ||||||||||||
405 | if (!error.isEmpty())
| 0 | ||||||||||||
406 | qWarning().nospace() << error; never executed: QMessageLogger(__FILE__, 406, __PRETTY_FUNCTION__).warning().nospace() << error; | 0 | ||||||||||||
407 | return; never executed: return; | 0 | ||||||||||||
408 | } | - | ||||||||||||
409 | - | |||||||||||||
410 | if (!v4->hasException)
| 2-1152 | ||||||||||||
411 | program->run(); executed 1152 times by 5 tests: program->run(); Executed by:
| 1152 | ||||||||||||
412 | - | |||||||||||||
413 | if (v4->hasException) {
| 4-1150 | ||||||||||||
414 | QQmlError error = v4->catchExceptionAsQmlError(); | - | ||||||||||||
415 | reportScriptException(script, error); | - | ||||||||||||
416 | } executed 4 times by 1 test: end of block Executed by:
| 4 | ||||||||||||
417 | } executed 1154 times by 5 tests: end of block Executed by:
| 1154 | ||||||||||||
418 | - | |||||||||||||
419 | void QQuickWorkerScriptEnginePrivate::reportScriptException(WorkerScript *script, | - | ||||||||||||
420 | const QQmlError &error) | - | ||||||||||||
421 | { | - | ||||||||||||
422 | QQuickWorkerScriptEnginePrivate *p = QQuickWorkerScriptEnginePrivate::get(workerEngine); | - | ||||||||||||
423 | - | |||||||||||||
424 | QMutexLocker locker(&p->m_lock); | - | ||||||||||||
425 | if (script->owner)
| 0-8 | ||||||||||||
426 | QCoreApplication::postEvent(script->owner, new WorkerErrorEvent(error)); executed 8 times by 1 test: QCoreApplication::postEvent(script->owner, new WorkerErrorEvent(error)); Executed by:
| 8 | ||||||||||||
427 | } executed 8 times by 1 test: end of block Executed by:
| 8 | ||||||||||||
428 | - | |||||||||||||
429 | WorkerDataEvent::WorkerDataEvent(int workerId, const QByteArray &data) | - | ||||||||||||
430 | : QEvent((QEvent::Type)WorkerData), m_id(workerId), m_data(data) | - | ||||||||||||
431 | { | - | ||||||||||||
432 | } executed 2154 times by 5 tests: end of block Executed by:
| 2154 | ||||||||||||
433 | - | |||||||||||||
434 | WorkerDataEvent::~WorkerDataEvent() | - | ||||||||||||
435 | { | - | ||||||||||||
436 | } | - | ||||||||||||
437 | - | |||||||||||||
438 | int WorkerDataEvent::workerId() const | - | ||||||||||||
439 | { | - | ||||||||||||
440 | return m_id; executed 1182 times by 5 tests: return m_id; Executed by:
| 1182 | ||||||||||||
441 | } | - | ||||||||||||
442 | - | |||||||||||||
443 | QByteArray WorkerDataEvent::data() const | - | ||||||||||||
444 | { | - | ||||||||||||
445 | return m_data; executed 2154 times by 5 tests: return m_data; Executed by:
| 2154 | ||||||||||||
446 | } | - | ||||||||||||
447 | - | |||||||||||||
448 | WorkerLoadEvent::WorkerLoadEvent(int workerId, const QUrl &url) | - | ||||||||||||
449 | : QEvent((QEvent::Type)WorkerLoad), m_id(workerId), m_url(url) | - | ||||||||||||
450 | { | - | ||||||||||||
451 | } executed 1154 times by 5 tests: end of block Executed by:
| 1154 | ||||||||||||
452 | - | |||||||||||||
453 | int WorkerLoadEvent::workerId() const | - | ||||||||||||
454 | { | - | ||||||||||||
455 | return m_id; executed 1154 times by 5 tests: return m_id; Executed by:
| 1154 | ||||||||||||
456 | } | - | ||||||||||||
457 | - | |||||||||||||
458 | QUrl WorkerLoadEvent::url() const | - | ||||||||||||
459 | { | - | ||||||||||||
460 | return m_url; executed 1154 times by 5 tests: return m_url; Executed by:
| 1154 | ||||||||||||
461 | } | - | ||||||||||||
462 | - | |||||||||||||
463 | WorkerRemoveEvent::WorkerRemoveEvent(int workerId) | - | ||||||||||||
464 | : QEvent((QEvent::Type)WorkerRemove), m_id(workerId) | - | ||||||||||||
465 | { | - | ||||||||||||
466 | } executed 1152 times by 5 tests: end of block Executed by:
| 1152 | ||||||||||||
467 | - | |||||||||||||
468 | int WorkerRemoveEvent::workerId() const | - | ||||||||||||
469 | { | - | ||||||||||||
470 | return m_id; executed 1152 times by 5 tests: return m_id; Executed by:
| 1152 | ||||||||||||
471 | } | - | ||||||||||||
472 | - | |||||||||||||
473 | WorkerErrorEvent::WorkerErrorEvent(const QQmlError &error) | - | ||||||||||||
474 | : QEvent((QEvent::Type)WorkerError), m_error(error) | - | ||||||||||||
475 | { | - | ||||||||||||
476 | } executed 8 times by 1 test: end of block Executed by:
| 8 | ||||||||||||
477 | - | |||||||||||||
478 | QQmlError WorkerErrorEvent::error() const | - | ||||||||||||
479 | { | - | ||||||||||||
480 | return m_error; executed 8 times by 1 test: return m_error; Executed by:
| 8 | ||||||||||||
481 | } | - | ||||||||||||
482 | - | |||||||||||||
483 | QQuickWorkerScriptEngine::QQuickWorkerScriptEngine(QQmlEngine *parent) | - | ||||||||||||
484 | : QThread(parent), d(new QQuickWorkerScriptEnginePrivate(parent)) | - | ||||||||||||
485 | { | - | ||||||||||||
486 | d->m_lock.lock(); | - | ||||||||||||
487 | connect(d, SIGNAL(stopThread()), this, SLOT(quit()), Qt::DirectConnection); | - | ||||||||||||
488 | start(QThread::LowestPriority); | - | ||||||||||||
489 | d->m_wait.wait(&d->m_lock); | - | ||||||||||||
490 | d->moveToThread(this); | - | ||||||||||||
491 | d->m_lock.unlock(); | - | ||||||||||||
492 | } executed 1110 times by 5 tests: end of block Executed by:
| 1110 | ||||||||||||
493 | - | |||||||||||||
494 | QQuickWorkerScriptEngine::~QQuickWorkerScriptEngine() | - | ||||||||||||
495 | { | - | ||||||||||||
496 | d->m_lock.lock(); | - | ||||||||||||
497 | QCoreApplication::postEvent(d, new QEvent((QEvent::Type)QQuickWorkerScriptEnginePrivate::WorkerDestroyEvent)); | - | ||||||||||||
498 | d->m_lock.unlock(); | - | ||||||||||||
499 | - | |||||||||||||
500 | //We have to force to cleanup the main thread's event queue here | - | ||||||||||||
501 | //to make sure the main GUI release all pending locks/wait conditions which | - | ||||||||||||
502 | //some worker script/agent are waiting for (QQmlListModelWorkerAgent::sync() for example). | - | ||||||||||||
503 | while (!isFinished()) {
| 1110-136696 | ||||||||||||
504 | // We can't simply wait here, because the worker thread will not terminate | - | ||||||||||||
505 | // until the main thread processes the last data event it generates | - | ||||||||||||
506 | QCoreApplication::processEvents(); | - | ||||||||||||
507 | yieldCurrentThread(); | - | ||||||||||||
508 | } executed 136696 times by 5 tests: end of block Executed by:
| 136696 | ||||||||||||
509 | - | |||||||||||||
510 | d->deleteLater(); | - | ||||||||||||
511 | } executed 1110 times by 5 tests: end of block Executed by:
| 1110 | ||||||||||||
512 | - | |||||||||||||
513 | QQuickWorkerScriptEnginePrivate::WorkerScript::WorkerScript() | - | ||||||||||||
514 | : id(-1), initialized(false), owner(nullptr) | - | ||||||||||||
515 | { | - | ||||||||||||
516 | } executed 1152 times by 5 tests: end of block Executed by:
| 1152 | ||||||||||||
517 | - | |||||||||||||
518 | QQuickWorkerScriptEnginePrivate::WorkerScript::~WorkerScript() | - | ||||||||||||
519 | { | - | ||||||||||||
520 | } | - | ||||||||||||
521 | - | |||||||||||||
522 | int QQuickWorkerScriptEngine::registerWorkerScript(QQuickWorkerScript *owner) | - | ||||||||||||
523 | { | - | ||||||||||||
524 | typedef QQuickWorkerScriptEnginePrivate::WorkerScript WorkerScript; | - | ||||||||||||
525 | WorkerScript *script = new WorkerScript; | - | ||||||||||||
526 | - | |||||||||||||
527 | script->id = d->m_nextId++; | - | ||||||||||||
528 | script->owner = owner; | - | ||||||||||||
529 | - | |||||||||||||
530 | d->m_lock.lock(); | - | ||||||||||||
531 | d->workers.insert(script->id, script); | - | ||||||||||||
532 | d->m_lock.unlock(); | - | ||||||||||||
533 | - | |||||||||||||
534 | return script->id; executed 1152 times by 5 tests: return script->id; Executed by:
| 1152 | ||||||||||||
535 | } | - | ||||||||||||
536 | - | |||||||||||||
537 | void QQuickWorkerScriptEngine::removeWorkerScript(int id) | - | ||||||||||||
538 | { | - | ||||||||||||
539 | QQuickWorkerScriptEnginePrivate::WorkerScript* script = d->workers.value(id); | - | ||||||||||||
540 | if (script) {
| 0-1152 | ||||||||||||
541 | script->owner = nullptr; | - | ||||||||||||
542 | QCoreApplication::postEvent(d, new WorkerRemoveEvent(id)); | - | ||||||||||||
543 | } executed 1152 times by 5 tests: end of block Executed by:
| 1152 | ||||||||||||
544 | } executed 1152 times by 5 tests: end of block Executed by:
| 1152 | ||||||||||||
545 | - | |||||||||||||
546 | void QQuickWorkerScriptEngine::executeUrl(int id, const QUrl &url) | - | ||||||||||||
547 | { | - | ||||||||||||
548 | QCoreApplication::postEvent(d, new WorkerLoadEvent(id, url)); | - | ||||||||||||
549 | } executed 1154 times by 5 tests: end of block Executed by:
| 1154 | ||||||||||||
550 | - | |||||||||||||
551 | void QQuickWorkerScriptEngine::sendMessage(int id, const QByteArray &data) | - | ||||||||||||
552 | { | - | ||||||||||||
553 | QCoreApplication::postEvent(d, new WorkerDataEvent(id, data)); | - | ||||||||||||
554 | } executed 1182 times by 5 tests: end of block Executed by:
| 1182 | ||||||||||||
555 | - | |||||||||||||
556 | void QQuickWorkerScriptEngine::run() | - | ||||||||||||
557 | { | - | ||||||||||||
558 | d->m_lock.lock(); | - | ||||||||||||
559 | - | |||||||||||||
560 | d->workerEngine = new QQuickWorkerScriptEnginePrivate::WorkerEngine(d); | - | ||||||||||||
561 | d->workerEngine->init(); | - | ||||||||||||
562 | - | |||||||||||||
563 | d->m_wait.wakeAll(); | - | ||||||||||||
564 | - | |||||||||||||
565 | d->m_lock.unlock(); | - | ||||||||||||
566 | - | |||||||||||||
567 | exec(); | - | ||||||||||||
568 | - | |||||||||||||
569 | qDeleteAll(d->workers); | - | ||||||||||||
570 | d->workers.clear(); | - | ||||||||||||
571 | - | |||||||||||||
572 | delete d->workerEngine; d->workerEngine = nullptr; | - | ||||||||||||
573 | } executed 1110 times by 5 tests: end of block Executed by:
| 1110 | ||||||||||||
574 | - | |||||||||||||
575 | - | |||||||||||||
576 | /*! | - | ||||||||||||
577 | \qmltype WorkerScript | - | ||||||||||||
578 | \instantiates QQuickWorkerScript | - | ||||||||||||
579 | \ingroup qtquick-threading | - | ||||||||||||
580 | \inqmlmodule QtQuick | - | ||||||||||||
581 | \brief Enables the use of threads in a Qt Quick application. | - | ||||||||||||
582 | - | |||||||||||||
583 | Use WorkerScript to run operations in a new thread. | - | ||||||||||||
584 | This is useful for running operations in the background so | - | ||||||||||||
585 | that the main GUI thread is not blocked. | - | ||||||||||||
586 | - | |||||||||||||
587 | Messages can be passed between the new thread and the parent thread | - | ||||||||||||
588 | using \l sendMessage() and the \c onMessage() handler. | - | ||||||||||||
589 | - | |||||||||||||
590 | An example: | - | ||||||||||||
591 | - | |||||||||||||
592 | \snippet qml/workerscript/workerscript.qml 0 | - | ||||||||||||
593 | - | |||||||||||||
594 | The above worker script specifies a JavaScript file, "script.js", that handles | - | ||||||||||||
595 | the operations to be performed in the new thread. Here is \c script.js: | - | ||||||||||||
596 | - | |||||||||||||
597 | \quotefile qml/workerscript/script.js | - | ||||||||||||
598 | - | |||||||||||||
599 | When the user clicks anywhere within the rectangle, \c sendMessage() is | - | ||||||||||||
600 | called, triggering the \tt WorkerScript.onMessage() handler in | - | ||||||||||||
601 | \tt script.js. This in turn sends a reply message that is then received | - | ||||||||||||
602 | by the \tt onMessage() handler of \tt myWorker. | - | ||||||||||||
603 | - | |||||||||||||
604 | - | |||||||||||||
605 | \section3 Restrictions | - | ||||||||||||
606 | - | |||||||||||||
607 | Since the \c WorkerScript.onMessage() function is run in a separate thread, the | - | ||||||||||||
608 | JavaScript file is evaluated in a context separate from the main QML engine. This means | - | ||||||||||||
609 | that unlike an ordinary JavaScript file that is imported into QML, the \c script.js | - | ||||||||||||
610 | in the above example cannot access the properties, methods or other attributes | - | ||||||||||||
611 | of the QML item, nor can it access any context properties set on the QML object | - | ||||||||||||
612 | through QQmlContext. | - | ||||||||||||
613 | - | |||||||||||||
614 | Additionally, there are restrictions on the types of values that can be passed to and | - | ||||||||||||
615 | from the worker script. See the sendMessage() documentation for details. | - | ||||||||||||
616 | - | |||||||||||||
617 | Worker script can not use \l {qtqml-javascript-imports.html}{.import} syntax. | - | ||||||||||||
618 | - | |||||||||||||
619 | \sa {Qt Quick Examples - Threading}, | - | ||||||||||||
620 | {Threaded ListModel Example} | - | ||||||||||||
621 | */ | - | ||||||||||||
622 | QQuickWorkerScript::QQuickWorkerScript(QObject *parent) | - | ||||||||||||
623 | : QObject(parent), m_engine(nullptr), m_scriptId(-1), m_componentComplete(true) | - | ||||||||||||
624 | { | - | ||||||||||||
625 | } executed 1152 times by 5 tests: end of block Executed by:
| 1152 | ||||||||||||
626 | - | |||||||||||||
627 | QQuickWorkerScript::~QQuickWorkerScript() | - | ||||||||||||
628 | { | - | ||||||||||||
629 | if (m_scriptId != -1) m_engine->removeWorkerScript(m_scriptId); executed 1152 times by 5 tests: m_engine->removeWorkerScript(m_scriptId); Executed by:
| 0-1152 | ||||||||||||
630 | } executed 1152 times by 5 tests: end of block Executed by:
| 1152 | ||||||||||||
631 | - | |||||||||||||
632 | /*! | - | ||||||||||||
633 | \qmlproperty url WorkerScript::source | - | ||||||||||||
634 | - | |||||||||||||
635 | This holds the url of the JavaScript file that implements the | - | ||||||||||||
636 | \tt WorkerScript.onMessage() handler for threaded operations. | - | ||||||||||||
637 | */ | - | ||||||||||||
638 | QUrl QQuickWorkerScript::source() const | - | ||||||||||||
639 | { | - | ||||||||||||
640 | return m_source; executed 2 times by 1 test: return m_source; Executed by:
| 2 | ||||||||||||
641 | } | - | ||||||||||||
642 | - | |||||||||||||
643 | void QQuickWorkerScript::setSource(const QUrl &source) | - | ||||||||||||
644 | { | - | ||||||||||||
645 | if (m_source == source)
| 0-1154 | ||||||||||||
646 | return; never executed: return; | 0 | ||||||||||||
647 | - | |||||||||||||
648 | m_source = source; | - | ||||||||||||
649 | - | |||||||||||||
650 | if (engine())
| 2-1152 | ||||||||||||
651 | m_engine->executeUrl(m_scriptId, m_source); executed 2 times by 1 test: m_engine->executeUrl(m_scriptId, m_source); Executed by:
| 2 | ||||||||||||
652 | - | |||||||||||||
653 | emit sourceChanged(); | - | ||||||||||||
654 | } executed 1154 times by 5 tests: end of block Executed by:
| 1154 | ||||||||||||
655 | - | |||||||||||||
656 | /*! | - | ||||||||||||
657 | \qmlmethod WorkerScript::sendMessage(jsobject message) | - | ||||||||||||
658 | - | |||||||||||||
659 | Sends the given \a message to a worker script handler in another | - | ||||||||||||
660 | thread. The other worker script handler can receive this message | - | ||||||||||||
661 | through the onMessage() handler. | - | ||||||||||||
662 | - | |||||||||||||
663 | The \c message object may only contain values of the following | - | ||||||||||||
664 | types: | - | ||||||||||||
665 | - | |||||||||||||
666 | \list | - | ||||||||||||
667 | \li boolean, number, string | - | ||||||||||||
668 | \li JavaScript objects and arrays | - | ||||||||||||
669 | \li ListModel objects (any other type of QObject* is not allowed) | - | ||||||||||||
670 | \endlist | - | ||||||||||||
671 | - | |||||||||||||
672 | All objects and arrays are copied to the \c message. With the exception | - | ||||||||||||
673 | of ListModel objects, any modifications by the other thread to an object | - | ||||||||||||
674 | passed in \c message will not be reflected in the original object. | - | ||||||||||||
675 | */ | - | ||||||||||||
676 | void QQuickWorkerScript::sendMessage(QQmlV4Function *args) | - | ||||||||||||
677 | { | - | ||||||||||||
678 | if (!engine()) {
| 4-1182 | ||||||||||||
679 | qWarning("QQuickWorkerScript: Attempt to send message before WorkerScript establishment"); | - | ||||||||||||
680 | return; executed 4 times by 1 test: return; Executed by:
| 4 | ||||||||||||
681 | } | - | ||||||||||||
682 | - | |||||||||||||
683 | QV4::Scope scope(args->v4engine()); | - | ||||||||||||
684 | QV4::ScopedValue argument(scope, QV4::Primitive::undefinedValue()); | - | ||||||||||||
685 | if (args->length() != 0)
| 0-1182 | ||||||||||||
686 | argument = (*args)[0]; executed 1182 times by 5 tests: argument = (*args)[0]; Executed by:
| 1182 | ||||||||||||
687 | - | |||||||||||||
688 | m_engine->sendMessage(m_scriptId, QV4::Serialize::serialize(argument, scope.engine)); | - | ||||||||||||
689 | } executed 1182 times by 5 tests: end of block Executed by:
| 1182 | ||||||||||||
690 | - | |||||||||||||
691 | void QQuickWorkerScript::classBegin() | - | ||||||||||||
692 | { | - | ||||||||||||
693 | m_componentComplete = false; | - | ||||||||||||
694 | } executed 1152 times by 5 tests: end of block Executed by:
| 1152 | ||||||||||||
695 | - | |||||||||||||
696 | QQuickWorkerScriptEngine *QQuickWorkerScript::engine() | - | ||||||||||||
697 | { | - | ||||||||||||
698 | if (m_engine) return m_engine; executed 1184 times by 5 tests: return m_engine; Executed by:
| 1184-2308 | ||||||||||||
699 | if (m_componentComplete) {
| 1152-1156 | ||||||||||||
700 | QQmlEngine *engine = qmlEngine(this); | - | ||||||||||||
701 | if (!engine) {
| 0-1152 | ||||||||||||
702 | qWarning("QQuickWorkerScript: engine() called without qmlEngine() set"); | - | ||||||||||||
703 | return nullptr; never executed: return nullptr; | 0 | ||||||||||||
704 | } | - | ||||||||||||
705 | - | |||||||||||||
706 | m_engine = QQmlEnginePrivate::get(engine)->getWorkerScriptEngine(); | - | ||||||||||||
707 | m_scriptId = m_engine->registerWorkerScript(this); | - | ||||||||||||
708 | - | |||||||||||||
709 | if (m_source.isValid())
| 0-1152 | ||||||||||||
710 | m_engine->executeUrl(m_scriptId, m_source); executed 1152 times by 5 tests: m_engine->executeUrl(m_scriptId, m_source); Executed by:
| 1152 | ||||||||||||
711 | - | |||||||||||||
712 | return m_engine; executed 1152 times by 5 tests: return m_engine; Executed by:
| 1152 | ||||||||||||
713 | } | - | ||||||||||||
714 | return nullptr; executed 1156 times by 5 tests: return nullptr; Executed by:
| 1156 | ||||||||||||
715 | } | - | ||||||||||||
716 | - | |||||||||||||
717 | void QQuickWorkerScript::componentComplete() | - | ||||||||||||
718 | { | - | ||||||||||||
719 | m_componentComplete = true; | - | ||||||||||||
720 | engine(); // Get it started now. | - | ||||||||||||
721 | } executed 1152 times by 5 tests: end of block Executed by:
| 1152 | ||||||||||||
722 | - | |||||||||||||
723 | /*! | - | ||||||||||||
724 | \qmlsignal WorkerScript::message(jsobject msg) | - | ||||||||||||
725 | - | |||||||||||||
726 | This signal is emitted when a message \a msg is received from a worker | - | ||||||||||||
727 | script in another thread through a call to sendMessage(). | - | ||||||||||||
728 | - | |||||||||||||
729 | The corresponding handler is \c onMessage. | - | ||||||||||||
730 | */ | - | ||||||||||||
731 | - | |||||||||||||
732 | bool QQuickWorkerScript::event(QEvent *event) | - | ||||||||||||
733 | { | - | ||||||||||||
734 | if (event->type() == (QEvent::Type)WorkerDataEvent::WorkerData) {
| 8-972 | ||||||||||||
735 | QQmlEngine *engine = qmlEngine(this); | - | ||||||||||||
736 | if (engine) {
| 0-972 | ||||||||||||
737 | WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event); | - | ||||||||||||
738 | QV4::Scope scope(engine->handle()); | - | ||||||||||||
739 | QV4::ScopedValue value(scope, QV4::Serialize::deserialize(workerEvent->data(), scope.engine)); | - | ||||||||||||
740 | emit message(QQmlV4Handle(value)); | - | ||||||||||||
741 | } executed 972 times by 4 tests: end of block Executed by:
| 972 | ||||||||||||
742 | return true; executed 972 times by 4 tests: return true; Executed by:
| 972 | ||||||||||||
743 | } else if (event->type() == (QEvent::Type)WorkerErrorEvent::WorkerError) {
| 0-8 | ||||||||||||
744 | WorkerErrorEvent *workerEvent = static_cast<WorkerErrorEvent *>(event); | - | ||||||||||||
745 | QQmlEnginePrivate::warning(qmlEngine(this), workerEvent->error()); | - | ||||||||||||
746 | return true; executed 8 times by 1 test: return true; Executed by:
| 8 | ||||||||||||
747 | } else { | - | ||||||||||||
748 | return QObject::event(event); never executed: return QObject::event(event); | 0 | ||||||||||||
749 | } | - | ||||||||||||
750 | } | - | ||||||||||||
751 | - | |||||||||||||
752 | QT_END_NAMESPACE | - | ||||||||||||
753 | - | |||||||||||||
754 | #include <qquickworkerscript.moc> | - | ||||||||||||
755 | - | |||||||||||||
756 | #include "moc_qquickworkerscript_p.cpp" | - | ||||||||||||
Source code | Switch to Preprocessed file |