aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4referenceobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4referenceobject_p.h22
2 files changed, 17 insertions, 9 deletions
diff --git a/src/qml/jsruntime/qv4referenceobject.cpp b/src/qml/jsruntime/qv4referenceobject.cpp
index c054976868..fcad9b92dc 100644
--- a/src/qml/jsruntime/qv4referenceobject.cpp
+++ b/src/qml/jsruntime/qv4referenceobject.cpp
@@ -293,6 +293,10 @@ DEFINE_OBJECT_VTABLE(QV4::ReferenceObject);
A ReferenceObject can take advantage of this to reduce the number of reads
that are required when dealing with a \c{QObject}'s property provening data.
+ When a property has a \tt{NOTIFY} signal and is a \tt{BINDABLE} at
+ the same time, we only need to use one such connection.
+ Currently, the \tt{BINDABLE} subscription will take predecedence.
+
ReferenceObjects that are part of a \l{Reference object chains}{chain}, will
traverse the chain up until a QOjbect holding root is found, and connect based
on that object.
diff --git a/src/qml/jsruntime/qv4referenceobject_p.h b/src/qml/jsruntime/qv4referenceobject_p.h
index 34bedb690f..35690a7228 100644
--- a/src/qml/jsruntime/qv4referenceobject_p.h
+++ b/src/qml/jsruntime/qv4referenceobject_p.h
@@ -56,6 +56,9 @@ DECLARE_HEAP_OBJECT(ReferenceObject, Object) {
Q_ASSERT(obj);
Q_ASSERT(engine);
+ Q_ASSERT(!referenceEndpoint);
+ Q_ASSERT(!bindableNotifier);
+
referenceEndpoint = new ReferenceObjectEndpoint(this);
referenceEndpoint->connect(
obj,
@@ -106,6 +109,9 @@ DECLARE_HEAP_OBJECT(ReferenceObject, Object) {
Q_ASSERT(obj);
Q_ASSERT(engine);
+ Q_ASSERT(!referenceEndpoint);
+ Q_ASSERT(!bindableNotifier);
+
bindableNotifier = new QPropertyNotifier(obj->metaObject()->property(property).bindable(obj).addNotifier([this](){ setDirty(true); }));
new(onDelete) QMetaObject::Connection(QObject::connect(obj, &QObject::destroyed, [this](){ setDirty(true); }));
};
@@ -135,11 +141,10 @@ DECLARE_HEAP_OBJECT(ReferenceObject, Object) {
auto wrapper = static_cast<QV4::Heap::QObjectWrapper*>(object);
QObject* obj = wrapper->object();
- if (obj->metaObject()->property(property).hasNotifySignal() && internalClass->engine->qmlEngine())
- connectToNotifySignal(obj, property, internalClass->engine->qmlEngine());
-
if (obj->metaObject()->property(property).isBindable() && internalClass->engine->qmlEngine())
connectToBindable(obj, property, internalClass->engine->qmlEngine());
+ else if (obj->metaObject()->property(property).hasNotifySignal() && internalClass->engine->qmlEngine())
+ connectToNotifySignal(obj, property, internalClass->engine->qmlEngine());
}
if (object && object->internalClass->vtable->type == Managed::Type_QMLTypeWrapper) {
@@ -149,11 +154,10 @@ DECLARE_HEAP_OBJECT(ReferenceObject, Object) {
Scoped<QV4::QQmlTypeWrapper> scopedWrapper(scope, wrapper);
QObject* obj = scopedWrapper->object();
- if (obj->metaObject()->property(property).hasNotifySignal() && internalClass->engine->qmlEngine())
- connectToNotifySignal(obj, property, internalClass->engine->qmlEngine());
-
if (obj->metaObject()->property(property).isBindable() && internalClass->engine->qmlEngine())
connectToBindable(obj, property, internalClass->engine->qmlEngine());
+ else if (obj->metaObject()->property(property).hasNotifySignal() && internalClass->engine->qmlEngine())
+ connectToNotifySignal(obj, property, internalClass->engine->qmlEngine());
}
// If we could not connect to anything we don't have a way to
@@ -208,9 +212,9 @@ DECLARE_HEAP_OBJECT(ReferenceObject, Object) {
}
void destroy() {
- // If we are connected we must have connected to the destroyed
- // signal too, and we should clean it up.
- if (isConnected()) {
+ // If we allocated any connection then we must have connected
+ // to the destroyed signal too, and we should clean it up.
+ if (referenceEndpoint || bindableNotifier) {
QObject::disconnect(*reinterpret_cast<QMetaObject::Connection*>(&onDelete));
std::destroy_at(reinterpret_cast<QMetaObject::Connection*>(&onDelete));
}