aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qqmlecmascript/testtypes.h
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-05-14 16:04:33 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2014-07-26 04:37:48 +0200
commit14bc8dc3f3016889cfcbdbe7309b09be7687ebe0 (patch)
tree5d0cd6a0939f497562d67fede6fbec0fd9a6a8ba /tests/auto/qml/qqmlecmascript/testtypes.h
parentba8416b80f42c81387170620472194e7a76429b8 (diff)
Fix interaction of garbage collector with JS objects during QML type instantiation
It may happen that during the lengthy process of instantiating a tree of objects for QML, the garbage collector runs. For objects created by QML we support different ownership models, for example in QtQuick visual parents keep their visual children alive, despite perhaps a lack of QObject parentship. That ownership becomes active once the QML autoparent function has assigned the correct visual parent, which happens after object instantiation (after QQmlObjectCreator). Similarly when a composite type is created, its QObject parent is only set after all properties have been set. The root QObject is kept alive through a special boolean, but if the sub-objects aren't children yet, their JS wrapper might get deleted. For composite types with var properties, that also means their var properties get deleted, such as the model property of TableView.qml in the bug report. In the future we want to support creating QWidget hierarchies with QML, which also for layouts may rely on a delayed parent assignment for layouts. To accommodate all this, this patch introduces an array on the JS stack that keeps track of all JS wrappers for all QObjects created. This array is alive during object tree creation. Afterwards, the different ownership models take over, for example the auto parent function assigning a visual parent. This patch also fixes an off-by-one in the total object count calculation for composite types, where when instantiating a composite type as a sub-object we counted the sub composite's object count but forgot the object itself. Task-number: QTBUG-38835 Task-number: QTBUG-39966 Change-Id: I6104b2434510642081e0c54793ed296adeca7481 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'tests/auto/qml/qqmlecmascript/testtypes.h')
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h45
1 files changed, 45 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index 928d594f62..d5a1220f23 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -1661,6 +1661,51 @@ public:
};
};
+// Like QtObject, but with default property
+class QObjectContainer : public QObject
+{
+ Q_OBJECT
+ Q_CLASSINFO("DefaultProperty", "data")
+ Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false)
+public:
+ QObjectContainer();
+
+ QQmlListProperty<QObject> data();
+
+ static void children_append(QQmlListProperty<QObject> *prop, QObject *o);
+ static int children_count(QQmlListProperty<QObject> *prop);
+ static QObject *children_at(QQmlListProperty<QObject> *prop, int index);
+ static void children_clear(QQmlListProperty<QObject> *prop);
+
+ QList<QObject*> dataChildren;
+ QWidget *widgetParent;
+ bool gcOnAppend;
+
+protected slots:
+ void childDestroyed(QObject *child);
+};
+
+class QObjectContainerWithGCOnAppend : public QObjectContainer
+{
+ Q_OBJECT
+public:
+ QObjectContainerWithGCOnAppend()
+ {
+ gcOnAppend = true;
+ }
+};
+
+class FloatingQObject : public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+public:
+ FloatingQObject() {}
+
+ virtual void classBegin();
+ virtual void componentComplete();
+};
+
void registerTypes();
#endif // TESTTYPES_H