Simplify property capturing code
authorLars Knoll <lars.knoll@theqtcompany.com>
Wed, 10 Jun 2015 11:32:20 +0000 (13:32 +0200)
committerSimon Hausmann <simon.hausmann@theqtcompany.com>
Thu, 18 Jun 2015 14:41:13 +0000 (14:41 +0000)
No need to inherit from a base class defined in QQmlEnginePrivate.
The capture handling can be a simple value based class without
virtual methods that is allocated on the stack.

Change-Id: Ib0ddf4afcaf154b3f953d8c9322f5bec196d7abf
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
src/qml/jsruntime/qv4qobjectwrapper.cpp
src/qml/qml/qqmlcontextwrapper.cpp
src/qml/qml/qqmlengine_p.h
src/qml/qml/qqmljavascriptexpression.cpp
src/qml/qml/qqmljavascriptexpression_p.h

index 878bebbc726c3df528aeb6329ad7dd9c3392ae42..c803bf4efa6b58d9828498a3c7ada3b4a0773e80 100644 (file)
@@ -370,18 +370,19 @@ ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx
 
         if (captureRequired) {
             if (property->accessors->notifier) {
-                if (n)
-                    ep->captureProperty(n);
+                if (n && ep->propertyCapture)
+                    ep->propertyCapture->captureProperty(n);
             } else {
-                ep->captureProperty(object, property->coreIndex, property->notifyIndex);
+                if (ep->propertyCapture)
+                    ep->propertyCapture->captureProperty(object, property->coreIndex, property->notifyIndex);
             }
         }
 
         return rv->asReturnedValue();
     }
 
-    if (captureRequired && ep && !property->isConstant())
-        ep->captureProperty(object, property->coreIndex, property->notifyIndex);
+    if (captureRequired && ep && ep->propertyCapture && !property->isConstant())
+        ep->propertyCapture->captureProperty(object, property->coreIndex, property->notifyIndex);
 
     if (property->isVarProperty()) {
         QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object);
index 6fbfc844c8645b4129fcadcd7cda544348a65f3a..15bf790d4f90f184c1b7d441e4585f293841a4f8 100644 (file)
@@ -45,6 +45,7 @@
 #include <private/qv4compileddata_p.h>
 #include <private/qqmltypewrapper_p.h>
 #include <private/qqmllistwrapper_p.h>
+#include <private/qqmljavascriptexpression_p.h>
 #include <private/qjsvalue_p.h>
 
 QT_BEGIN_NAMESPACE
