summaryrefslogtreecommitdiffstats
path: root/src/declarative/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/util')
-rw-r--r--src/declarative/util/qmlopenmetaobject.cpp115
-rw-r--r--src/declarative/util/qmlopenmetaobject_p.h22
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