aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4referenceobject.cpp64
-rw-r--r--src/qml/jsruntime/qv4referenceobject_p.h67
2 files changed, 67 insertions, 64 deletions
diff --git a/src/qml/jsruntime/qv4referenceobject.cpp b/src/qml/jsruntime/qv4referenceobject.cpp
index 7493ed5714..336b715ca0 100644
--- a/src/qml/jsruntime/qv4referenceobject.cpp
+++ b/src/qml/jsruntime/qv4referenceobject.cpp
@@ -488,4 +488,68 @@ void QQmlDirtyReferenceObject_callback(QQmlNotifierEndpoint *e, void **) {
static_cast<QV4::Heap::ReferenceObjectEndpoint*>(e)->reference->setDirty(true);
}
+namespace QV4 {
+
+void Heap::ReferenceObject::connectToNotifySignal(QObject *obj, int property, QQmlEngine *engine)
+{
+ Q_ASSERT(obj);
+ Q_ASSERT(engine);
+
+ Q_ASSERT(!referenceEndpoint);
+ Q_ASSERT(!bindableNotifier);
+
+ referenceEndpoint = new ReferenceObjectEndpoint(this);
+
+ // Connect and signal emission work on "signal indexes". Those are different from "method
+ // indexes".
+ // The public MetaObject interface can, generally, give us the "method index" of the notify
+ // signal.
+ // Quite unintuitively, this is true for "notifySignalIndex". As the "method index" and the
+ // "signal index" can be different, connecting the "method index" of the notify signal can
+ // incur in issues when the signal is being emitted and checking for connected endpoints.
+ // For example, we might be connected to the "method index" of the notify signal for the
+ // property and end up checking for the subscribers of a different signal when the notify
+ // signal is emitted, due to the different meaning of the same index.
+ // Thus we pass by the private interface to ensure that we are connecting based on the "signal
+ // index" instead.
+ const int index = QMetaObjectPrivate::signalIndex(obj->metaObject()->property(property)
+ .notifySignal());
+ referenceEndpoint->connect(obj, index, engine);
+
+ // When the object that is being referenced is destroyed, we
+ // need to ensure that one additional read is performed to
+ // invalidate the data we hold.
+ // As the object might be destroyed in a way that doesn't
+ // trigger the notify signal for the relevant property, we react
+ // directly to the destruction itself.
+ // We use a plain connection instead of a QQmlNotifierEndpoint
+ // based connection as, currently, declarative-side signals are
+ // always discarded during destruction (see
+ // QQmlData::signalEmitted).
+ // In theory it should be possible to relax that condition for
+ // the destroy signal specifically, which should allow a more
+ // optimized way of connecting.
+ // Nonetheless this seems to be the only place where we have
+ // this kind of need, and thus go for the simpler solution,
+ // which can be changed later if the need arises.
+ new (onDelete) QMetaObject::Connection(
+ QObject::connect(obj, &QObject::destroyed, [this](){ setDirty(true); }));
+}
+
+void Heap::ReferenceObject::connectToBindable(QObject *obj, int property, QQmlEngine *engine)
+{
+ 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); }));
+}
+
+} // namespace QV4
+
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4referenceobject_p.h b/src/qml/jsruntime/qv4referenceobject_p.h
index 0e7219ef92..c179e83363 100644
--- a/src/qml/jsruntime/qv4referenceobject_p.h
+++ b/src/qml/jsruntime/qv4referenceobject_p.h
@@ -53,70 +53,6 @@ DECLARE_HEAP_OBJECT(ReferenceObject, Object) {
void init(Object *object, int property, Flags flags)
{
- auto connectToNotifySignal = [this](QObject* obj, int property, QQmlEngine* engine) {
- Q_ASSERT(obj);
- Q_ASSERT(engine);
-
- Q_ASSERT(!referenceEndpoint);
- Q_ASSERT(!bindableNotifier);
-
- referenceEndpoint = new ReferenceObjectEndpoint(this);
- referenceEndpoint->connect(
- obj,
- // Connect and signal emission work on "signal
- // indexes". Those are different from "method
- // indexes".
- // The public MetaObject interface can, generally,
- // give us the "method index" of the notify
- // signal.
- // Quite unintuitively, this is true for
- // "notifySignalIndex".
- // As the "method index" and the "signal index"
- // can be different, connecting the "method index"
- // of the notify signal can incur in issues when
- // the signal is being emitted and checking for
- // connected endpoints.
- // For example, we might be connected to the
- // "method index" of the notify signal for the
- // property and end up checking for the
- // subscribers of a different signal when the
- // notify signal is emitted, due to the different
- // meaning of the same index.
- // Thus we pass by the private interface to ensure
- // that we are connecting based on the "signal
- // index" instead.
- QMetaObjectPrivate::signalIndex(obj->metaObject()->property(property).notifySignal()),
- engine);
- // When the object that is being referenced is destroyed, we
- // need to ensure that one additional read is performed to
- // invalidate the data we hold.
- // As the object might be destroyed in a way that doesn't
- // trigger the notify signal for the relevant property, we react
- // directly to the destruction itself.
- // We use a plain connection instead of a QQmlNotifierEndpoint
- // based connection as, currently, declarative-side signals are
- // always discarded during destruction (see
- // QQmlData::signalEmitted).
- // In theory it should be possible to relax that condition for
- // the destroy signal specifically, which should allow a more
- // optimized way of connecting.
- // Nonetheless this seems to be the only place where we have
- // this kind of need, and thus go for the simpler solution,
- // which can be changed later if the need arises.
- new(onDelete) QMetaObject::Connection(QObject::connect(obj, &QObject::destroyed, [this](){ setDirty(true); }));
- };
-
- auto connectToBindable = [this](QObject* obj, int property, QQmlEngine* engine) {
- 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); }));
- };
-
setObject(object);
m_property = property;
m_flags = flags;
@@ -227,6 +163,9 @@ DECLARE_HEAP_OBJECT(ReferenceObject, Object) {
delete bindableNotifier;
}
+ void connectToNotifySignal(QObject *obj, int property, QQmlEngine *engine);
+ void connectToBindable(QObject *obj, int property, QQmlEngine *engine);
+
private:
bool hasFlag(Flag flag) const