@@ -209,7 +210,8 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
 
                 if (propertyIdx < context->idValueCount) {
 
-                    ep->captureProperty(&context->idValues[propertyIdx].bindings);
+                    if (ep->propertyCapture)
+                        ep->propertyCapture->captureProperty(&context->idValues[propertyIdx].bindings);
                     if (hasProperty)
                         *hasProperty = true;
                     return QV4::QObjectWrapper::wrap(v4, context->idValues[propertyIdx]);
@@ -217,8 +219,8 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
 
                     QQmlContextPrivate *cp = context->asQQmlContextPrivate();
 
-                    ep->captureProperty(context->asQQmlContext(), -1,
-                                        propertyIdx + cp->notifyIndex);
+                    if (ep->propertyCapture)
+                        ep->propertyCapture->captureProperty(context->asQQmlContext(), -1, propertyIdx + cp->notifyIndex);
 
                     const QVariant &value = cp->propertyValues.at(propertyIdx);
                     if (hasProperty)
@@ -357,7 +359,7 @@ void QmlContextWrapper::registerQmlDependencies(ExecutionEngine *engine, const C
     QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0;
     if (!ep)
         return;
-    QQmlEnginePrivate::PropertyCapture *capture = ep->propertyCapture;
+    QQmlPropertyCapture *capture = ep->propertyCapture;
     if (!capture)
         return;
 
@@ -451,8 +453,8 @@ ReturnedValue QQmlIdObjectsArray::getIndexed(const Managed *m, uint index, bool
         *hasProperty = true;
 
     QQmlEnginePrivate *ep = scope.engine->qmlEngine() ? QQmlEnginePrivate::get(scope.engine->qmlEngine()) : 0;
-    if (ep)
-        ep->captureProperty(&context->idValues[index].bindings);
+    if (ep && ep->propertyCapture)
+        ep->propertyCapture->captureProperty(&context->idValues[index].bindings);
 
     return QObjectWrapper::wrap(This->engine(), context->idValues[index].data());
 }
index 1021c30f4a815457a280d5a56c45c33419ef080d..1a317f6fbd9c5060e99ec73e8a4297ba8b117c8a 100644 (file)
@@ -94,6 +94,7 @@ class QQmlObjectCreator;
 class QDir;
 class QQmlIncubator;
 class QQmlProfiler;
+class QQmlPropertyCapture;
 
 // This needs to be declared here so that the pool for it can live in QQmlEnginePrivate.
 // The inline method definitions are in qqmljavascriptexpression_p.h
@@ -122,16 +123,7 @@ public:
     // is just qmlClearTypeRegistrations (which can't be called while an engine exists)
     static bool baseModulesUninitialized;
 
-    class PropertyCapture {
-    public:
-        inline virtual ~PropertyCapture() {}
-        virtual void captureProperty(QQmlNotifier *) = 0;
-        virtual void captureProperty(QObject *, int, int) = 0;
-    };
-
-    PropertyCapture *propertyCapture;
-    inline void captureProperty(QQmlNotifier *);
-    inline void captureProperty(QObject *, int, int);
+    QQmlPropertyCapture *propertyCapture;
 
     QRecyclePool<QQmlJavaScriptExpressionGuard> jsExpressionGuardPool;
 
@@ -413,18 +405,6 @@ QQmlEnginePrivate *QQmlEnginePrivate::get(QV4::ExecutionEngine *e)
     return get(qmlEngine);
 }
 
-void QQmlEnginePrivate::captureProperty(QQmlNotifier *n)
-{
-    if (propertyCapture)
-        propertyCapture->captureProperty(n);
-}
-
-void QQmlEnginePrivate::captureProperty(QObject *o, int c, int n)
-{
-    if (propertyCapture)
-        propertyCapture->captureProperty(o, c, n);
-}
-
 void QQmlEnginePrivate::setDebugChangesCache(const QHash<QUrl, QByteArray> &changes)
 {
     Locker locker(this);
index 60378a26e70cc4efa795e345412506b3209aa0a4..a45ba680e5f31eeb33da0202a2b01e7bcae226e3 100644 (file)
@@ -167,9 +167,9 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b
     DeleteWatcher watcher(this);
 
     Q_ASSERT(notifyOnValueChanged() || activeGuards.isEmpty());
-    GuardCapture capture(m_context->engine, this, &watcher);
+    QQmlPropertyCapture capture(m_context->engine, this, &watcher);
 
-    QQmlEnginePrivate::PropertyCapture *lastPropertyCapture = ep->propertyCapture;
+    QQmlPropertyCapture *lastPropertyCapture = ep->propertyCapture;
     ep->propertyCapture = notifyOnValueChanged() ? &capture : 0;
 
 
@@ -209,7 +209,7 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b
         capture.errorString = 0;
     }
 
-    while (Guard *g = capture.guards.takeFirst())
+    while (QQmlJavaScriptExpressionGuard *g = capture.guards.takeFirst())
         g->Delete();
 
     ep->propertyCapture = lastPropertyCapture;
@@ -217,7 +217,7 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b
     return result->asReturnedValue();
 }
 
