diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-02-22 04:56:49 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-02-22 05:53:27 (GMT) |
commit | 33eb76f050b45718d87926a8ff7afc89d6201c16 (patch) | |
tree | 935ddc2337b3891aab1ad7edcb06a62aabf14668 /src/declarative/qml/qmlmetaproperty.cpp | |
parent | 5f63321e3fe2b436d469d2722dc464ea4c7830c4 (diff) | |
download | Qt-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.cpp | 92 |
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); |