diff options
author | Anton Kreuzkamp <anton.kreuzkamp@kdab.com> | 2017-04-26 16:31:48 +0200 |
---|---|---|
committer | Anton Kreuzkamp <anton.kreuzkamp@kdab.com> | 2017-08-13 04:07:30 +0000 |
commit | 17513266b81e88b84fda250734f07c94a198fabc (patch) | |
tree | 2bb498ba41df15971035fb040bf4c07e8369fbc3 /src/qml/qml | |
parent | 041c8d28eaa0e516a0c6502fa801781aa8ebe5a6 (diff) |
Add API to learn about QQmlBinding's dependencies
Adds a method `dependencies()` to QQmlBinding, that returns a
QVector<QQmlProperty> of all properties the binding depends on. The API is
meant to be used in debugging tools (e.g. in GammaRay).
Also adds a public method subBindings() to QQmlValueTypeProxyBinding in
order to be able to access their dependencies.
Change-Id: Ib833703ec9e632661626c4532b8d73997f38e62b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 32 | ||||
-rw-r--r-- | src/qml/qml/qqmlbinding_p.h | 9 | ||||
-rw-r--r-- | src/qml/qml/qqmljavascriptexpression_p.h | 14 | ||||
-rw-r--r-- | src/qml/qml/qqmlnotifier_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypeproxybinding.cpp | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypeproxybinding_p.h | 1 |
6 files changed, 57 insertions, 9 deletions
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 84f30af066..566fbb86ac 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -54,6 +54,7 @@ #include <QVariant> #include <QtCore/qdebug.h> +#include <QVector> QT_BEGIN_NAMESPACE @@ -579,6 +580,37 @@ void QQmlBinding::getPropertyData(QQmlPropertyData **propertyData, QQmlPropertyD } } +QVector<QQmlProperty> QQmlBinding::dependencies() const +{ + QVector<QQmlProperty> dependencies; + if (!m_target.data()) + return dependencies; + + for (const auto &guardList : { permanentGuards, activeGuards }) { + for (QQmlJavaScriptExpressionGuard *guard = guardList.first(); guard; guard = guardList.next(guard)) { + if (guard->signalIndex() == -1) // guard's sender is a QQmlNotifier, not a QObject*. + continue; + + QObject *senderObject = guard->senderAsObject(); + if (!senderObject) + continue; + + const QMetaObject *senderMeta = senderObject->metaObject(); + if (!senderMeta) + continue; + + for (int i = 0; i < senderMeta->propertyCount(); i++) { + QMetaProperty property = senderMeta->property(i); + if (property.notifySignalIndex() == QMetaObjectPrivate::signal(senderMeta, guard->signalIndex()).methodIndex()) { + dependencies.push_back(QQmlProperty(senderObject, QString::fromUtf8(senderObject->metaObject()->property(i).name()))); + } + } + } + } + + return dependencies; +} + class QObjectPointerBinding: public QQmlNonbindingBinding { QQmlMetaObject targetMetaObject; diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index 1c894148e4..38d59a8919 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -102,6 +102,15 @@ public: QString expressionIdentifier() const override; void expressionChanged() override; + /** + * This method returns a snapshot of the currently tracked dependencies of + * this binding. The dependencies can change upon reevaluation. This method is + * used in GammaRay to visualize binding hierarchies. + * + * Call this method from the UI thread. + */ + QVector<QQmlProperty> dependencies() const; + protected: virtual void doUpdate(const DeleteWatcher &watcher, QQmlPropertyData::WriteFlags flags, QV4::Scope &scope) = 0; diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index 8b4b64f4d2..e9a9f4feee 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -162,6 +162,13 @@ protected: void setupFunction(QV4::ExecutionContext *qmlContext, QV4::Function *f); void setCompilationUnit(QV4::CompiledData::CompilationUnit *compilationUnit); + // We store some flag bits in the following flag pointers. + // activeGuards:flag1 - notifyOnValueChanged + // activeGuards:flag2 - useSharedContext + QBiPointer<QObject, DeleteWatcher> m_scopeObject; + QForwardFieldList<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next> activeGuards; + QForwardFieldList<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next> permanentGuards; + private: friend class QQmlContextData; friend class QQmlPropertyCapture; @@ -170,13 +177,6 @@ private: 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<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next> activeGuards; - QForwardFieldList<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next> permanentGuards; - QQmlContextData *m_context; QQmlJavaScriptExpression **m_prevExpression; QQmlJavaScriptExpression *m_nextExpression; diff --git a/src/qml/qml/qqmlnotifier_p.h b/src/qml/qml/qqmlnotifier_p.h index 6e91369793..a99b13f155 100644 --- a/src/qml/qml/qqmlnotifier_p.h +++ b/src/qml/qml/qqmlnotifier_p.h @@ -109,6 +109,9 @@ public: inline int signalIndex() const { return sourceSignal; } + inline QObject *senderAsObject() const; + inline QQmlNotifier *senderAsNotifier() const; + private: friend class QQmlData; friend class QQmlNotifier; @@ -117,8 +120,6 @@ private: // endpoint is connected to. While the endpoint is notifying, the // senderPtr points to another qintptr that contains this value. qintptr senderPtr; - inline QObject *senderAsObject() const; - inline QQmlNotifier *senderAsNotifier() const; Callback callback:4; int needsConnectNotify:1; diff --git a/src/qml/qml/qqmlvaluetypeproxybinding.cpp b/src/qml/qml/qqmlvaluetypeproxybinding.cpp index 4e2e7b06c7..7a3e4b2df4 100644 --- a/src/qml/qml/qqmlvaluetypeproxybinding.cpp +++ b/src/qml/qml/qqmlvaluetypeproxybinding.cpp @@ -72,6 +72,11 @@ bool QQmlValueTypeProxyBinding::isValueTypeProxy() const return true; } +QQmlAbstractBinding *QQmlValueTypeProxyBinding::subBindings() const +{ + return m_bindings.data(); +} + QQmlAbstractBinding *QQmlValueTypeProxyBinding::binding(QQmlPropertyIndex propertyIndex) const { QQmlAbstractBinding *binding = m_bindings.data(); diff --git a/src/qml/qml/qqmlvaluetypeproxybinding_p.h b/src/qml/qml/qqmlvaluetypeproxybinding_p.h index 92b5470f39..ba0d305bd9 100644 --- a/src/qml/qml/qqmlvaluetypeproxybinding_p.h +++ b/src/qml/qml/qqmlvaluetypeproxybinding_p.h @@ -60,6 +60,7 @@ class QQmlValueTypeProxyBinding : public QQmlAbstractBinding public: QQmlValueTypeProxyBinding(QObject *o, QQmlPropertyIndex coreIndex); + QQmlAbstractBinding *subBindings() const; QQmlAbstractBinding *binding(QQmlPropertyIndex targetPropertyIndex) const; void removeBindings(quint32 mask); |