summaryrefslogtreecommitdiffstats
path: root/src/declarative/util
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2009-12-09 21:39:21 (GMT)
committerMartin Jones <martin.jones@nokia.com>2009-12-09 21:39:21 (GMT)
commit0d0f02be045f05838d0c219321809b46db16b50d (patch)
treee2536960abee06d581e531b227085c3e8df49f0e /src/declarative/util
parentf107c0d9dfe5c854c1235d34755bbf1de34c4cb4 (diff)
downloadQt-0d0f02be045f05838d0c219321809b46db16b50d.zip
Qt-0d0f02be045f05838d0c219321809b46db16b50d.tar.gz
Qt-0d0f02be045f05838d0c219321809b46db16b50d.tar.bz2
Avoid creating a new dynamic metaobject for each delegate.
Diffstat (limited to 'src/declarative/util')
-rw-r--r--src/declarative/util/qmlopenmetaobject.cpp181
-rw-r--r--src/declarative/util/qmlopenmetaobject_p.h18
2 files changed, 145 insertions, 54 deletions
diff --git a/src/declarative/util/qmlopenmetaobject.cpp b/src/declarative/util/qmlopenmetaobject.cpp
index 04cd8a5..30457f9 100644
--- a/src/declarative/util/qmlopenmetaobject.cpp
+++ b/src/declarative/util/qmlopenmetaobject.cpp
@@ -40,70 +40,141 @@
****************************************************************************/
#include "qmlopenmetaobject_p.h"
-
+#include "qmlpropertycache_p.h"
+#include "qmldeclarativedata_p.h"
#include <qmetaobjectbuilder_p.h>
#include <QDebug>
QT_BEGIN_NAMESPACE
-class QmlOpenMetaObjectPrivate
+
+class QmlOpenMetaObjectTypePrivate
{
public:
- QmlOpenMetaObjectPrivate() : parent(0), mem(0) {}
+ QmlOpenMetaObjectTypePrivate() : mem(0), engine(0) {}
+
+ void init(QObject *obj);
- bool autoCreate;
- QAbstractDynamicMetaObject *parent;
int propertyOffset;
int signalOffset;
- QList<QVariant> data;
QHash<QByteArray, int> names;
QMetaObjectBuilder mob;
QMetaObject *mem;
+ QmlEngine *engine;
+};
+
+QmlOpenMetaObjectType::QmlOpenMetaObjectType(QmlEngine *engine)
+ : d(new QmlOpenMetaObjectTypePrivate)
+{
+ d->engine = engine;
+}
+
+QmlOpenMetaObjectType::~QmlOpenMetaObjectType()
+{
+ qFree(d->mem);
+}
+
+void QmlOpenMetaObjectTypePrivate::init(QObject *obj)
+{
+ if (!mem) {
+ mob.setSuperClass(obj->metaObject());
+ mob.setClassName(obj->metaObject()->className());
+ mob.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+
+ QObjectPrivate *op = QObjectPrivate::get(obj);
+ if (op->metaObject)
+ mob.setSuperClass(op->metaObject);
+ mem = mob.toMetaObject();
+
+ propertyOffset = mem->propertyOffset();
+ signalOffset = mem->methodOffset();
+ }
+}
+
+class QmlOpenMetaObjectPrivate
+{
+public:
+ QmlOpenMetaObjectPrivate(QmlOpenMetaObject *_q) : q(_q), parent(0), type(0), ownType(false) {}
+
+ inline QVariant &getData(int idx) {
+ while (data.count() <= idx)
+ data << QPair<QVariant, bool>(QVariant(), false);
+ QPair<QVariant, bool> &prop = data[idx];
+ if (!prop.second) {
+ prop.first = q->initialValue(idx);
+ prop.second = true;
+ }
+ return prop.first;
+ }
+
+ inline void writeData(int idx, const QVariant &value) {
+ while (data.count() <= idx)
+ data << QPair<QVariant, bool>(QVariant(), false);
+ QPair<QVariant, bool> &prop = data[idx];
+ prop.first = value;
+ prop.second = true;
+ }
+
+ bool autoCreate;
+ QmlOpenMetaObject *q;
+ QAbstractDynamicMetaObject *parent;
+ QList<QPair<QVariant, bool> > data;
QObject *object;
+ QmlOpenMetaObjectType *type;
+ bool ownType;
};
QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, bool automatic)
-: d(new QmlOpenMetaObjectPrivate)
+: d(new QmlOpenMetaObjectPrivate(this))
{
d->autoCreate = automatic;
d->object = obj;
- d->mob.setSuperClass(obj->metaObject());
- d->mob.setClassName(obj->metaObject()->className());
- d->mob.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+ d->type = new QmlOpenMetaObjectType(0);
+ d->ownType = true;
+ d->type->d->init(obj);
QObjectPrivate *op = QObjectPrivate::get(obj);
- if (op->metaObject)
- d->mob.setSuperClass(op->metaObject);
+ *static_cast<QMetaObject *>(this) = *d->type->d->mem;
+ op->metaObject = this;
+}
+
+QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, QmlOpenMetaObjectType *type, bool automatic)
+: d(new QmlOpenMetaObjectPrivate(this))
+{
+ d->autoCreate = automatic;
+ d->object = obj;
- d->mem = d->mob.toMetaObject();
- *static_cast<QMetaObject *>(this) = *d->mem;
+ d->type = type;
+ d->type->d->init(obj);
+
+ QObjectPrivate *op = QObjectPrivate::get(obj);
+ *static_cast<QMetaObject *>(this) = *d->type->d->mem;
op->metaObject = this;
- d->propertyOffset = propertyOffset();
- d->signalOffset = methodOffset();
}
QmlOpenMetaObject::~QmlOpenMetaObject()
{
if (d->parent)
delete d->parent;
- qFree(d->mem);
+ if (d->ownType)
+ delete d->type;
delete d;
}
int QmlOpenMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
{
if (( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty)
- && id >= d->propertyOffset) {
- int propId = id - d->propertyOffset;
+ && id >= d->type->d->propertyOffset) {
+ int propId = id - d->type->d->propertyOffset;
if (c == QMetaObject::ReadProperty) {
propertyRead(propId);
- *reinterpret_cast<QVariant *>(a[0]) = d->data[propId];
+ *reinterpret_cast<QVariant *>(a[0]) = d->getData(propId);
} else if (c == QMetaObject::WriteProperty) {
- if (d->data[propId] != *reinterpret_cast<QVariant *>(a[0])) {
+ if (d->data[propId].first != *reinterpret_cast<QVariant *>(a[0])) {
propertyWrite(propId);
- d->data[propId] = *reinterpret_cast<QVariant *>(a[0]);
- activate(d->object, d->signalOffset + propId, 0);
+ d->writeData(propId, *reinterpret_cast<QVariant *>(a[0]));
+ activate(d->object, d->type->d->signalOffset + propId, 0);
}
}
return -1;
@@ -117,50 +188,49 @@ int QmlOpenMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
QVariant QmlOpenMetaObject::value(int id) const
{
- Q_ASSERT(id >= 0 && id < d->data.count());
- return d->data.at(id);
+ return d->getData(id);
}
void QmlOpenMetaObject::setValue(int id, const QVariant &value)
{
- Q_ASSERT(id >= 0 && id < d->data.count());
- d->data[id] = value;
- activate(d->object, id + d->signalOffset, 0);
+ d->writeData(id, value);
+ activate(d->object, id + d->type->d->signalOffset, 0);
}
QVariant QmlOpenMetaObject::value(const QByteArray &name) const
{
- QHash<QByteArray, int>::ConstIterator iter = d->names.find(name);
- if (iter == d->names.end())
+ QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.find(name);
+ if (iter == d->type->d->names.end())
return QVariant();
- return d->data.at(*iter);
+ return d->getData(*iter);
}
QVariant &QmlOpenMetaObject::operator[](const QByteArray &name)
{
- QHash<QByteArray, int>::ConstIterator iter = d->names.find(name);
- Q_ASSERT(iter != d->names.end());
+ QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.find(name);
+ Q_ASSERT(iter != d->type->d->names.end());
- return d->data[*iter];
+ return d->getData(*iter);
}
void QmlOpenMetaObject::setValue(const QByteArray &name, const QVariant &val)
{
- QHash<QByteArray, int>::ConstIterator iter = d->names.find(name);
+ QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.find(name);
int id = -1;
- if (iter == d->names.end()) {
- id = doCreateProperty(name.constData()) - d->propertyOffset;
+ if (iter == d->type->d->names.end()) {
+ id = doCreateProperty(name.constData()) - d->type->d->propertyOffset;
} else {
id = *iter;
}
- if (d->data[id] == val)
+ QVariant &dataVal = d->getData(id);
+ if (dataVal == val)
return;
- d->data[id] = val;
- activate(d->object, id + d->signalOffset, 0);
+ dataVal = val;
+ activate(d->object, id + d->type->d->signalOffset, 0);
}
int QmlOpenMetaObject::createProperty(const char *name, const char *)
@@ -173,17 +243,18 @@ int QmlOpenMetaObject::createProperty(const char *name, const char *)
int QmlOpenMetaObject::doCreateProperty(const char *name)
{
- int id = d->mob.propertyCount();
- d->mob.addSignal("__" + QByteArray::number(id) + "()");
- QMetaPropertyBuilder build = d->mob.addProperty(name, "QVariant", id);
+ qDebug() << "doCreateProperty()" << name;
+ int id = d->type->d->mob.propertyCount();
+ d->type->d->mob.addSignal("__" + QByteArray::number(id) + "()");
+ QMetaPropertyBuilder build = d->type->d->mob.addProperty(name, "QVariant", id);
build.setDynamic(true);
- d->data << propertyCreated(id, build);
- qFree(d->mem);
- d->mem = d->mob.toMetaObject();
- *static_cast<QMetaObject *>(this) = *d->mem;
- d->names.insert(name, id);
+ propertyCreated(id, build);
+ qFree(d->type->d->mem);
+ d->type->d->mem = d->type->d->mob.toMetaObject();
+ *static_cast<QMetaObject *>(this) = *d->type->d->mem;
+ d->type->d->names.insert(name, id);
- return d->propertyOffset + id;
+ return d->type->d->propertyOffset + id;
}
void QmlOpenMetaObject::propertyRead(int)
@@ -194,21 +265,25 @@ void QmlOpenMetaObject::propertyWrite(int)
{
}
-QVariant QmlOpenMetaObject::propertyCreated(int, QMetaPropertyBuilder &)
+void QmlOpenMetaObject::propertyCreated(int id, QMetaPropertyBuilder &)
+{
+}
+
+QVariant QmlOpenMetaObject::initialValue(int)
{
return QVariant();
}
int QmlOpenMetaObject::count() const
{
- return d->data.count();
+ return d->type->d->names.count();
}
QByteArray QmlOpenMetaObject::name(int idx) const
{
- Q_ASSERT(idx >= 0 && idx < d->data.count());
+ Q_ASSERT(idx >= 0 && idx < d->type->d->names.count());
- return d->mob.property(idx).name();
+ return d->type->d->mob.property(idx).name();
}
QObject *QmlOpenMetaObject::object() const
diff --git a/src/declarative/util/qmlopenmetaobject_p.h b/src/declarative/util/qmlopenmetaobject_p.h
index 6045678..b33f99b 100644
--- a/src/declarative/util/qmlopenmetaobject_p.h
+++ b/src/declarative/util/qmlopenmetaobject_p.h
@@ -53,12 +53,27 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
+class QmlEngine;
+class QmlOpenMetaObjectTypePrivate;
+class QmlOpenMetaObjectType
+{
+public:
+ QmlOpenMetaObjectType(QmlEngine *engine);
+ ~QmlOpenMetaObjectType();
+
+private:
+ QmlOpenMetaObjectTypePrivate *d;
+ friend class QmlOpenMetaObject;
+ friend class QmlOpenMetaObjectPrivate;
+};
+
class QmlOpenMetaObjectPrivate;
class QMetaPropertyBuilder;
class Q_DECLARATIVE_EXPORT QmlOpenMetaObject : public QAbstractDynamicMetaObject
{
public:
QmlOpenMetaObject(QObject *, bool = true);
+ QmlOpenMetaObject(QObject *, QmlOpenMetaObjectType *, bool = true);
~QmlOpenMetaObject();
QVariant value(const QByteArray &) const;
@@ -71,13 +86,14 @@ public:
QByteArray name(int) const;
QObject *object() const;
+ virtual QVariant initialValue(int);
protected:
virtual int metaCall(QMetaObject::Call _c, int _id, void **_a);
virtual int createProperty(const char *, const char *);
virtual void propertyRead(int);
virtual void propertyWrite(int);
- virtual QVariant propertyCreated(int, QMetaPropertyBuilder &);
+ virtual void propertyCreated(int, QMetaPropertyBuilder &);
private:
int doCreateProperty(const char *);