diff options
author | Leander Beernaert <leander.beernaert@qt.io> | 2020-01-16 16:25:06 +0100 |
---|---|---|
committer | Leander Beernaert <leander.beernaert@qt.io> | 2020-01-16 16:25:06 +0100 |
commit | 1d333d3375874efb8d37df37dc5ef561573794ad (patch) | |
tree | 2d8c995f64c05c84c1fcceb2c5cb40fcae69855f /src/qmlworkerscript | |
parent | b106d86c433706928b0b0c206a0d9f831681e1bf (diff) | |
parent | e79a2658cde899d6ee11ec3c0d0a3768eb2c864b (diff) |
Merge remote-tracking branch 'origin/dev' into wip/cmake
Change-Id: I0c5b939c70bdb91ccdf7068784308416dcaa5736
Diffstat (limited to 'src/qmlworkerscript')
-rw-r--r-- | src/qmlworkerscript/doc/qtqmlworkerscript.qdocconf | 6 | ||||
-rw-r--r-- | src/qmlworkerscript/doc/snippets/qml/workerscript/script.mjs | 4 | ||||
-rw-r--r-- | src/qmlworkerscript/doc/snippets/qml/workerscript/workerscript.qml | 74 | ||||
-rw-r--r-- | src/qmlworkerscript/qmlworkerscript.pro | 8 | ||||
-rw-r--r-- | src/qmlworkerscript/qqmlworkerscriptmodule.cpp | 51 | ||||
-rw-r--r-- | src/qmlworkerscript/qqmlworkerscriptmodule_p.h | 66 | ||||
-rw-r--r-- | src/qmlworkerscript/qquickworkerscript.cpp | 24 | ||||
-rw-r--r-- | src/qmlworkerscript/qquickworkerscript_p.h | 8 | ||||
-rw-r--r-- | src/qmlworkerscript/qv4serialize.cpp | 49 |
9 files changed, 148 insertions, 142 deletions
diff --git a/src/qmlworkerscript/doc/qtqmlworkerscript.qdocconf b/src/qmlworkerscript/doc/qtqmlworkerscript.qdocconf index bb883cf39f..e56e1759b3 100644 --- a/src/qmlworkerscript/doc/qtqmlworkerscript.qdocconf +++ b/src/qmlworkerscript/doc/qtqmlworkerscript.qdocconf @@ -23,15 +23,13 @@ qhp.QtQmlWorkerScript.sortPages = true tagfile = qtqmlworkerscript.tags -depends += qtcore qtqml qtdoc +depends += qtcore qtqml qtquick qtdoc headerdirs += .. sourcedirs += .. \ ../../imports/workerscript -exampledirs += ../../../examples/qml \ - ../ \ - snippets +exampledirs += snippets navigation.qmltypespage = "Qt Qml WorkerScript QML Types" diff --git a/src/qmlworkerscript/doc/snippets/qml/workerscript/script.mjs b/src/qmlworkerscript/doc/snippets/qml/workerscript/script.mjs new file mode 100644 index 0000000000..f55dee3507 --- /dev/null +++ b/src/qmlworkerscript/doc/snippets/qml/workerscript/script.mjs @@ -0,0 +1,4 @@ +WorkerScript.onMessage = function(message) { + // ... long-running operations and calculations are done here + WorkerScript.sendMessage({ 'reply': 'Mouse is at ' + message.x + ',' + message.y }) +} diff --git a/src/qmlworkerscript/doc/snippets/qml/workerscript/workerscript.qml b/src/qmlworkerscript/doc/snippets/qml/workerscript/workerscript.qml new file mode 100644 index 0000000000..cc637d34cf --- /dev/null +++ b/src/qmlworkerscript/doc/snippets/qml/workerscript/workerscript.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![0] +import QtQuick 2.0 + +Rectangle { + width: 300; height: 300 + + Text { + id: myText + text: 'Click anywhere' + } + + WorkerScript { + id: myWorker + source: "script.mjs" + + onMessage: myText.text = messageObject.reply + } + + MouseArea { + anchors.fill: parent + onClicked: myWorker.sendMessage({ 'x': mouse.x, 'y': mouse.y }) + } +} +//![0] diff --git a/src/qmlworkerscript/qmlworkerscript.pro b/src/qmlworkerscript/qmlworkerscript.pro index 9f5e0e809a..b091937796 100644 --- a/src/qmlworkerscript/qmlworkerscript.pro +++ b/src/qmlworkerscript/qmlworkerscript.pro @@ -6,17 +6,21 @@ QMAKE_DOCS = $$PWD/doc/qtqmlworkerscript.qdocconf DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FOREACH HEADERS += \ - qqmlworkerscriptmodule_p.h \ qquickworkerscript_p.h \ qtqmlworkerscriptglobal.h \ qtqmlworkerscriptglobal_p.h \ qv4serialize_p.h SOURCES += \ - qqmlworkerscriptmodule.cpp \ qquickworkerscript.cpp \ qv4serialize.cpp include(../3rdparty/masm/masm-defs.pri) +QMLTYPES_FILENAME = plugins.qmltypes +QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/WorkerScript.2 +QML_IMPORT_NAME = QtQml.WorkerScript +IMPORT_VERSION = 2.15 +CONFIG += qmltypes install_qmltypes install_metatypes + load(qt_module) diff --git a/src/qmlworkerscript/qqmlworkerscriptmodule.cpp b/src/qmlworkerscript/qqmlworkerscriptmodule.cpp deleted file mode 100644 index b85456a633..0000000000 --- a/src/qmlworkerscript/qqmlworkerscriptmodule.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmlworkerscriptmodule_p.h" -#include "qquickworkerscript_p.h" - -QT_BEGIN_NAMESPACE - -void QQmlWorkerScriptModule::defineModule() -{ - const char uri[] = "QtQml.WorkerScript"; - qmlRegisterTypesAndRevisions<QQuickWorkerScript>(uri, 2); -} - -QT_END_NAMESPACE diff --git a/src/qmlworkerscript/qqmlworkerscriptmodule_p.h b/src/qmlworkerscript/qqmlworkerscriptmodule_p.h deleted file mode 100644 index ae52d10c16..0000000000 --- a/src/qmlworkerscript/qqmlworkerscriptmodule_p.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQMLWORKERSCRIPTMODULE_P_H -#define QQMLWORKERSCRIPTMODULE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qtqmlworkerscriptglobal_p.h> - -QT_BEGIN_NAMESPACE - -class Q_QMLWORKERSCRIPT_PRIVATE_EXPORT QQmlWorkerScriptModule -{ -public: - static void defineModule(); -}; - -QT_END_NAMESPACE - -#endif // QQMLWORKERSCRIPTMODULE_P_H diff --git a/src/qmlworkerscript/qquickworkerscript.cpp b/src/qmlworkerscript/qquickworkerscript.cpp index 8b236697b9..72ae6d5bd4 100644 --- a/src/qmlworkerscript/qquickworkerscript.cpp +++ b/src/qmlworkerscript/qquickworkerscript.cpp @@ -130,6 +130,7 @@ struct WorkerScript : public QV4::ExecutionEngine { QQuickWorkerScriptEnginePrivate *p = nullptr; QUrl source; QQuickWorkerScript *owner = nullptr; + QScopedPointer<QNetworkAccessManager> scriptLocalNAM; int id = -1; }; @@ -389,6 +390,16 @@ WorkerScript::WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent) QV4::ScopedValue sendMessage(scope, QV4::FunctionObject::createBuiltinFunction(this, name, QQuickWorkerScriptEnginePrivate::method_sendMessage, 1)); api->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("sendMessage"))), sendMessage); globalObject->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("WorkerScript"))), api); + networkAccessManager = [](QV4::ExecutionEngine *engine){ + auto *workerScript = static_cast<WorkerScript *>(engine); + if (workerScript->scriptLocalNAM) + return workerScript->scriptLocalNAM.get(); + if (auto *namFactory = workerScript->p->qmlengine->networkAccessManagerFactory()) + workerScript->scriptLocalNAM.reset(namFactory->create(workerScript->p)); + else + workerScript->scriptLocalNAM.reset(new QNetworkAccessManager(workerScript->p)); + return workerScript->scriptLocalNAM.get(); + }; } int QQuickWorkerScriptEngine::registerWorkerScript(QQuickWorkerScript *owner) @@ -533,6 +544,17 @@ void QQuickWorkerScript::setSource(const QUrl &source) } /*! + \qmlproperty url WorkerScript::ready + + This holds whether the WorkerScript has been initialized and is ready + for receiving messages via \tt WorkerScript.sendMessage(). +*/ +bool QQuickWorkerScript::ready() const +{ + return m_engine != nullptr; +} + +/*! \qmlmethod WorkerScript::sendMessage(jsobject message) Sends the given \a message to a worker script handler in another @@ -592,6 +614,8 @@ QQuickWorkerScriptEngine *QQuickWorkerScript::engine() if (m_source.isValid()) m_engine->executeUrl(m_scriptId, m_source); + emit readyChanged(); + return m_engine; } return nullptr; diff --git a/src/qmlworkerscript/qquickworkerscript_p.h b/src/qmlworkerscript/qquickworkerscript_p.h index 9b5d3587fb..03581089e0 100644 --- a/src/qmlworkerscript/qquickworkerscript_p.h +++ b/src/qmlworkerscript/qquickworkerscript_p.h @@ -53,6 +53,7 @@ #include <qqml.h> +#include <QtQmlWorkerScript/private/qtqmlworkerscriptglobal_p.h> #include <QtQml/qqmlparserstatus.h> #include <QtCore/qthread.h> #include <QtQml/qjsvalue.h> @@ -83,10 +84,12 @@ private: }; class QQmlV4Function; -class Q_AUTOTEST_EXPORT QQuickWorkerScript : public QObject, public QQmlParserStatus +class Q_QMLWORKERSCRIPT_PRIVATE_EXPORT QQuickWorkerScript : public QObject, public QQmlParserStatus { Q_OBJECT Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(bool ready READ ready NOTIFY readyChanged) + QML_NAMED_ELEMENT(WorkerScript); Q_INTERFACES(QQmlParserStatus) @@ -97,11 +100,14 @@ public: QUrl source() const; void setSource(const QUrl &); + bool ready() const; + public Q_SLOTS: void sendMessage(QQmlV4Function*); Q_SIGNALS: void sourceChanged(); + void readyChanged(); void message(const QJSValue &messageObject); protected: diff --git a/src/qmlworkerscript/qv4serialize.cpp b/src/qmlworkerscript/qv4serialize.cpp index a5e62d3e35..f0a644a8b8 100644 --- a/src/qmlworkerscript/qv4serialize.cpp +++ b/src/qmlworkerscript/qv4serialize.cpp @@ -81,6 +81,7 @@ enum Type { WorkerDate, WorkerRegexp, WorkerListModel, + WorkerUrl, #if QT_CONFIG(qml_sequence_object) WorkerSequence #endif @@ -142,10 +143,29 @@ static inline void *popPtr(const char *&data) return rv; } +#define ALIGN(size) (((size) + 3) & ~3) +static inline void serializeString(QByteArray &data, const QString &str, Type type) +{ + int length = str.length(); + if (length > 0xFFFFFF) { + push(data, valueheader(WorkerUndefined)); + return; + } + int utf16size = ALIGN(length * sizeof(quint16)); + + reserve(data, utf16size + sizeof(quint32)); + push(data, valueheader(type, length)); + + int offset = data.size(); + data.resize(data.size() + utf16size); + char *buffer = data.data() + offset; + + memcpy(buffer, str.constData(), length*sizeof(QChar)); +} + // XXX TODO: Check that worker script is exception safe in the case of // serialization/deserialization failures -#define ALIGN(size) (((size) + 3) & ~3) void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine *engine) { QV4::Scope scope(engine); @@ -159,22 +179,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine } else if (v.isBoolean()) { push(data, valueheader(v.booleanValue() == true ? WorkerTrue : WorkerFalse)); } else if (v.isString()) { - const QString &qstr = v.toQString(); - int length = qstr.length(); - if (length > 0xFFFFFF) { - push(data, valueheader(WorkerUndefined)); - return; - } - int utf16size = ALIGN(length * sizeof(quint16)); - - reserve(data, utf16size + sizeof(quint32)); - push(data, valueheader(WorkerString, length)); - - int offset = data.size(); - data.resize(data.size() + utf16size); - char *buffer = data.data() + offset; - - memcpy(buffer, qstr.constData(), length*sizeof(QChar)); + serializeString(data, v.toQString(), WorkerString); } else if (v.as<FunctionObject>()) { // XXX TODO: Implement passing function objects between the main and // worker scripts @@ -259,6 +264,11 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine return; } #endif + const QVariant variant = engine->toVariant(v, QMetaType::QUrl, false); + if (variant.userType() == QMetaType::QUrl) { + serializeString(data, variant.value<QUrl>().toString(), WorkerUrl); + return; + } // regular object QV4::ScopedValue val(scope, v); @@ -340,11 +350,14 @@ ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine) case WorkerFalse: return QV4::Encode(false); case WorkerString: + case WorkerUrl: { quint32 size = headersize(header); QString qstr((const QChar *)data, size); data += ALIGN(size * sizeof(quint16)); - return QV4::Encode(engine->newString(qstr)); + return (type == WorkerUrl) + ? engine->fromVariant(QVariant::fromValue(QUrl(qstr))) + : Encode(engine->newString(qstr)); } case WorkerFunction: Q_ASSERT(!"Unreachable"); |