Fixup list model serialization
authorLars Knoll <lars.knoll@digia.com>
Fri, 24 May 2013 12:50:03 +0000 (14:50 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Fri, 24 May 2013 14:16:39 +0000 (16:16 +0200)
We need to properly refcount the agent, so it doesn't get
deleted when it's still in use.

Change-Id: Id9a0764e15c10e7b15a216523d6b22764ac863dc
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/qml/v4/qv4serialize.cpp
src/qml/types/qqmllistmodelworkeragent_p.h

index 4e0efc7..f222e4d 100644 (file)
@@ -359,6 +359,11 @@ QV4::Value Serialize::deserialize(const char *&data, QV8Engine *engine)
         void *ptr = popPtr(data);
         QQmlListModelWorkerAgent *agent = (QQmlListModelWorkerAgent *)ptr;
         QV4::Value rv = engine->newQObject(agent);
+        // ### Find a better solution then the ugly property
+        QQmlListModelWorkerAgent::VariantRef ref(agent);
+        QVariant var = qVariantFromValue(ref);
+        rv.asObject()->defineReadonlyProperty(v4->newString("__qml:hidden:ref"), engine->fromVariant(var));
+
         agent->release();
         agent->setV8Engine(engine);
         return rv;
index 80ed5d9..e39c6f8 100644 (file)
@@ -90,6 +90,22 @@ public:
     Q_INVOKABLE void move(int from, int to, int count);
     Q_INVOKABLE void sync();
 
+    struct VariantRef
+    {
+        VariantRef() : a(0) {}
+        VariantRef(const VariantRef &r) : a(r.a) { if (a) a->addref(); }
+        VariantRef(QQmlListModelWorkerAgent *_a) : a(_a) { if (a) a->addref(); }
+        ~VariantRef() { if (a) a->release(); }
+
+        VariantRef &operator=(const VariantRef &o) {
+            if (o.a) o.a->addref();
+            if (a) a->release(); a = o.a;
+            return *this;
+        }
+
+        QQmlListModelWorkerAgent *a;
+    };
+
     void modelDestroyed();
 protected:
     virtual bool event(QEvent *);
@@ -135,5 +151,7 @@ private:
 
 QT_END_NAMESPACE
 
+Q_DECLARE_METATYPE(QQmlListModelWorkerAgent::VariantRef)
+
 #endif // QQUICKLISTMODELWORKERAGENT_P_H