From 1e5dd7d82d542527ca9e650f78a5e25b6a3ebc41 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 16 Jun 2009 14:32:04 +1000 Subject: Deferred properties mostly work. However, they still don't honour the presence of an id property. --- src/declarative/qml/qmlengine.cpp | 9 +++-- src/declarative/qml/qmlvme.cpp | 38 +++++++++++++++++----- src/declarative/qml/qmlvme_p.h | 4 ++- .../qmlbindengine/deferredProperties.txt | 5 +++ tests/auto/declarative/qmlbindengine/testtypes.cpp | 1 + tests/auto/declarative/qmlbindengine/testtypes.h | 25 ++++++++++++++ .../qmlbindengine/tst_qmlbindengine.cpp | 18 ++++++++++ 7 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 tests/auto/declarative/qmlbindengine/deferredProperties.txt diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index a43b9b9..36b6424 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -71,7 +71,7 @@ #include #include "private/qmlmetaproperty_p.h" #include - +#include QT_BEGIN_NAMESPACE @@ -710,7 +710,12 @@ void qmlExecuteDeferred(QObject *object) { QmlInstanceDeclarativeData *data = QmlInstanceDeclarativeData::get(object); - if (data) { + if (data && data->deferredComponent) { + QmlVME vme; + vme.runDeferred(object); + + data->deferredComponent->release(); + data->deferredComponent = 0; } } diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index e65b206..ccf12b0 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -89,16 +89,11 @@ QmlVME::QmlVME() struct ListInstance { ListInstance() {} - /* - ListInstance(const QVariant &l, int t) - : list(l), type(t), qmlListInterface(0) {} - */ ListInstance(QList *q, int t) : type(t), qListInterface(q), qmlListInterface(0) {} ListInstance(QmlPrivate::ListInterface *q, int t) : type(t), qListInterface(0), qmlListInterface(q) {} - //QVariant list; int type; QList *qListInterface; QmlPrivate::ListInterface *qmlListInterface; @@ -106,6 +101,35 @@ struct ListInstance QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, int count) { + QStack stack; + + if (start == -1) start = 0; + if (count == -1) count = comp->bytecode.count(); + + return run(stack, ctxt, comp, start, count); +} + +void QmlVME::runDeferred(QObject *object) +{ + QmlInstanceDeclarativeData *data = QmlInstanceDeclarativeData::get(object); + + if (!data || !data->context || !data->deferredComponent) + return; + + QmlContext *ctxt = data->context; + ctxt->activate(); + QmlCompiledComponent *comp = data->deferredComponent; + int start = data->deferredIdx + 1; + int count = data->deferredComponent->bytecode.at(data->deferredIdx).defer.deferCount; + QStack stack; + stack.push(object); + + run(stack, ctxt, comp, start, count); + ctxt->deactivate(); +} + +QObject *QmlVME::run(QStack &stack, QmlContext *ctxt, QmlCompiledComponent *comp, int start, int count) +{ // XXX - All instances of QmlContext::activeContext() here should be // replaced with the use of ctxt. However, this cannot be done until // behaviours stop modifying the active context and expecting the @@ -126,7 +150,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in QmlEnginePrivate::SimpleList bindValues; QmlEnginePrivate::SimpleList parserStatus; - QStack stack; QStack qliststack; QStack pushedProperties; @@ -134,9 +157,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in vmeErrors.clear(); - if (start == -1) start = 0; - if (count == -1) count = comp->bytecode.count(); - for (int ii = start; !isError() && ii < (start + count); ++ii) { QmlInstruction &instr = comp->bytecode[ii]; diff --git a/src/declarative/qml/qmlvme_p.h b/src/declarative/qml/qmlvme_p.h index f2ed576..149c82c 100644 --- a/src/declarative/qml/qmlvme_p.h +++ b/src/declarative/qml/qmlvme_p.h @@ -58,12 +58,14 @@ class QmlVME public: QmlVME(); - QObject *run(QmlContext *, QmlCompiledComponent *, int start = -1, int end = -1); + QObject *run(QmlContext *, QmlCompiledComponent *, int start = -1, int count = -1); + void runDeferred(QObject *); bool isError() const; QList errors() const; private: + QObject *run(QStack &, QmlContext *, QmlCompiledComponent *, int start, int count); QList vmeErrors; }; diff --git a/tests/auto/declarative/qmlbindengine/deferredProperties.txt b/tests/auto/declarative/qmlbindengine/deferredProperties.txt new file mode 100644 index 0000000..41aa891 --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/deferredProperties.txt @@ -0,0 +1,5 @@ +MyDeferredObject { + value: 10 + objectProperty: MyQmlObject {} + objectProperty2: MyQmlObject { id: blah } +} diff --git a/tests/auto/declarative/qmlbindengine/testtypes.cpp b/tests/auto/declarative/qmlbindengine/testtypes.cpp index 4bb0dc8..afac27b 100644 --- a/tests/auto/declarative/qmlbindengine/testtypes.cpp +++ b/tests/auto/declarative/qmlbindengine/testtypes.cpp @@ -1,4 +1,5 @@ #include "testtypes.h" QML_DEFINE_TYPE(MyQmlObject,MyQmlObject); +QML_DEFINE_TYPE(MyDeferredObject,MyDeferredObject); QML_DEFINE_TYPE(MyQmlContainer,MyQmlContainer); diff --git a/tests/auto/declarative/qmlbindengine/testtypes.h b/tests/auto/declarative/qmlbindengine/testtypes.h index 6a4bda6..1934fe0 100644 --- a/tests/auto/declarative/qmlbindengine/testtypes.h +++ b/tests/auto/declarative/qmlbindengine/testtypes.h @@ -122,6 +122,31 @@ public: int millipedeLegs() const { return 1000; } }; +class MyDeferredObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int value READ value WRITE setValue) + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty); + Q_PROPERTY(QObject *objectProperty2 READ objectProperty2 WRITE setObjectProperty2); + Q_CLASSINFO("DeferredPropertyNames", "value,objectProperty,objectProperty2"); + +public: + MyDeferredObject() : m_value(0), m_object(0), m_object2(0) {} + + int value() const { return m_value; } + void setValue(int v) { m_value = v; } + + QObject *objectProperty() const { return m_object; } + void setObjectProperty(QObject *obj) { m_object = obj; } + + QObject *objectProperty2() const { return m_object2; } + void setObjectProperty2(QObject *obj) { m_object2 = obj; } +private: + int m_value; + QObject *m_object; + QObject *m_object2; +}; +QML_DECLARE_TYPE(MyDeferredObject); #endif // TESTTYPES_H diff --git a/tests/auto/declarative/qmlbindengine/tst_qmlbindengine.cpp b/tests/auto/declarative/qmlbindengine/tst_qmlbindengine.cpp index a1efc5f..0ff66c4 100644 --- a/tests/auto/declarative/qmlbindengine/tst_qmlbindengine.cpp +++ b/tests/auto/declarative/qmlbindengine/tst_qmlbindengine.cpp @@ -36,6 +36,7 @@ private slots: void arrayExpressions(); void contextPropertiesTriggerReeval(); void objectPropertiesTriggerReeval(); + void deferredProperties(); private: QmlEngine engine; @@ -337,6 +338,23 @@ void tst_qmlbindengine::objectPropertiesTriggerReeval() } } +void tst_qmlbindengine::deferredProperties() +{ + QmlComponent component(&engine, TEST_FILE("deferredProperties.txt")); + MyDeferredObject *object = + qobject_cast(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->value(), 0); + QVERIFY(object->objectProperty() == 0); + QVERIFY(object->objectProperty2() != 0); + qmlExecuteDeferred(object); + QCOMPARE(object->value(), 10); + QVERIFY(object->objectProperty() != 0); + MyQmlObject *qmlObject = + qobject_cast(object->objectProperty()); + QVERIFY(qmlObject != 0); +} + QTEST_MAIN(tst_qmlbindengine) #include "tst_qmlbindengine.moc" -- cgit v0.12