diff options
Diffstat (limited to 'src/declarative/util')
-rw-r--r-- | src/declarative/util/qmlopenmetaobject.cpp | 115 | ||||
-rw-r--r-- | src/declarative/util/qmlopenmetaobject_p.h | 22 |
2 files changed, 96 insertions, 41 deletions
diff --git a/src/declarative/util/qmlopenmetaobject.cpp b/src/declarative/util/qmlopenmetaobject.cpp index 473d9d9..e66a3e7 100644 --- a/src/declarative/util/qmlopenmetaobject.cpp +++ b/src/declarative/util/qmlopenmetaobject.cpp @@ -43,7 +43,7 @@ #include "qmlpropertycache_p.h" #include "qmldeclarativedata_p.h" #include <qmetaobjectbuilder_p.h> -#include <QDebug> +#include <qdebug.h> QT_BEGIN_NAMESPACE @@ -51,39 +51,69 @@ QT_BEGIN_NAMESPACE class QmlOpenMetaObjectTypePrivate { public: - QmlOpenMetaObjectTypePrivate() : mem(0), engine(0) {} + QmlOpenMetaObjectTypePrivate() : mem(0), cache(0), engine(0) {} - void init(QObject *obj); + void init(const QMetaObject *metaObj); int propertyOffset; int signalOffset; QHash<QByteArray, int> names; QMetaObjectBuilder mob; QMetaObject *mem; + QmlPropertyCache *cache; QmlEngine *engine; + QSet<QmlOpenMetaObject*> referers; }; -QmlOpenMetaObjectType::QmlOpenMetaObjectType(QmlEngine *engine) +QmlOpenMetaObjectType::QmlOpenMetaObjectType(const QMetaObject *base, QmlEngine *engine) : d(new QmlOpenMetaObjectTypePrivate) { d->engine = engine; + d->init(base); } QmlOpenMetaObjectType::~QmlOpenMetaObjectType() { + if (d->mem) + qFree(d->mem); + delete d; +} + +int QmlOpenMetaObjectType::createProperty(const QByteArray &name) +{ + int id = d->mob.propertyCount(); + d->mob.addSignal("__" + QByteArray::number(id) + "()"); + QMetaPropertyBuilder build = d->mob.addProperty(name, "QVariant", id); + build.setDynamic(true); + propertyCreated(id, build); qFree(d->mem); + d->mem = d->mob.toMetaObject(); + d->names.insert(name, id); + QSet<QmlOpenMetaObject*>::iterator it = d->referers.begin(); + while (it != d->referers.end()) { + QmlOpenMetaObject *omo = *it; + *static_cast<QMetaObject *>(omo) = *d->mem; + if (d->cache) + d->cache->update(d->engine, omo); + ++it; + } + + return d->propertyOffset + id; } -void QmlOpenMetaObjectTypePrivate::init(QObject *obj) +void QmlOpenMetaObjectType::propertyCreated(int id, QMetaPropertyBuilder &builder) +{ + if (d->referers.count()) + (*d->referers.begin())->propertyCreated(id, builder); +} + +void QmlOpenMetaObjectTypePrivate::init(const QMetaObject *metaObj) { if (!mem) { - mob.setSuperClass(obj->metaObject()); - mob.setClassName(obj->metaObject()->className()); + mob.setSuperClass(metaObj); + mob.setClassName(metaObj->className()); mob.setFlags(QMetaObjectBuilder::DynamicMetaObject); - QObjectPrivate *op = QObjectPrivate::get(obj); - if (op->metaObject) - mob.setSuperClass(op->metaObject); mem = mob.toMetaObject(); propertyOffset = mem->propertyOffset(); @@ -91,10 +121,13 @@ void QmlOpenMetaObjectTypePrivate::init(QObject *obj) } } +//---------------------------------------------------------------------------- + class QmlOpenMetaObjectPrivate { public: - QmlOpenMetaObjectPrivate(QmlOpenMetaObject *_q) : q(_q), parent(0), type(0), ownType(false) {} + QmlOpenMetaObjectPrivate(QmlOpenMetaObject *_q) + : q(_q), parent(0), type(0), cacheProperties(false) {} inline QVariant &getData(int idx) { while (data.count() <= idx) @@ -121,7 +154,7 @@ public: QList<QPair<QVariant, bool> > data; QObject *object; QmlOpenMetaObjectType *type; - bool ownType; + bool cacheProperties; }; QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, bool automatic) @@ -130,9 +163,8 @@ QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, bool automatic) d->autoCreate = automatic; d->object = obj; - d->type = new QmlOpenMetaObjectType(0); - d->ownType = true; - d->type->d->init(obj); + d->type = new QmlOpenMetaObjectType(obj->metaObject(), 0); + d->type->d->referers.insert(this); QObjectPrivate *op = QObjectPrivate::get(obj); *static_cast<QMetaObject *>(this) = *d->type->d->mem; @@ -146,7 +178,8 @@ QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, QmlOpenMetaObjectType *type, d->object = obj; d->type = type; - d->type->d->init(obj); + d->type->addref(); + d->type->d->referers.insert(this); QObjectPrivate *op = QObjectPrivate::get(obj); *static_cast<QMetaObject *>(this) = *d->type->d->mem; @@ -157,11 +190,16 @@ QmlOpenMetaObject::~QmlOpenMetaObject() { if (d->parent) delete d->parent; - if (d->ownType) - delete d->type; + d->type->d->referers.remove(this); + d->type->release(); delete d; } +QmlOpenMetaObjectType *QmlOpenMetaObject::type() const +{ + return d->type; +} + int QmlOpenMetaObject::metaCall(QMetaObject::Call c, int id, void **a) { if (( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty) @@ -220,7 +258,7 @@ void QmlOpenMetaObject::setValue(const QByteArray &name, const QVariant &val) int id = -1; if (iter == d->type->d->names.end()) { - id = doCreateProperty(name.constData()) - d->type->d->propertyOffset; + id = d->type->createProperty(name.constData()) - d->type->d->propertyOffset; } else { id = *iter; } @@ -233,29 +271,34 @@ void QmlOpenMetaObject::setValue(const QByteArray &name, const QVariant &val) activate(d->object, id + d->type->d->signalOffset, 0); } +void QmlOpenMetaObject::setCached(bool c) +{ + if (c == d->cacheProperties || !d->type->d->engine) + return; + + d->cacheProperties = c; + + QmlDeclarativeData *qmldata = QmlDeclarativeData::get(d->object, true); + if (d->cacheProperties) { + if (!d->type->d->cache) + d->type->d->cache = QmlPropertyCache::create(d->type->d->engine, this); + qmldata->propertyCache = d->type->d->cache; + d->type->d->cache->addref(); + } else { + if (d->type->d->cache) + d->type->d->cache->release(); + qmldata->propertyCache = 0; + } +} + int QmlOpenMetaObject::createProperty(const char *name, const char *) { if (d->autoCreate) - return doCreateProperty(name); + return d->type->createProperty(name); else return -1; } -int QmlOpenMetaObject::doCreateProperty(const char *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); - 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->type->d->propertyOffset + id; -} - void QmlOpenMetaObject::propertyRead(int) { } @@ -264,7 +307,7 @@ void QmlOpenMetaObject::propertyWrite(int) { } -void QmlOpenMetaObject::propertyCreated(int id, QMetaPropertyBuilder &) +void QmlOpenMetaObject::propertyCreated(int, QMetaPropertyBuilder &) { } diff --git a/src/declarative/util/qmlopenmetaobject_p.h b/src/declarative/util/qmlopenmetaobject_p.h index b33f99b..73e3a98 100644 --- a/src/declarative/util/qmlopenmetaobject_p.h +++ b/src/declarative/util/qmlopenmetaobject_p.h @@ -42,6 +42,7 @@ #ifndef QMLOPENMETAOBJECT_H #define QMLOPENMETAOBJECT_H +#include <qmlrefcount_p.h> #include <QtCore/QMetaObject> #include <QtCore/QObject> @@ -54,13 +55,19 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QmlEngine; +class QMetaPropertyBuilder; class QmlOpenMetaObjectTypePrivate; -class QmlOpenMetaObjectType +class QmlOpenMetaObjectType : public QmlRefCount { public: - QmlOpenMetaObjectType(QmlEngine *engine); + QmlOpenMetaObjectType(const QMetaObject *base, QmlEngine *engine); ~QmlOpenMetaObjectType(); + int createProperty(const QByteArray &name); + +protected: + virtual void propertyCreated(int, QMetaPropertyBuilder &); + private: QmlOpenMetaObjectTypePrivate *d; friend class QmlOpenMetaObject; @@ -68,7 +75,6 @@ private: }; class QmlOpenMetaObjectPrivate; -class QMetaPropertyBuilder; class Q_DECLARATIVE_EXPORT QmlOpenMetaObject : public QAbstractDynamicMetaObject { public: @@ -87,6 +93,13 @@ public: QObject *object() const; virtual QVariant initialValue(int); + + // Be careful - once setCached(true) is called createProperty() is no + // longer automatically called for new properties. + void setCached(bool); + + QmlOpenMetaObjectType *type() const; + protected: virtual int metaCall(QMetaObject::Call _c, int _id, void **_a); virtual int createProperty(const char *, const char *); @@ -96,9 +109,8 @@ protected: virtual void propertyCreated(int, QMetaPropertyBuilder &); private: - int doCreateProperty(const char *); - QmlOpenMetaObjectPrivate *d; + friend class QmlOpenMetaObjectType; }; QT_END_NAMESPACE |