From c500bd41751ca253fe40868fe54557749736d109 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 25 Jul 2011 15:47:40 +1000 Subject: [PATCH] Allow object to be accessed by multiple QDeclarativeEngines Task-number: QTBUG-18610 Change-Id: Idd9444018b5344586d6579ddac6a0ffd26bf7139 Reviewed-on: http://codereview.qt.nokia.com/2075 Reviewed-by: Qt Sanity Bot Reviewed-by: Aaron Kennedy --- src/declarative/qml/qdeclarativepropertycache.cpp | 22 ++++++------- src/declarative/qml/v8/qv8qobjectwrapper.cpp | 2 +- .../qdeclarativeengine/tst_qdeclarativeengine.cpp | 37 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index 8dba8e4..6ff47d7 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -220,20 +220,17 @@ QDeclarativePropertyCache::QDeclarativePropertyCache(QDeclarativeEngine *e, cons QDeclarativePropertyCache::~QDeclarativePropertyCache() { clear(); -} -void QDeclarativePropertyCache::clear() -{ if (parent) parent->release(); parent = 0; +} - propertyIndexCacheStart = 0; - methodIndexCacheStart = 0; - - propertyIndexCache.clear(); - methodIndexCache.clear(); - stringCache.clear(); +// This is inherited from QDeclarativeCleanup, so it should only clear the things +// that are tied to the specific QDeclarativeEngine. +void QDeclarativePropertyCache::clear() +{ qPersistentDispose(constructor); + engine = 0; } QDeclarativePropertyCache::Data QDeclarativePropertyCache::create(const QMetaObject *metaObject, @@ -417,8 +414,7 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb { Q_ASSERT(engine); Q_ASSERT(metaObject); - - clear(); + Q_ASSERT(stringCache.isEmpty()); // Optimization to prevent unnecessary reallocation of lists propertyIndexCache.reserve(metaObject->propertyCount()); @@ -508,7 +504,7 @@ QDeclarativePropertyCache::property(QDeclarativeEngine *engine, QObject *obj, QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QDeclarativeData *ddata = QDeclarativeData::get(obj); - if (ddata && ddata->propertyCache && ddata->propertyCache->qmlEngine() == engine) // XXX aakenend + if (ddata && ddata->propertyCache) cache = ddata->propertyCache; if (!cache) { cache = ep->cache(obj); @@ -546,7 +542,7 @@ QDeclarativePropertyCache::property(QDeclarativeEngine *engine, QObject *obj, QDeclarativePropertyCache *cache = 0; QDeclarativeData *ddata = QDeclarativeData::get(obj); - if (ddata && ddata->propertyCache && ddata->propertyCache->qmlEngine() == engine) + if (ddata && ddata->propertyCache) cache = ddata->propertyCache; if (!cache) { cache = enginePrivate->cache(obj); diff --git a/src/declarative/qml/v8/qv8qobjectwrapper.cpp b/src/declarative/qml/v8/qv8qobjectwrapper.cpp index f10c49a..393f837 100644 --- a/src/declarative/qml/v8/qv8qobjectwrapper.cpp +++ b/src/declarative/qml/v8/qv8qobjectwrapper.cpp @@ -878,7 +878,7 @@ v8::Local QV8QObjectWrapper::newQObject(QObject *object, QDeclarativ if (ddata->propertyCache) ddata->propertyCache->addref(); } - if (ddata->propertyCache) { + if (ddata->propertyCache && ddata->propertyCache->qmlEngine() == engine->engine()) { rv = ddata->propertyCache->newQObject(object, engine); } else { // XXX NewInstance() should be optimized diff --git a/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp b/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp index 17249ab..e9bd735 100644 --- a/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp +++ b/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #ifdef Q_OS_SYMBIAN // In Symbian OS test data is located in applications private dir @@ -70,6 +71,7 @@ private slots: void clearComponentCache(); void outputWarningsToStandardError(); void objectOwnership(); + void multipleEngines(); }; void tst_qdeclarativeengine::rootContext() @@ -328,6 +330,41 @@ void tst_qdeclarativeengine::objectOwnership() } +// Test an object can be accessed by multiple engines +void tst_qdeclarativeengine::multipleEngines() +{ + QObject o; + o.setObjectName("TestName"); + + // Simultaneous engines + { + QDeclarativeEngine engine1; + QDeclarativeEngine engine2; + engine1.rootContext()->setContextProperty("object", &o); + engine2.rootContext()->setContextProperty("object", &o); + + QDeclarativeExpression expr1(engine1.rootContext(), 0, QString("object.objectName")); + QDeclarativeExpression expr2(engine2.rootContext(), 0, QString("object.objectName")); + + QCOMPARE(expr1.evaluate().toString(), QString("TestName")); + QCOMPARE(expr2.evaluate().toString(), QString("TestName")); + } + + // Serial engines + { + QDeclarativeEngine engine1; + engine1.rootContext()->setContextProperty("object", &o); + QDeclarativeExpression expr1(engine1.rootContext(), 0, QString("object.objectName")); + QCOMPARE(expr1.evaluate().toString(), QString("TestName")); + } + { + QDeclarativeEngine engine1; + engine1.rootContext()->setContextProperty("object", &o); + QDeclarativeExpression expr1(engine1.rootContext(), 0, QString("object.objectName")); + QCOMPARE(expr1.evaluate().toString(), QString("TestName")); + } +} + QTEST_MAIN(tst_qdeclarativeengine) #include "tst_qdeclarativeengine.moc" -- 2.7.4