summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qmlmetaproperty.cpp
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2010-02-22 04:56:49 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2010-02-22 05:53:27 (GMT)
commit33eb76f050b45718d87926a8ff7afc89d6201c16 (patch)
tree935ddc2337b3891aab1ad7edcb06a62aabf14668 /src/declarative/qml/qmlmetaproperty.cpp
parent5f63321e3fe2b436d469d2722dc464ea4c7830c4 (diff)
downloadQt-33eb76f050b45718d87926a8ff7afc89d6201c16.zip
Qt-33eb76f050b45718d87926a8ff7afc89d6201c16.tar.gz
Qt-33eb76f050b45718d87926a8ff7afc89d6201c16.tar.bz2
Replace QmlList* and QList* support with a single QmlListProperty type
As a value type QmlListProperty doesn't consume any memory in the object. It also has a companion QmlListReference class that is part of the public API for C++ developers to interact with that also manages memory issues that existed with previous solutions (if the containing QObject was destroyed it left a dangling pointer).
Diffstat (limited to 'src/declarative/qml/qmlmetaproperty.cpp')
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp92
1 files changed, 38 insertions, 54 deletions
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index d7d4a07..7c273dc 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -52,16 +52,13 @@
#include "qmlengine_p.h"
#include "qmldeclarativedata_p.h"
#include "qmlstringconverters_p.h"
-
-#include <qfxperf_p_p.h>
+#include "qmllist_p.h"
#include <QStringList>
#include <QtCore/qdebug.h>
#include <math.h>
-Q_DECLARE_METATYPE(QList<QObject *>);
-
QT_BEGIN_NAMESPACE
/*!
@@ -213,7 +210,6 @@ QmlMetaProperty::QmlMetaProperty(const QmlMetaProperty &other)
\value InvalidProperty The property is invalid.
\value Bindable The property is a QmlBinding.
\value List The property is a QList pointer
- \value QmlList The property is a QmlList pointer
\value Object The property is a QObject derived type pointer
\value Normal The property is none of the above.
*/
@@ -257,8 +253,6 @@ QmlMetaPropertyPrivate::propertyCategory() const
return QmlMetaProperty::Bindable;
else if (core.flags & QmlPropertyCache::Data::IsQObjectDerived)
return QmlMetaProperty::Object;
- else if (core.flags & QmlPropertyCache::Data::IsQmlList)
- return QmlMetaProperty::QmlList;
else if (core.flags & QmlPropertyCache::Data::IsQList)
return QmlMetaProperty::List;
else
@@ -401,7 +395,7 @@ bool QmlMetaProperty::isWritable() const
if (!d->object)
return false;
- if (category == List || category == QmlList)
+ if (category == List)
return true;
else if (type() & SignalProperty)
return false;
@@ -703,6 +697,13 @@ QVariant QmlMetaPropertyPrivate::readValueProperty()
if (!ep) delete valueType;
return rv;
+ } else if(core.flags & QmlPropertyCache::Data::IsQList) {
+
+ QmlListProperty<QObject> prop;
+ void *args[] = { &prop, 0 };
+ QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args);
+ return QVariant::fromValue(QmlListReferencePrivate::init(prop, core.propType, context?context->engine():0));
+
} else {
return object->metaObject()->property(core.coreIndex).read(object.data());
@@ -813,9 +814,7 @@ bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
int t = property.propType;
int vt = value.userType();
- QmlEnginePrivate *enginePriv = 0;
- if (context && context->engine())
- enginePriv = QmlEnginePrivate::get(context->engine());
+ QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(context);
if (t == QVariant::Url) {
@@ -880,55 +879,40 @@ bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
} else if (property.flags & QmlPropertyCache::Data::IsQList) {
- int listType = QmlMetaType::listType(t);
- QMetaProperty prop = object->metaObject()->property(property.coreIndex);
-
- if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
- const QList<QObject *> &list =
- qvariant_cast<QList<QObject *> >(value);
- QVariant listVar = prop.read(object);
- QmlMetaType::clear(listVar);
- for (int ii = 0; ii < list.count(); ++ii) {
- QVariant v = QmlMetaType::qmlType(listType)->fromObject(list.at(ii));
- QmlMetaType::append(listVar, v);
- }
-
- } else if (vt == listType ||
- value.userType() == listType) {
- QVariant listVar = prop.read(object);
- QmlMetaType::append(listVar, value);
+ const QMetaObject *listType = 0;
+ if (enginePriv) {
+ listType = enginePriv->rawMetaObjectForType(enginePriv->listType(property.propType));
+ } else {
+ QmlType *type = QmlMetaType::qmlType(QmlMetaType::listType(property.propType));
+ if (!type) return false;
+ listType = type->baseMetaObject();
}
+ if (!listType) return false;
- } else if (property.flags & QmlPropertyCache::Data::IsQmlList) {
+ QmlListProperty<void> prop;
+ void *args[] = { &prop, 0 };
+ QMetaObject::metacall(object, QMetaObject::ReadProperty, coreIdx, args);
- // XXX - optimize!
- QMetaProperty prop = object->metaObject()->property(property.coreIndex);
- QVariant list = prop.read(object);
- QmlPrivate::ListInterface *li =
- *(QmlPrivate::ListInterface **)list.constData();
-
- int type = li->type();
-
- if (QObject *obj = QmlMetaType::toQObject(value)) {
- const QMetaObject *mo = rawMetaObjectForType(enginePriv, type);
-
- const QMetaObject *objMo = obj->metaObject();
- bool found = false;
- while(!found && objMo) {
- if (equal(objMo, mo))
- found = true;
- else
- objMo = objMo->superClass();
- }
+ if (!prop.clear) return false;
- if (!found)
- return false;
+ prop.clear(&prop);
+
+ if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
+ const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value);
- // NOTE: This assumes a cast to QObject does not alter
- // the object pointer
- void *d = (void *)&obj;
- li->append(d);
+ for (int ii = 0; ii < list.count(); ++ii) {
+ QObject *o = list.at(ii);
+ if (!canConvert(o->metaObject(), listType))
+ o = 0;
+ prop.append(&prop, (void *)o);
+ }
+ } else {
+ QObject *o = enginePriv?enginePriv->toQObject(value):QmlMetaType::toQObject(value);
+ if (!canConvert(o->metaObject(), listType))
+ o = 0;
+ prop.append(&prop, (void *)o);
}
+
} else {
Q_ASSERT(vt != t);