summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-11-30 09:14:24 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-11-30 09:14:24 (GMT)
commite927cdd850053bd59c57056b72607853783bf35f (patch)
tree168df2ed5706db8e5871d7ff01870754be248603 /src
parentbd2ba54d85415047a581b7b441309572a756dcc5 (diff)
downloadQt-e927cdd850053bd59c57056b72607853783bf35f.zip
Qt-e927cdd850053bd59c57056b72607853783bf35f.tar.gz
Qt-e927cdd850053bd59c57056b72607853783bf35f.tar.bz2
Two way WorkerScript communications
Diffstat (limited to 'src')
-rw-r--r--src/declarative/qml/qmlengine.cpp1
-rw-r--r--src/declarative/qml/qmlmetatype.cpp8
-rw-r--r--src/declarative/qml/qmlobjectscriptclass.cpp8
-rw-r--r--src/declarative/qml/qmlpropertycache.cpp4
-rw-r--r--src/declarative/qml/qmlpropertycache_p.h3
-rw-r--r--src/declarative/qml/qmlworkerscript.cpp359
-rw-r--r--src/declarative/qml/qmlworkerscript_p.h30
7 files changed, 257 insertions, 156 deletions
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 864d07e..8429232 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -226,6 +226,7 @@ void QmlEnginePrivate::init()
Q_Q(QmlEngine);
qRegisterMetaType<QVariant>("QVariant");
qRegisterMetaType<QmlScriptString>("QmlScriptString");
+ qRegisterMetaType<QScriptValue>("QScriptValue");
scriptEngine.installTranslatorFunctions();
contextClass = new QmlContextScriptClass(q);
diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp
index 5fb2f50..46d967b 100644
--- a/src/declarative/qml/qmlmetatype.cpp
+++ b/src/declarative/qml/qmlmetatype.cpp
@@ -58,6 +58,7 @@
#include <qlocale.h>
#include <ctype.h>
#include <QtCore/qcryptographichash.h>
+#include <QtScript/qscriptvalue.h>
#include <private/qmlcustomparser_p.h>
#ifdef QT_BOOTSTRAPPED
@@ -929,6 +930,7 @@ QList<QmlType*> QmlMetaType::qmlTypes()
#include <QtGui/qvector3d.h>
#include <QtGui/qvector4d.h>
#include <QtGui/qquaternion.h>
+Q_DECLARE_METATYPE(QScriptValue);
/*!
Copies \a copy into \a data, assuming they both are of type \a type. If
@@ -1138,6 +1140,9 @@ bool QmlMetaType::copy(int type, void *data, const void *copy)
if (type == qMetaTypeId<QVariant>()) {
*static_cast<NS(QVariant) *>(data) = *static_cast<const NS(QVariant)*>(copy);
return true;
+ } else if (type == qMetaTypeId<QScriptValue>()) {
+ *static_cast<NS(QScriptValue) *>(data) = *static_cast<const NS(QScriptValue)*>(copy);
+ return true;
} else if (typeCategory(type) != Unknown) {
*static_cast<void **>(data) = *static_cast<void* const *>(copy);
return true;
@@ -1340,6 +1345,9 @@ bool QmlMetaType::copy(int type, void *data, const void *copy)
if (type == qMetaTypeId<QVariant>()) {
*static_cast<NS(QVariant) *>(data) = NS(QVariant)();
return true;
+ } else if (type == qMetaTypeId<QScriptValue>()) {
+ *static_cast<NS(QScriptValue) *>(data) = NS(QScriptValue)();
+ return true;
} else if (typeCategory(type) != Unknown) {
*static_cast<void **>(data) = 0;
return true;
diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp
index 1a6f724..f78a12a 100644
--- a/src/declarative/qml/qmlobjectscriptclass.cpp
+++ b/src/declarative/qml/qmlobjectscriptclass.cpp
@@ -229,12 +229,16 @@ QScriptValue QmlObjectScriptClass::property(QObject *obj, const Identifier &name
} else if (lastData->flags & QmlPropertyCache::Data::IsQmlList) {
return enginePriv->listClass->newList(obj, lastData->coreIndex,
QmlListScriptClass::QmlListPtr);
- } if (lastData->flags & QmlPropertyCache::Data::IsQObjectDerived) {
+ } else if (lastData->flags & QmlPropertyCache::Data::IsQObjectDerived) {
QObject *rv = 0;
void *args[] = { &rv, 0 };
QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args);
-
return newQObject(rv, lastData->propType);
+ } else if (lastData->flags & QmlPropertyCache::Data::IsQScriptValue) {
+ QScriptValue rv = scriptEngine->nullValue();
+ void *args[] = { &rv, 0 };
+ QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args);
+ return rv;
} else {
QVariant var = obj->metaObject()->property(lastData->coreIndex).read(obj);
return enginePriv->scriptValueFromVariant(var);
diff --git a/src/declarative/qml/qmlpropertycache.cpp b/src/declarative/qml/qmlpropertycache.cpp
index b7a5fad..ff4991c 100644
--- a/src/declarative/qml/qmlpropertycache.cpp
+++ b/src/declarative/qml/qmlpropertycache.cpp
@@ -45,6 +45,8 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_METATYPE(QScriptValue);
+
void QmlPropertyCache::Data::load(const QMetaProperty &p)
{
propType = p.userType();
@@ -61,6 +63,8 @@ void QmlPropertyCache::Data::load(const QMetaProperty &p)
if (propType == qMetaTypeId<QmlBinding *>()) {
flags |= Data::IsQmlBinding;
+ } else if (propType == qMetaTypeId<QScriptValue>()) {
+ flags |= Data::IsQScriptValue;
} else if (p.isEnumType()) {
flags |= Data::IsEnumType;
} else {
diff --git a/src/declarative/qml/qmlpropertycache_p.h b/src/declarative/qml/qmlpropertycache_p.h
index c2e8abe..8f19a8b 100644
--- a/src/declarative/qml/qmlpropertycache_p.h
+++ b/src/declarative/qml/qmlpropertycache_p.h
@@ -83,7 +83,8 @@ public:
IsEnumType = 0x00000010,
IsQmlList = 0x00000020,
IsQList = 0x00000040,
- IsQmlBinding = 0x00000080
+ IsQmlBinding = 0x00000080,
+ IsQScriptValue = 0x00000100
};
Q_DECLARE_FLAGS(Flags, Flag)
diff --git a/src/declarative/qml/qmlworkerscript.cpp b/src/declarative/qml/qmlworkerscript.cpp
index a6428dd..d4fcf4a 100644
--- a/src/declarative/qml/qmlworkerscript.cpp
+++ b/src/declarative/qml/qmlworkerscript.cpp
@@ -55,15 +55,15 @@ class WorkerDataEvent : public QEvent
public:
enum Type { WorkerData = QEvent::User };
- WorkerDataEvent(int workerId, QmlWorkerScriptEngine::Data *data);
+ WorkerDataEvent(int workerId, const QVariant &data);
virtual ~WorkerDataEvent();
int workerId() const;
- QmlWorkerScriptEngine::Data *takeData();
+ QVariant data() const;
private:
int m_id;
- QmlWorkerScriptEngine::Data *m_data;
+ QVariant m_data;
};
class WorkerLoadEvent : public QEvent
@@ -81,31 +81,64 @@ private:
QUrl m_url;
};
+class WorkerRemoveEvent : public QEvent
+{
+public:
+ enum Type { WorkerRemove = WorkerLoadEvent::WorkerLoad + 1 };
+
+ WorkerRemoveEvent(int workerId);
+
+ int workerId() const;
+
+private:
+ int m_id;
+};
+
class QmlWorkerScriptEnginePrivate : public QObject
{
public:
QmlWorkerScriptEnginePrivate();
- QScriptEngine *workerEngine;
+ struct ScriptEngine : public QScriptEngine
+ {
+ ScriptEngine(QmlWorkerScriptEnginePrivate *parent) : p(parent) {}
+ QmlWorkerScriptEnginePrivate *p;
+ };
+ ScriptEngine *workerEngine;
+ static QmlWorkerScriptEnginePrivate *get(QScriptEngine *e) {
+ return static_cast<ScriptEngine *>(e)->p;
+ }
QMutex m_lock;
QWaitCondition m_wait;
+ struct WorkerScript {
+ WorkerScript();
+
+ int id;
+ bool initialized;
+ QmlWorkerScript *owner;
+ QScriptValue object;
+
+ QScriptValue callback;
+ };
+
+ QHash<int, WorkerScript *> workers;
QScriptValue getWorker(int);
int m_nextId;
- QHash<int, QScriptValue> m_workers;
static QVariant scriptValueToVariant(const QScriptValue &);
static QScriptValue variantToScriptValue(const QVariant &, QScriptEngine *);
- static QScriptValue onmessage(QScriptContext *ctxt, QScriptEngine *engine);
+ static QScriptValue onMessage(QScriptContext *ctxt, QScriptEngine *engine);
+ static QScriptValue sendMessage(QScriptContext *ctxt, QScriptEngine *engine);
protected:
virtual bool event(QEvent *);
private:
- void processMessage(int, QmlWorkerScriptEngine::Data *);
+ void processMessage(int, const QVariant &);
void processLoad(int, const QUrl &);
};
@@ -114,34 +147,75 @@ QmlWorkerScriptEnginePrivate::QmlWorkerScriptEnginePrivate()
{
}
-QScriptValue QmlWorkerScriptEnginePrivate::onmessage(QScriptContext *ctxt, QScriptEngine *engine)
+QScriptValue QmlWorkerScriptEnginePrivate::onMessage(QScriptContext *ctxt, QScriptEngine *engine)
{
+ QmlWorkerScriptEnginePrivate *p = QmlWorkerScriptEnginePrivate::get(engine);
+
+ int id = ctxt->thisObject().data().toVariant().toInt();
+
+ WorkerScript *script = p->workers.value(id);
+ if (!script)
+ return engine->undefinedValue();
+
if (ctxt->argumentCount() >= 1)
- ctxt->thisObject().setData(ctxt->argument(0));
+ script->callback = ctxt->argument(0);
+
+ return script->callback;
+}
+
+QScriptValue QmlWorkerScriptEnginePrivate::sendMessage(QScriptContext *ctxt, QScriptEngine *engine)
+{
+ if (!ctxt->argumentCount())
+ return engine->undefinedValue();
+
+ QmlWorkerScriptEnginePrivate *p = QmlWorkerScriptEnginePrivate::get(engine);
+
+ int id = ctxt->thisObject().data().toVariant().toInt();
+
+ WorkerScript *script = p->workers.value(id);
+ if (!script)
+ return engine->undefinedValue();
- return ctxt->thisObject().data();
+ p->m_lock.lock();
+ if (script->owner)
+ QCoreApplication::postEvent(script->owner,
+ new WorkerDataEvent(0, scriptValueToVariant(ctxt->argument(0))));
+ p->m_lock.unlock();
+
+ return engine->undefinedValue();
}
QScriptValue QmlWorkerScriptEnginePrivate::getWorker(int id)
{
- QHash<int, QScriptValue>::Iterator iter = m_workers.find(id);
- if (iter == m_workers.end()) {
- QScriptValue worker = workerEngine->newObject();
+ QHash<int, WorkerScript *>::ConstIterator iter = workers.find(id);
+
+ if (iter == workers.end())
+ return workerEngine->nullValue();
+
+ WorkerScript *script = *iter;
+ if (!script->initialized) {
- worker.setProperty(QLatin1String("onmessage"), workerEngine->newFunction(onmessage),
- QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
+ script->initialized = true;
+ script->object = workerEngine->newObject();
- iter = m_workers.insert(id, worker);
+ QScriptValue api = workerEngine->newObject();
+ api.setData(script->id);
+
+ api.setProperty(QLatin1String("onMessage"), workerEngine->newFunction(onMessage),
+ QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
+ api.setProperty(QLatin1String("sendMessage"), workerEngine->newFunction(sendMessage));
+
+ script->object.setProperty(QLatin1String("WorkerScript"), api);
}
- return *iter;
+ return script->object;
}
bool QmlWorkerScriptEnginePrivate::event(QEvent *event)
{
if (event->type() == (QEvent::Type)WorkerDataEvent::WorkerData) {
WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event);
- processMessage(workerEvent->workerId(), workerEvent->takeData());
+ processMessage(workerEvent->workerId(), workerEvent->data());
return true;
} else if (event->type() == (QEvent::Type)WorkerLoadEvent::WorkerLoad) {
WorkerLoadEvent *workerEvent = static_cast<WorkerLoadEvent *>(event);
@@ -152,19 +226,18 @@ bool QmlWorkerScriptEnginePrivate::event(QEvent *event)
}
}
-void QmlWorkerScriptEnginePrivate::processMessage(int id, QmlWorkerScriptEngine::Data *data)
+void QmlWorkerScriptEnginePrivate::processMessage(int id, const QVariant &data)
{
- QScriptValue worker = getWorker(id);
- QScriptValue onmessage = worker.data();
+ WorkerScript *script = workers.value(id);
+ if (!script)
+ return;
- if (onmessage.isFunction()) {
+ if (script->callback.isFunction()) {
QScriptValue args = workerEngine->newArray(1);
- args.setProperty(0, variantToScriptValue(data->var, workerEngine));
+ args.setProperty(0, variantToScriptValue(data, workerEngine));
- onmessage.call(worker, args);
+ script->callback.call(script->object, args);
}
-
- if (data) delete data;
}
void QmlWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
@@ -190,14 +263,80 @@ void QmlWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
}
}
-WorkerDataEvent::WorkerDataEvent(int workerId, QmlWorkerScriptEngine::Data *data)
+QVariant QmlWorkerScriptEnginePrivate::scriptValueToVariant(const QScriptValue &value)
+{
+ if (value.isBool()) {
+ return QVariant(value.toBool());
+ } else if (value.isString()) {
+ return QVariant(value.toString());
+ } else if (value.isNumber()) {
+ return QVariant((qreal)value.toNumber());
+ } else if (value.isArray()) {
+ QVariantList list;
+
+ quint32 length = (quint32)value.property("length").toNumber();
+
+ for (quint32 ii = 0; ii < length; ++ii) {
+ QVariant v = scriptValueToVariant(ii);
+ list << v;
+ }
+
+ return QVariant(list);
+ } else if (value.isObject()) {
+ QVariantHash hash;
+
+ QScriptValueIterator iter(value);
+
+ while (iter.hasNext()) {
+ iter.next();
+ hash.insert(iter.name(), scriptValueToVariant(iter.value()));
+ }
+
+ return QVariant(hash);
+ }
+
+ return QVariant();
+
+}
+
+QScriptValue QmlWorkerScriptEnginePrivate::variantToScriptValue(const QVariant &value, QScriptEngine *engine)
+{
+ if (value.type() == QVariant::Bool) {
+ return QScriptValue(value.toBool());
+ } else if (value.type() == QVariant::String) {
+ return QScriptValue(value.toString());
+ } else if (value.type() == (QVariant::Type)QMetaType::QReal) {
+ return QScriptValue(value.toReal());
+ } else if (value.type() == (QVariant::Type)QMetaType::QVariantList) {
+ QVariantList list = qvariant_cast<QVariantList>(value);
+ QScriptValue rv = engine->newArray(list.count());
+
+ for (quint32 ii = 0; ii < list.count(); ++ii)
+ rv.setProperty(ii, variantToScriptValue(list.at(ii), engine));
+
+ return rv;
+ } else if (value.type() == (QVariant::Type)QMetaType::QVariantHash) {
+
+ QVariantHash hash = qvariant_cast<QVariantHash>(value);
+
+ QScriptValue rv = engine->newObject();
+
+ for (QVariantHash::ConstIterator iter = hash.begin(); iter != hash.end(); ++iter)
+ rv.setProperty(iter.key(), variantToScriptValue(iter.value(), engine));
+
+ return rv;
+ } else {
+ return engine->nullValue();
+ }
+}
+
+WorkerDataEvent::WorkerDataEvent(int workerId, const QVariant &data)
: QEvent((QEvent::Type)WorkerData), m_id(workerId), m_data(data)
{
}
WorkerDataEvent::~WorkerDataEvent()
{
- if (m_data) { delete m_data; m_data = 0; }
}
int WorkerDataEvent::workerId() const
@@ -205,11 +344,9 @@ int WorkerDataEvent::workerId() const
return m_id;
}
-QmlWorkerScriptEngine::Data *WorkerDataEvent::takeData()
+QVariant WorkerDataEvent::data() const
{
- QmlWorkerScriptEngine::Data *rv = m_data;
- m_data = 0;
- return rv;
+ return m_data;
}
WorkerLoadEvent::WorkerLoadEvent(int workerId, const QUrl &url)
@@ -227,6 +364,16 @@ QUrl WorkerLoadEvent::url() const
return m_url;
}
+WorkerRemoveEvent::WorkerRemoveEvent(int workerId)
+: QEvent((QEvent::Type)WorkerRemove), m_id(workerId)
+{
+}
+
+int WorkerRemoveEvent::workerId() const
+{
+ return m_id;
+}
+
QmlWorkerScriptEngine::QmlWorkerScriptEngine(QObject *parent)
: QThread(parent), d(new QmlWorkerScriptEnginePrivate)
{
@@ -234,6 +381,7 @@ QmlWorkerScriptEngine::QmlWorkerScriptEngine(QObject *parent)
start(QThread::LowPriority);
d->m_wait.wait(&d->m_lock);
d->moveToThread(this);
+ d->m_lock.unlock();
}
QmlWorkerScriptEngine::~QmlWorkerScriptEngine()
@@ -241,48 +389,44 @@ QmlWorkerScriptEngine::~QmlWorkerScriptEngine()
delete d; d = 0;
}
-QmlWorkerScriptEngine::WorkerScript::WorkerScript()
-: engine(0), id(0)
+QmlWorkerScriptEnginePrivate::WorkerScript::WorkerScript()
+: id(-1), initialized(false), owner(0)
{
}
-void QmlWorkerScriptEngine::WorkerScript::executeUrl(const QUrl &url)
+int QmlWorkerScriptEngine::registerWorkerScript(QmlWorkerScript *owner)
{
- engine->executeUrl(this, url);
-}
+ QmlWorkerScriptEnginePrivate::WorkerScript *script = new QmlWorkerScriptEnginePrivate::WorkerScript;
+ script->id = d->m_nextId++;
+ script->owner = owner;
-void QmlWorkerScriptEngine::WorkerScript::sendMessage(Data *data)
-{
- engine->sendMessage(this, data);
+ d->m_lock.lock();
+ d->workers.insert(script->id, script);
+ d->m_lock.unlock();
+
+ return script->id;
}
-void QmlWorkerScriptEngine::executeUrl(WorkerScript *script, const QUrl &data)
+void QmlWorkerScriptEngine::removeWorkerScript(int id)
{
- QCoreApplication::postEvent(d, new WorkerLoadEvent(script->id, data));
+ QCoreApplication::postEvent(d, new WorkerRemoveEvent(id));
}
-/*!
- Ownership of \a data transfers to QmlWorkerScriptEngine. It can not be modified by
- the caller.
-*/
-void QmlWorkerScriptEngine::sendMessage(WorkerScript *script, Data *data)
+void QmlWorkerScriptEngine::executeUrl(int id, const QUrl &url)
{
- QCoreApplication::postEvent(d, new WorkerDataEvent(script->id, data));
+ QCoreApplication::postEvent(d, new WorkerLoadEvent(id, url));
}
-QmlWorkerScriptEngine::WorkerScript *QmlWorkerScriptEngine::createWorkerScript()
+void QmlWorkerScriptEngine::sendMessage(int id, const QVariant &data)
{
- WorkerScript *rv = new WorkerScript;
- rv->engine = this;
- rv->id = d->m_nextId++;
- return rv;
+ QCoreApplication::postEvent(d, new WorkerDataEvent(id, data));
}
void QmlWorkerScriptEngine::run()
{
d->m_lock.lock();
- d->workerEngine = new QScriptEngine;
+ d->workerEngine = new QmlWorkerScriptEnginePrivate::ScriptEngine(d);
d->m_wait.wakeAll();
@@ -294,80 +438,13 @@ void QmlWorkerScriptEngine::run()
}
QmlWorkerScript::QmlWorkerScript(QObject *parent)
-: QObject(parent), m_script(0)
+: QObject(parent), m_engine(0), m_scriptId(-1)
{
}
QmlWorkerScript::~QmlWorkerScript()
{
- if (m_script) { delete m_script; m_script = 0; }
-}
-
-QVariant QmlWorkerScriptEnginePrivate::scriptValueToVariant(const QScriptValue &value)
-{
- if (value.isBool()) {
- return QVariant(value.toBool());
- } else if (value.isString()) {
- return QVariant(value.toString());
- } else if (value.isNumber()) {
- return QVariant((qreal)value.toNumber());
- } else if (value.isArray()) {
- QVariantList list;
-
- quint32 length = (quint32)value.property("length").toNumber();
-
- for (quint32 ii = 0; ii < length; ++ii) {
- QVariant v = scriptValueToVariant(ii);
- list << v;
- }
-
- return QVariant(list);
- } else if (value.isObject()) {
- QVariantHash hash;
-
- QScriptValueIterator iter(value);
-
- while (iter.hasNext()) {
- iter.next();
- hash.insert(iter.name(), scriptValueToVariant(iter.value()));
- }
-
- return QVariant(hash);
- }
-
- return QVariant();
-
-}
-
-QScriptValue QmlWorkerScriptEnginePrivate::variantToScriptValue(const QVariant &value, QScriptEngine *engine)
-{
- if (value.type() == QVariant::Bool) {
- return QScriptValue(value.toBool());
- } else if (value.type() == QVariant::String) {
- return QScriptValue(value.toString());
- } else if (value.type() == (QVariant::Type)QMetaType::QReal) {
- return QScriptValue(value.toReal());
- } else if (value.type() == (QVariant::Type)QMetaType::QVariantList) {
- QVariantList list = qvariant_cast<QVariantList>(value);
- QScriptValue rv = engine->newArray(list.count());
-
- for (quint32 ii = 0; ii < list.count(); ++ii)
- rv.setProperty(ii, variantToScriptValue(list.at(ii), engine));
-
- return rv;
- } else if (value.type() == (QVariant::Type)QMetaType::QVariantHash) {
-
- QVariantHash hash = qvariant_cast<QVariantHash>(value);
-
- QScriptValue rv = engine->newObject();
-
- for (QVariantHash::ConstIterator iter = hash.begin(); iter != hash.end(); ++iter)
- rv.setProperty(iter.key(), variantToScriptValue(iter.value(), engine));
-
- return rv;
- } else {
- return engine->nullValue();
- }
+ if (m_scriptId != -1) m_engine->removeWorkerScript(m_scriptId);
}
QUrl QmlWorkerScript::source() const
@@ -382,37 +459,55 @@ void QmlWorkerScript::setSource(const QUrl &source)
m_source = source;
- if (m_script)
- m_script->executeUrl(m_source);
+ if (m_engine)
+ m_engine->executeUrl(m_scriptId, m_source);
emit sourceChanged();
}
void QmlWorkerScript::sendMessage(const QScriptValue &message)
{
- if (!m_script) {
+ if (!m_engine) {
qWarning("QmlWorkerScript: Attempt to send message before WorkerScript establishment");
return;
}
- QmlWorkerScriptEngine::Data *data = new QmlWorkerScriptEngine::Data;
- data->var = QmlWorkerScriptEnginePrivate::scriptValueToVariant(message);
- m_script->sendMessage(data);
+ m_engine->sendMessage(m_scriptId, QmlWorkerScriptEnginePrivate::scriptValueToVariant(message));
}
void QmlWorkerScript::componentComplete()
{
- if (!m_script) {
+ if (!m_engine) {
QmlEngine *engine = qmlEngine(this);
if (!engine) {
qWarning("QmlWorkerScript: componentComplete() called without qmlEngine() set");
return;
}
- m_script = QmlEnginePrivate::get(engine)->getWorkerScriptEngine()->createWorkerScript();
+
+ m_engine = QmlEnginePrivate::get(engine)->getWorkerScriptEngine();
+ m_scriptId = m_engine->registerWorkerScript(this);
if (m_source.isValid())
- m_script->executeUrl(m_source);
+ m_engine->executeUrl(m_scriptId, m_source);
}
}
+bool QmlWorkerScript::event(QEvent *event)
+{
+ if (event->type() == (QEvent::Type)WorkerDataEvent::WorkerData) {
+ QmlEngine *engine = qmlEngine(this);
+ if (engine) {
+ QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
+ WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event);
+ QScriptValue value =
+ QmlWorkerScriptEnginePrivate::variantToScriptValue(workerEvent->data(), scriptEngine);
+ emit message(value);
+ }
+ return true;
+ } else {
+ return QObject::event(event);
+ }
+}
+
+
QML_DEFINE_TYPE(Qt, 4, 6, WorkerScript, QmlWorkerScript);
diff --git a/src/declarative/qml/qmlworkerscript_p.h b/src/declarative/qml/qmlworkerscript_p.h
index 90861f8..b7106c5 100644
--- a/src/declarative/qml/qmlworkerscript_p.h
+++ b/src/declarative/qml/qmlworkerscript_p.h
@@ -59,6 +59,7 @@
#include <QtScript/qscriptvalue.h>
#include <QtCore/qurl.h>
+class QmlWorkerScript;
class QmlWorkerScriptEnginePrivate;
class QmlWorkerScriptEngine : public QThread
{
@@ -67,26 +68,10 @@ public:
QmlWorkerScriptEngine(QObject *parent = 0);
virtual ~QmlWorkerScriptEngine();
- class Data;
- class WorkerScript {
- public:
- void sendMessage(Data *);
- void executeUrl(const QUrl &);
-
- private:
- WorkerScript();
- friend class QmlWorkerScriptEngine;
- QmlWorkerScriptEngine *engine;
- int id;
- };
- WorkerScript *createWorkerScript();
-
- struct Data {
- QVariant var;
- };
-
- void executeUrl(WorkerScript *, const QUrl &);
- void sendMessage(WorkerScript *, Data *);
+ int registerWorkerScript(QmlWorkerScript *);
+ void removeWorkerScript(int);
+ void executeUrl(int, const QUrl &);
+ void sendMessage(int, const QVariant &);
protected:
virtual void run();
@@ -112,12 +97,15 @@ public slots:
signals:
void sourceChanged();
+ void message(const QScriptValue &messageObject);
protected:
virtual void componentComplete();
+ virtual bool event(QEvent *);
private:
- QmlWorkerScriptEngine::WorkerScript *m_script;
+ QmlWorkerScriptEngine *m_engine;
+ int m_scriptId;
QUrl m_source;
};
QML_DECLARE_TYPE(QmlWorkerScript);