From 9e0b57b9a94c82d747e36260115050d912d6f576 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 14 May 2012 11:12:00 +0100 Subject: [PATCH] More efficient property interceptor implementation The initial implementation vastly overestimated the number of interceptors that would exist. Change-Id: Ieddc55306e5976a9373a2b468013936240228992 Reviewed-by: Michael Brasser --- src/qml/qml/qqmlpropertyvalueinterceptor_p.h | 7 +++++++ src/qml/qml/qqmlvmemetaobject.cpp | 26 +++++++++++++------------- src/qml/qml/qqmlvmemetaobject_p.h | 4 ++-- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/qml/qml/qqmlpropertyvalueinterceptor_p.h b/src/qml/qml/qqmlpropertyvalueinterceptor_p.h index cf449c9..6cd94b3 100644 --- a/src/qml/qml/qqmlpropertyvalueinterceptor_p.h +++ b/src/qml/qml/qqmlpropertyvalueinterceptor_p.h @@ -66,6 +66,13 @@ public: virtual ~QQmlPropertyValueInterceptor(); virtual void setTarget(const QQmlProperty &property) = 0; virtual void write(const QVariant &value) = 0; + +private: + friend class QQmlVMEMetaObject; + + int m_coreIndex; + int m_valueTypeCoreIndex; + QQmlPropertyValueInterceptor *m_next; }; #define QQmlPropertyValueInterceptor_iid "org.qt-project.Qt.QQmlPropertyValueInterceptor" diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 001ed79..01a4737 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -487,7 +487,7 @@ QQmlVMEMetaObject::QQmlVMEMetaObject(QObject *obj, : QV8GCCallback::Node(GcPrologueCallback), object(obj), compiledData(cdata), ctxt(QQmlData::get(obj, true)->outerContext), metaData(meta), data(0), aliasEndpoints(0), firstVarPropertyIndex(-1), varPropertiesInitialized(false), - v8methods(0), parent(0) + interceptors(0), v8methods(0), parent(0) { compiledData->addref(); @@ -540,14 +540,14 @@ QQmlVMEMetaObject::~QQmlVMEMetaObject() int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) { int id = _id; - if(c == QMetaObject::WriteProperty) { - int flags = *reinterpret_cast(a[3]); - if (!(flags & QQmlPropertyPrivate::BypassInterceptor) - && !aInterceptors.isEmpty() - && aInterceptors.testBit(id)) { - QPair pair = interceptors.value(id); - int valueIndex = pair.first; - QQmlPropertyValueInterceptor *vi = pair.second; + if (c == QMetaObject::WriteProperty && interceptors && + !(*reinterpret_cast(a[3]) & QQmlPropertyPrivate::BypassInterceptor)) { + + for (QQmlPropertyValueInterceptor *vi = interceptors; vi; vi = vi->m_next) { + if (vi->m_coreIndex != id) + continue; + + int valueIndex = vi->m_valueTypeCoreIndex; int type = property(id).userType(); if (type != QVariant::Invalid) { @@ -1000,10 +1000,10 @@ void QQmlVMEMetaObject::list_clear(QQmlListProperty *prop) void QQmlVMEMetaObject::registerInterceptor(int index, int valueIndex, QQmlPropertyValueInterceptor *interceptor) { - if (aInterceptors.isEmpty()) - aInterceptors.resize(propertyCount() + metaData->propertyCount); - aInterceptors.setBit(index); - interceptors.insert(index, qMakePair(valueIndex, interceptor)); + interceptor->m_coreIndex = index; + interceptor->m_valueTypeCoreIndex = valueIndex; + interceptor->m_next = interceptors; + interceptors = interceptor; } int QQmlVMEMetaObject::vmeMethodLineNumber(int index) diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h index 5bd472a..53fe34d 100644 --- a/src/qml/qml/qqmlvmemetaobject_p.h +++ b/src/qml/qml/qqmlvmemetaobject_p.h @@ -198,8 +198,8 @@ private: void connectAlias(int aliasId); QBitArray aConnected; - QBitArray aInterceptors; - QHash > interceptors; + + QQmlPropertyValueInterceptor *interceptors; v8::Persistent *v8methods; v8::Handle method(int); -- 2.7.4