-void QQmlJavaScriptExpression::GuardCapture::captureProperty(QQmlNotifier *n)
+void QQmlPropertyCapture::captureProperty(QQmlNotifier *n)
 {
     if (watcher->wasDeleted())
         return;
@@ -227,13 +227,13 @@ void QQmlJavaScriptExpression::GuardCapture::captureProperty(QQmlNotifier *n)
     while (!guards.isEmpty() && !guards.first()->isConnected(n))
         guards.takeFirst()->Delete();
 
-    Guard *g = 0;
+    QQmlJavaScriptExpressionGuard *g = 0;
     if (!guards.isEmpty()) {
         g = guards.takeFirst();
         g->cancelNotify();
         Q_ASSERT(g->isConnected(n));
     } else {
-        g = Guard::New(expression, engine);
+        g = QQmlJavaScriptExpressionGuard::New(expression, engine);
         g->connect(n);
     }
 
@@ -244,7 +244,7 @@ void QQmlJavaScriptExpression::GuardCapture::captureProperty(QQmlNotifier *n)
 
     \a n is in the signal index range (see QObjectPrivate::signalIndex()).
 */
-void QQmlJavaScriptExpression::GuardCapture::captureProperty(QObject *o, int c, int n)
+void QQmlPropertyCapture::captureProperty(QObject *o, int c, int n)
 {
     if (watcher->wasDeleted())
         return;
@@ -273,13 +273,13 @@ void QQmlJavaScriptExpression::GuardCapture::captureProperty(QObject *o, int c,
         while (!guards.isEmpty() && !guards.first()->isConnected(o, n))
             guards.takeFirst()->Delete();
 
-        Guard *g = 0;
+        QQmlJavaScriptExpressionGuard *g = 0;
         if (!guards.isEmpty()) {
             g = guards.takeFirst();
             g->cancelNotify();
             Q_ASSERT(g->isConnected(o, n));
         } else {
-            g = Guard::New(expression, engine);
+            g = QQmlJavaScriptExpressionGuard::New(expression, engine);
             g->connect(o, n, engine);
         }
 
@@ -375,7 +375,7 @@ QV4::ReturnedValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, Q
 
 void QQmlJavaScriptExpression::clearGuards()
 {
-    while (Guard *g = activeGuards.takeFirst())
+    while (QQmlJavaScriptExpressionGuard *g = activeGuards.takeFirst())
         g->Delete();
 }
 
index ce490ee1709c7b3b4525313528c32998c035d90b..24e9878aa21f558e4371c6870183aed5267a1259 100644 (file)
@@ -145,35 +145,16 @@ public:
 
 private:
     friend class QQmlContextData;
-    typedef QQmlJavaScriptExpressionGuard Guard;
+    friend class QQmlPropertyCapture;
     friend void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *, void **);
 
-    struct GuardCapture : public QQmlEnginePrivate::PropertyCapture {
-        GuardCapture(QQmlEngine *engine, QQmlJavaScriptExpression *e, DeleteWatcher *w)
-        : engine(engine), expression(e), watcher(w), errorString(0) { }
-
-        ~GuardCapture()  {
-            Q_ASSERT(guards.isEmpty());
-            Q_ASSERT(errorString == 0);
-        }
-
-        virtual void captureProperty(QQmlNotifier *);
-        virtual void captureProperty(QObject *, int, int);
-
-        QQmlEngine *engine;
-        QQmlJavaScriptExpression *expression;
-        DeleteWatcher *watcher;
-        QFieldList<Guard, &Guard::next> guards;
-        QStringList *errorString;
-    };
-
     QQmlDelayedError *m_error;
 
     // We store some flag bits in the following flag pointers.
     //    activeGuards:flag1  - notifyOnValueChanged
     //    activeGuards:flag2  - useSharedContext
     QBiPointer<QObject, DeleteWatcher> m_scopeObject;
-    QForwardFieldList<Guard, &Guard::next> activeGuards;
+    QForwardFieldList<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next> activeGuards;
 
     QQmlContextData *m_context;
     QQmlJavaScriptExpression **m_prevExpression;
@@ -183,6 +164,27 @@ protected:
     QV4::PersistentValue m_function;
 };
 
+class QQmlPropertyCapture
+{
+public:
+    QQmlPropertyCapture(QQmlEngine *engine, QQmlJavaScriptExpression *e, QQmlJavaScriptExpression::DeleteWatcher *w)
+    : engine(engine), expression(e), watcher(w), errorString(0) { }
+
+    ~QQmlPropertyCapture()  {
+        Q_ASSERT(guards.isEmpty());
+        Q_ASSERT(errorString == 0);
+    }
+
+    void captureProperty(QQmlNotifier *);
+    void captureProperty(QObject *, int, int);
+
+    QQmlEngine *engine;
+    QQmlJavaScriptExpression *expression;
+    QQmlJavaScriptExpression::DeleteWatcher *watcher;
+    QFieldList<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next> guards;
+    QStringList *errorString;
+};
+
 QQmlJavaScriptExpression::DeleteWatcher::DeleteWatcher(QQmlJavaScriptExpression *e)
 : _c(0), _w(0), _s(e)
 {