aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/types/qquickworkerscript.cpp199
1 files changed, 55 insertions, 144 deletions
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 706982ba97..c4fc9a0532 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -139,48 +139,26 @@ public:
QQuickWorkerScriptEnginePrivate(QQmlEngine *eng);
- class WorkerEngine : public QV8Engine
- {
- public:
- WorkerEngine(QQuickWorkerScriptEnginePrivate *parent);
- ~WorkerEngine() override;
-
- void init(int id);
-
-#if QT_CONFIG(qml_network)
- QNetworkAccessManager *networkAccessManager() override;
-#endif
-
- QQuickWorkerScriptEnginePrivate *p;
-
- QV4::ReturnedValue sendFunction(int id);
-
- QV4::PersistentValue onmessage;
- private:
- QV4::PersistentValue createsend;
-#if QT_CONFIG(qml_network)
- QNetworkAccessManager *accessManager;
-#endif
- };
-
- static QQuickWorkerScriptEnginePrivate *get(QV8Engine *e) {
- return static_cast<WorkerEngine *>(e)->p;
- }
-
QQmlEngine *qmlengine;
QMutex m_lock;
QWaitCondition m_wait;
- struct WorkerScript {
+ struct WorkerScript : public QV8Engine {
WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent);
- ~WorkerScript();
+ ~WorkerScript() override;
+
+#if QT_CONFIG(qml_network)
+ QNetworkAccessManager *networkAccessManager() override;
+#endif
- QV4::ExecutionEngine *v4() const { return QV8Engine::getV4(workerEngine.data()); }
- QScopedPointer<WorkerEngine> workerEngine;
- int id;
+ QQuickWorkerScriptEnginePrivate *p = nullptr;
QUrl source;
- QQuickWorkerScript *owner;
+ QQuickWorkerScript *owner = nullptr;
+#if QT_CONFIG(qml_network)
+ QScopedPointer<QNetworkAccessManager> accessManager;
+#endif
+ int id = -1;
};
QHash<int, WorkerScript *> workers;
@@ -202,100 +180,6 @@ private:
void reportScriptException(WorkerScript *, const QQmlError &error);
};
-QQuickWorkerScriptEnginePrivate::WorkerEngine::WorkerEngine(QQuickWorkerScriptEnginePrivate *parent)
- : QV8Engine(new QV4::ExecutionEngine), p(parent)
-#if QT_CONFIG(qml_network)
-, accessManager(nullptr)
-#endif
-{
- m_v4Engine->v8Engine = this;
-}
-
-QQuickWorkerScriptEnginePrivate::WorkerEngine::~WorkerEngine()
-{
-#if QT_CONFIG(qml_network)
- delete accessManager;
-#endif
- delete m_v4Engine;
-}
-
-void QQuickWorkerScriptEnginePrivate::WorkerEngine::init(int id)
-{
- initQmlGlobalObject();
-#define CALL_ONMESSAGE_SCRIPT \
- "(function(message) { "\
- "var isfunction = false; "\
- "try { "\
- "isfunction = WorkerScript.onMessage instanceof Function; "\
- "} catch (e) {}" \
- "if (isfunction) "\
- "WorkerScript.onMessage(message); "\
- "})"
-
-#define SEND_MESSAGE_CREATE_SCRIPT \
- "(function(method, engine) { "\
- "return (function(id) { "\
- "return (function(message) { "\
- "if (arguments.length) method(engine, id, message); "\
- "}); "\
- "}); "\
- "})"
-
- QV4::Scope scope(m_v4Engine);
- QV4::ExecutionContext *globalContext = scope.engine->rootContext();
- 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
- Q_ASSERT(!scope.engine->hasException);
- 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
- QV4::ScopedFunctionObject createsendconstructor(scope, createsendscript.run());
- Q_ASSERT(!scope.engine->hasException);
- QV4::ScopedString name(scope, m_v4Engine->newString(QStringLiteral("sendMessage")));
- QV4::ScopedValue function(scope, QV4::FunctionObject::createBuiltinFunction(m_v4Engine, name, method_sendMessage, 1));
- QV4::JSCallData jsCallData(scope, 1);
- jsCallData->args[0] = function;
- *jsCallData->thisObject = m_v4Engine->global();
- createsend.set(scope.engine, createsendconstructor->call(jsCallData));
-
-
- QV4::ScopedValue v(scope, sendFunction(id));
- QV4::ScopedObject api(scope, scope.engine->newObject());
- api->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("sendMessage"))), v);
- m_v4Engine->globalObject->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("WorkerScript"))), api);
-}
-
-// Requires handle and context scope
-QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(int id)
-{
- QV4::ExecutionEngine *v4 = createsend.engine();
- if (!v4)
- return QV4::Encode::undefined();
-
- QV4::Scope scope(v4);
- QV4::ScopedFunctionObject f(scope, createsend.value());
-
- QV4::ScopedValue v(scope);
- QV4::JSCallData jsCallData(scope, 1);
- jsCallData->args[0] = QV4::Primitive::fromInt32(id);
- *jsCallData->thisObject = m_v4Engine->global();
- v = f->call(jsCallData);
- if (scope.hasException())
- v = scope.engine->catchException();
- return v->asReturnedValue();
-}
-
-#if QT_CONFIG(qml_network)
-QNetworkAccessManager *QQuickWorkerScriptEnginePrivate::WorkerEngine::networkAccessManager()
-{
- if (!accessManager) {
- if (p->qmlengine && p->qmlengine->networkAccessManagerFactory()) {
- accessManager = p->qmlengine->networkAccessManagerFactory()->create(p);
- } else {
- accessManager = new QNetworkAccessManager(p);
- }
- }
- return accessManager;
-}
-#endif
-
QQuickWorkerScriptEnginePrivate::QQuickWorkerScriptEnginePrivate(QQmlEngine *engine)
: qmlengine(engine), m_nextId(0)
{
@@ -305,15 +189,12 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4
const QV4::Value *, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
- WorkerEngine *engine = static_cast<WorkerEngine *>(scope.engine->v8Engine);
+ WorkerScript *script = static_cast<WorkerScript *>(scope.engine->v8Engine);
- int id = argc > 1 ? argv[1].toInt32() : 0;
-
- QV4::ScopedValue v(scope, argc > 2 ? argv[2] : QV4::Primitive::undefinedValue());
+ QV4::ScopedValue v(scope, argc > 0 ? argv[0] : QV4::Primitive::undefinedValue());
QByteArray data = QV4::Serialize::serialize(v, scope.engine);
- QMutexLocker locker(&engine->p->m_lock);
- WorkerScript *script = engine->p->workers.value(id);
+ QMutexLocker locker(&script->p->m_lock);
if (script && script->owner)
QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, data));
@@ -352,16 +233,23 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d
if (!script)
return;
- QV4::ExecutionEngine *v4 = script->v4();
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(script);
QV4::Scope scope(v4);
- QV4::ScopedFunctionObject f(scope, script->workerEngine->onmessage.value());
+ QV4::ScopedString v(scope);
+ QV4::ScopedObject worker(scope, v4->globalObject->get((v = v4->newString(QStringLiteral("WorkerScript")))));
+ QV4::ScopedFunctionObject onmessage(scope);
+ if (worker)
+ onmessage = worker->get((v = v4->newString(QStringLiteral("onMessage"))));
+
+ if (!onmessage)
+ return;
QV4::ScopedValue value(scope, QV4::Serialize::deserialize(data, v4));
QV4::JSCallData jsCallData(scope, 1);
*jsCallData->thisObject = v4->global();
jsCallData->args[0] = value;
- f->call(jsCallData);
+ onmessage->call(jsCallData);
if (scope.hasException()) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
reportScriptException(script, error);
@@ -379,7 +267,7 @@ void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
if (!script)
return;
- QV4::ExecutionEngine *v4 = script->v4();
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(script);
QV4::Scope scope(v4);
QScopedPointer<QV4::Script> program;
@@ -405,9 +293,7 @@ void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
void QQuickWorkerScriptEnginePrivate::reportScriptException(WorkerScript *script,
const QQmlError &error)
{
- QQuickWorkerScriptEnginePrivate *p = QQuickWorkerScriptEnginePrivate::get(script->workerEngine.data());
-
- QMutexLocker locker(&p->m_lock);
+ QMutexLocker locker(&script->p->m_lock);
if (script->owner)
QCoreApplication::postEvent(script->owner, new WorkerErrorEvent(error));
}
@@ -497,16 +383,41 @@ QQuickWorkerScriptEngine::~QQuickWorkerScriptEngine()
}
QQuickWorkerScriptEnginePrivate::WorkerScript::WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent)
-: id(id), owner(nullptr)
+ : QV8Engine(new QV4::ExecutionEngine)
+ , p(parent)
+ , id(id)
{
- workerEngine.reset(new QQuickWorkerScriptEnginePrivate::WorkerEngine(parent));
- workerEngine->init(id);
+ m_v4Engine->v8Engine = this;
+
+ initQmlGlobalObject();
+
+ QV4::Scope scope(m_v4Engine);
+ QV4::ScopedObject api(scope, scope.engine->newObject());
+ QV4::ScopedString name(scope, m_v4Engine->newString(QStringLiteral("sendMessage")));
+ QV4::ScopedValue sendMessage(scope, QV4::FunctionObject::createBuiltinFunction(m_v4Engine, name, method_sendMessage, 1));
+ api->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("sendMessage"))), sendMessage);
+ m_v4Engine->globalObject->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("WorkerScript"))), api);
}
QQuickWorkerScriptEnginePrivate::WorkerScript::~WorkerScript()
{
+ delete m_v4Engine;
}
+#if QT_CONFIG(qml_network)
+QNetworkAccessManager *QQuickWorkerScriptEnginePrivate::WorkerScript::networkAccessManager()
+{
+ if (!accessManager) {
+ if (p->qmlengine && p->qmlengine->networkAccessManagerFactory()) {
+ accessManager.reset(p->qmlengine->networkAccessManagerFactory()->create(p));
+ } else {
+ accessManager.reset(new QNetworkAccessManager(p));
+ }
+ }
+ return accessManager.data();
+}
+#endif
+
int QQuickWorkerScriptEngine::registerWorkerScript(QQuickWorkerScript *owner)
{
typedef QQuickWorkerScriptEnginePrivate::WorkerScript WorkerScript;