Allow object to be accessed by multiple QDeclarativeEngines
authorAaron Kennedy <aaron.kennedy@nokia.com>
Mon, 25 Jul 2011 05:47:40 +0000 (15:47 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 25 Jul 2011 05:49:00 +0000 (07:49 +0200)
Task-number: QTBUG-18610

Change-Id: Idd9444018b5344586d6579ddac6a0ffd26bf7139
Reviewed-on: http://codereview.qt.nokia.com/2075
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
src/declarative/qml/qdeclarativepropertycache.cpp
src/declarative/qml/v8/qv8qobjectwrapper.cpp
tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp

index 8dba8e4..6ff47d7 100644 (file)
@@ -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);
index f10c49a..393f837 100644 (file)
@@ -878,7 +878,7 @@ v8::Local<v8::Object> 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
index 17249ab..e9bd735 100644 (file)
@@ -49,6 +49,7 @@
 #include <QDebug>
 #include <QDeclarativeComponent>
 #include <QDeclarativeNetworkAccessManagerFactory>
+#include <QDeclarativeExpression>
 
 #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"