aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorAnton Kreuzkamp <anton.kreuzkamp@kdab.com>2017-04-26 16:31:48 +0200
committerAnton Kreuzkamp <anton.kreuzkamp@kdab.com>2017-08-13 04:07:30 +0000
commit17513266b81e88b84fda250734f07c94a198fabc (patch)
tree2bb498ba41df15971035fb040bf4c07e8369fbc3 /src/qml/qml
parent041c8d28eaa0e516a0c6502fa801781aa8ebe5a6 (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.cpp32
-rw-r--r--src/qml/qml/qqmlbinding_p.h9
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h14
-rw-r--r--src/qml/qml/qqmlnotifier_p.h5
-rw-r--r--src/qml/qml/qqmlvaluetypeproxybinding.cpp5
-rw-r--r--src/qml/qml/qqmlvaluetypeproxybinding_p.h1
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);