More efficient property interceptor implementation
authorAaron Kennedy <aaron.kennedy@nokia.com>
Mon, 14 May 2012 10:12:00 +0000 (11:12 +0100)
committerQt by Nokia <qt-info@nokia.com>
Tue, 15 May 2012 15:33:43 +0000 (17:33 +0200)
The initial implementation vastly overestimated the number of interceptors
that would exist.

Change-Id: Ieddc55306e5976a9373a2b468013936240228992
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
src/qml/qml/qqmlpropertyvalueinterceptor_p.h
src/qml/qml/qqmlvmemetaobject.cpp
src/qml/qml/qqmlvmemetaobject_p.h

index cf449c9..6cd94b3 100644 (file)
@@ -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"
index 001ed79..01a4737 100644 (file)
@@ -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<int*>(a[3]);
-        if (!(flags & QQmlPropertyPrivate::BypassInterceptor)
-            && !aInterceptors.isEmpty()
-            && aInterceptors.testBit(id)) {
-            QPair<int, QQmlPropertyValueInterceptor*> pair = interceptors.value(id);
-            int valueIndex = pair.first;
-            QQmlPropertyValueInterceptor *vi = pair.second;
+    if (c == QMetaObject::WriteProperty && interceptors &&
+       !(*reinterpret_cast<int*>(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<QObject> *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)
index 5bd472a..53fe34d 100644 (file)
@@ -198,8 +198,8 @@ private:
 
     void connectAlias(int aliasId);
     QBitArray aConnected;
-    QBitArray aInterceptors;
-    QHash<int, QPair<int, QQmlPropertyValueInterceptor*> > interceptors;
+
+    QQmlPropertyValueInterceptor *interceptors;
 
     v8::Persistent<v8::Function> *v8methods;
     v8::Handle<v8::Function> method(int);