summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-06-11 08:47:07 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-06-11 08:47:07 (GMT)
commit7e541e9e4832a26339a44ee55d325ba089717e17 (patch)
tree8ac3583740a6df8642b42d9759f7782fbdd9817a /src/declarative
parentaef2140573c5b68062db2f1a2cf968a1637344ae (diff)
downloadQt-7e541e9e4832a26339a44ee55d325ba089717e17.zip
Qt-7e541e9e4832a26339a44ee55d325ba089717e17.tar.gz
Qt-7e541e9e4832a26339a44ee55d325ba089717e17.tar.bz2
Skeleton for property deferring
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/qml/qml.h1
-rw-r--r--src/declarative/qml/qmlcompiler.cpp54
-rw-r--r--src/declarative/qml/qmlcompiler_p.h1
-rw-r--r--src/declarative/qml/qmldeclarativedata_p.h94
-rw-r--r--src/declarative/qml/qmlengine.cpp41
-rw-r--r--src/declarative/qml/qmlinstruction_p.h8
-rw-r--r--src/declarative/qml/qmlvme.cpp13
7 files changed, 182 insertions, 30 deletions
diff --git a/src/declarative/qml/qml.h b/src/declarative/qml/qml.h
index 370bb58..51ca612 100644
--- a/src/declarative/qml/qml.h
+++ b/src/declarative/qml/qml.h
@@ -90,6 +90,7 @@ QT_MODULE(Declarative)
class QmlContext;
class QmlEngine;
+Q_DECLARATIVE_EXPORT void qmlExecuteDeferred(QObject *);
Q_DECLARATIVE_EXPORT QmlContext *qmlContext(const QObject *);
Q_DECLARATIVE_EXPORT QmlEngine *qmlEngine(const QObject *);
Q_DECLARATIVE_EXPORT QObject *qmlAttachedPropertiesObjectById(int, const QObject *);
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index d29ac1f..2a3cc8d 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -621,13 +621,19 @@ bool QmlCompiler::compileObject(Object *obj, const BindingContext &ctxt)
output->types.at(obj->type).type->customParser() != 0;
QList<QmlCustomParserProperty> customProps;
+ QStringList deferred = deferredProperties(obj);
+ QList<Property *> deferredProps;
+
// Compile all explicit properties specified
foreach(Property *prop, obj->properties) {
if (isCustomParser) {
// Custom parser types don't support signal properties
if (testProperty(prop, obj)) {
- COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
+ if (deferred.contains(prop->name))
+ deferredProps << prop;
+ else
+ COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
} else {
customProps << QmlCustomParserNodePrivate::fromProperty(prop);
}
@@ -635,7 +641,10 @@ bool QmlCompiler::compileObject(Object *obj, const BindingContext &ctxt)
if (isSignalPropertyName(prop->name)) {
COMPILE_CHECK(compileSignal(prop,obj));
} else {
- COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
+ if (deferred.contains(prop->name))
+ deferredProps << prop;
+ else
+ COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
}
}
@@ -647,12 +656,20 @@ bool QmlCompiler::compileObject(Object *obj, const BindingContext &ctxt)
if (isCustomParser) {
if (testProperty(prop, obj)) {
- COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
+ QMetaProperty p = deferred.isEmpty()?QMetaProperty():QmlMetaType::defaultProperty(obj->metaObject());
+ if (deferred.contains(p.name()))
+ deferredProps << prop;
+ else
+ COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
} else {
customProps << QmlCustomParserNodePrivate::fromProperty(prop);
}
} else {
- COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
+ QMetaProperty p = deferred.isEmpty()?QMetaProperty():QmlMetaType::defaultProperty(obj->metaObject());
+ if (deferred.contains(p.name()))
+ deferredProps << prop;
+ else
+ COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
}
}
@@ -670,6 +687,22 @@ bool QmlCompiler::compileObject(Object *obj, const BindingContext &ctxt)
output->indexForByteArray(customData);
}
+ // Build the deferred block (### Need to check for presence of "id")
+ if (!deferredProps.isEmpty()) {
+ QmlInstruction defer;
+ defer.type = QmlInstruction::Defer;
+ defer.line = 0;
+ int deferIdx = output->bytecode.count();
+ output->bytecode << defer;
+
+ foreach (Property *prop, deferredProps) {
+ COMPILE_CHECK(compileProperty(prop, obj, objCtxt));
+ }
+
+ output->bytecode[deferIdx].defer.deferCount =
+ output->bytecode.count() - deferIdx - 1;
+ }
+
// If the type support the QmlParserStatusInterface we need to invoke
// classComplete()
if (parserStatusCast != -1) {
@@ -1634,6 +1667,19 @@ bool QmlCompiler::canConvert(int convertType, QmlParser::Object *object)
return false;
}
+QStringList QmlCompiler::deferredProperties(QmlParser::Object *obj)
+{
+ const QMetaObject *mo = obj->metatype;
+
+ int idx = mo->indexOfClassInfo("DeferredPropertyNames");
+ if (idx == -1)
+ return QStringList();
+
+ QMetaClassInfo classInfo = mo->classInfo(idx);
+ QStringList rv = QString(QLatin1String(classInfo.value())).split(',');
+ return rv;
+}
+
QmlCompiledData::QmlCompiledData()
{
}
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 3b1a496..2559b14 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -180,6 +180,7 @@ private:
void finalizeBinding(const BindingReference &);
bool canConvert(int, QmlParser::Object *);
+ QStringList deferredProperties(QmlParser::Object *);
struct IdReference {
QString id;
diff --git a/src/declarative/qml/qmldeclarativedata_p.h b/src/declarative/qml/qmldeclarativedata_p.h
index fb7a015..b8d3cf4 100644
--- a/src/declarative/qml/qmldeclarativedata_p.h
+++ b/src/declarative/qml/qmldeclarativedata_p.h
@@ -52,20 +52,108 @@ public:
QmlSimpleDeclarativeData() : flags(0), context(0) {}
virtual void destroyed(QObject *);
- enum Flag { Extended = 0x00000001 };
+ enum Flag { Instance = 0x00000001, Extended = 0x00000002 };
quint32 flags;
QmlContext *context;
+
+ static inline QmlSimpleDeclarativeData *get(QObject *object,
+ bool create = false);
};
-class QmlExtendedDeclarativeData : public QmlSimpleDeclarativeData
+class QmlCompiledComponent;
+class QmlInstanceDeclarativeData : public QmlSimpleDeclarativeData
{
public:
- QmlExtendedDeclarativeData() { flags = Extended; }
+ QmlInstanceDeclarativeData() { flags |= Instance; }
virtual void destroyed(QObject *);
+
+ QmlCompiledComponent *deferredComponent;
+ unsigned int deferredIdx;
+
+ static inline QmlInstanceDeclarativeData *get(QObject *object,
+ bool create = false);
+};
+
+class QmlExtendedDeclarativeData : public QmlInstanceDeclarativeData
+{
+public:
+ QmlExtendedDeclarativeData() { flags |= Extended; }
+
QHash<int, QObject *> attachedProperties;
+
+ static inline QmlExtendedDeclarativeData *get(QObject *object,
+ bool create = false);
};
+QmlSimpleDeclarativeData *
+QmlSimpleDeclarativeData::get(QObject *object, bool create)
+{
+ QObjectPrivate *priv = QObjectPrivate::get(object);
+
+ if (create && !priv->declarativeData)
+ priv->declarativeData = new QmlInstanceDeclarativeData;
+
+ return static_cast<QmlSimpleDeclarativeData *>(priv->declarativeData);
+}
+
+QmlInstanceDeclarativeData *
+QmlInstanceDeclarativeData::get(QObject *object, bool create)
+{
+ QObjectPrivate *priv = QObjectPrivate::get(object);
+
+ QmlSimpleDeclarativeData *simple =
+ static_cast<QmlSimpleDeclarativeData *>(priv->declarativeData);
+
+ if (simple && (simple->flags & Instance)) {
+ return static_cast<QmlInstanceDeclarativeData *>(simple);
+ } else if (create && simple) {
+ QmlInstanceDeclarativeData *rv = new QmlInstanceDeclarativeData;
+ rv->context = simple->context;
+ simple->destroyed(object);
+ priv->declarativeData = rv;
+ return rv;
+ } else if (create) {
+ QmlInstanceDeclarativeData *rv = new QmlInstanceDeclarativeData;
+ priv->declarativeData = rv;
+ return rv;
+ }
+ return 0;
+}
+
+QmlExtendedDeclarativeData *
+QmlExtendedDeclarativeData::get(QObject *object, bool create)
+{
+ QObjectPrivate *priv = QObjectPrivate::get(object);
+
+ QmlSimpleDeclarativeData *simple =
+ static_cast<QmlSimpleDeclarativeData *>(priv->declarativeData);
+
+ if (simple && (simple->flags & Extended)) {
+ return static_cast<QmlExtendedDeclarativeData *>(simple);
+ } else if (create && simple) {
+ QmlExtendedDeclarativeData *rv = new QmlExtendedDeclarativeData;
+ rv->context = simple->context;
+
+ if (simple->flags & Instance) {
+ QmlInstanceDeclarativeData *instance =
+ static_cast<QmlInstanceDeclarativeData *>(priv->declarativeData);
+ rv->deferredComponent = instance->deferredComponent;
+ rv->deferredIdx = instance->deferredIdx;
+ delete simple;
+ } else {
+ simple->destroyed(object);
+ }
+ priv->declarativeData = rv;
+ return rv;
+ } else if (create) {
+ QmlExtendedDeclarativeData *rv = new QmlExtendedDeclarativeData;
+ priv->declarativeData = rv;
+ return rv;
+ }
+ return 0;
+}
+
QT_END_NAMESPACE
#endif // QMLDECLARATIVEDATA_P_H
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 66781ce..edc76c2 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -706,6 +706,14 @@ void QmlEngine::setContextForObject(QObject *object, QmlContext *context)
context->d_func()->contextObjects.append(object);
}
+void qmlExecuteDeferred(QObject *object)
+{
+ QmlInstanceDeclarativeData *data = QmlInstanceDeclarativeData::get(object);
+
+ if (data) {
+ }
+}
+
QmlContext *qmlContext(const QObject *obj)
{
return QmlEngine::contextForObject(obj);
@@ -719,36 +727,21 @@ QmlEngine *qmlEngine(const QObject *obj)
QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object)
{
- QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
-
-
- QmlSimpleDeclarativeData *data = static_cast<QmlSimpleDeclarativeData *>(priv->declarativeData);
+ QmlExtendedDeclarativeData *edata =
+ QmlExtendedDeclarativeData::get(const_cast<QObject *>(object), true);
- QmlExtendedDeclarativeData *edata = (data && data->flags & QmlSimpleDeclarativeData::Extended)?static_cast<QmlExtendedDeclarativeData *>(data):0;
-
- if (edata) {
- QObject *rv = edata->attachedProperties.value(id);
- if (rv)
- return rv;
- }
+ QObject *rv = edata->attachedProperties.value(id);
+ if (rv)
+ return rv;
QmlAttachedPropertiesFunc pf = QmlMetaType::attachedPropertiesFuncById(id);
if (!pf)
return 0;
- QObject *rv = pf(const_cast<QObject *>(object));
-
- if (rv) {
- if (!edata) {
-
- edata = new QmlExtendedDeclarativeData;
- if (data) edata->context = data->context;
- priv->declarativeData = edata;
-
- }
+ rv = pf(const_cast<QObject *>(object));
+ if (rv)
edata->attachedProperties.insert(id, rv);
- }
return rv;
}
@@ -759,9 +752,11 @@ void QmlSimpleDeclarativeData::destroyed(QObject *object)
context->d_func()->contextObjects.removeAll(object);
}
-void QmlExtendedDeclarativeData::destroyed(QObject *object)
+void QmlInstanceDeclarativeData::destroyed(QObject *object)
{
QmlSimpleDeclarativeData::destroyed(object);
+ if (deferredComponent)
+ deferredComponent->release();
delete this;
}
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 0f1f697..e3b0dfe 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -139,6 +139,11 @@ public:
PopFetchedObject,
PopQList,
+ //
+ // Deferred creation
+ //
+ Defer, /* defer */
+
//
// Expression optimizations
//
@@ -270,6 +275,9 @@ public:
int property;
int object;
} assignStackObject;
+ struct {
+ int deferCount;
+ } defer;
};
void dump(QmlCompiledComponent *);
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index 3a66c69..58972ef 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -44,6 +44,7 @@
#include <private/qmlboundsignal_p.h>
#include <private/qmlstringconverters_p.h>
#include "private/qmetaobjectbuilder_p.h"
+#include "private/qmldeclarativedata_p.h"
#include <qml.h>
#include <private/qmlcustomparser_p.h>
#include <qperformancelog.h>
@@ -745,6 +746,18 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
}
break;
+ case QmlInstruction::Defer:
+ {
+ QObject *target = stack.top();
+ QmlInstanceDeclarativeData *data =
+ QmlInstanceDeclarativeData::get(target, true);
+ comp->addref();
+ data->deferredComponent = comp;
+ data->deferredIdx = ii;
+ ii += instr.defer.deferCount;
+ }
+ break;
+
case QmlInstruction::PopFetchedObject:
{
stack.pop();