Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmlpropertytopropertybinding_p.h
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQMLPROPERTYTOPROPERTYBINDINDING_P_H
5#define QQMLPROPERTYTOPROPERTYBINDINDING_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <private/qqmlabstractbinding_p.h>
19#include <private/qqmlengine_p.h>
20#include <private/qqmlnotifier_p.h>
21#include <private/qqmlvaluetype_p.h>
22#include <private/qv4jscall_p.h>
23
24#include <QtCore/qproperty.h>
25
26QT_BEGIN_NAMESPACE
27
28// Different forms of property-to-property binding
29// unbindable -> unbindable: QQmlAbstractBinding + QQmlNotifierEndpoint
30// unbindable -> bindable: QPropertyBindingPrivate + QQmlNotifierEndpoint
31// bindable -> unbindable: QQmlAbstractBinding + QPropertyObserver
32// bindable -> bindable: QPropertyBindingPrivate only
33
34class QQmlPropertyToPropertyBinding
35{
36public:
37 static Q_QML_EXPORT QQmlAnyBinding create(
38 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
39
40private:
41 friend class QQmlPropertyToUnbindablePropertyBinding;
42 friend class QQmlUnbindableToUnbindablePropertyBinding;
43 friend class QQmlBindableToUnbindablePropertyBinding;
44 friend class QQmlPropertyToBindablePropertyBinding;
45 friend class QQmlUnbindableToBindablePropertyBinding;
46 friend class QQmlBindableToBindablePropertyBinding;
47
48 QQmlPropertyToPropertyBinding(QQmlEngine *engine, const QQmlProperty &source);
49
50 template<typename Capture>
51 QVariant readSourceValue(Capture &&capture) const
52 {
53 const QMetaObject *sourceMetaObject = sourceObject->metaObject();
54 const QMetaProperty property
55 = sourceMetaObject->property(sourcePropertyIndex.coreIndex());
56 if (!property.isConstant())
57 capture(sourceMetaObject, property);
58
59 QVariant value;
60
61 const int valueTypeIndex = sourcePropertyIndex.valueTypeIndex();
62 if (valueTypeIndex == -1) {
63 value = property.read(sourceObject);
64 } else {
65 QQmlGadgetPtrWrapper *wrapper
66 = QQmlEnginePrivate::get(engine)->valueTypeInstance(property.metaType());
67 wrapper->read(sourceObject, sourcePropertyIndex.coreIndex());
68 value = wrapper->readOnGadget(wrapper->property(valueTypeIndex));
69 }
70
71 return value;
72 }
73
74 void doConnectNotify(QQmlNotifierEndpoint *endpoint, const QMetaProperty &property)
75 {
76 const int notifyIndex = QMetaObjectPrivate::signalIndex(property.notifySignal());
77
78 // We cannot capture non-bindable properties without signals
79 if (notifyIndex == -1)
80 return;
81
82 if (endpoint->isConnected(sourceObject, notifyIndex))
83 endpoint->cancelNotify();
84 else
85 endpoint->connect(sourceObject, notifyIndex, engine, true);
86 }
87
88 QQmlEngine *engine = nullptr;
89 QObject *sourceObject = nullptr;
90 QQmlPropertyIndex sourcePropertyIndex;
91};
92
94{
95public:
96 Kind kind() const final;
97 void setEnabled(bool e, QQmlPropertyData::WriteFlags flags) final;
98 void update(QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding);
99
100protected:
102 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
103
104 virtual void captureProperty(
105 const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty) = 0;
106
107 QQmlPropertyToPropertyBinding m_binding;
108};
109
112{
113public:
115 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
116protected:
117 void captureProperty(
118 const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty) final;
119};
120
123{
124public:
126 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
127
128 static void update(QPropertyObserver *observer, QUntypedPropertyData *);
129
130protected:
131 void captureProperty(
132 const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty) final;
133private:
134 bool m_isObserving = false;
135};
136
138{
139public:
141 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target,
142 const QtPrivate::BindingFunctionVTable *vtable);
143
144 template<typename Concrete>
145 static bool update(QMetaType metaType, QUntypedPropertyData *dataPtr, void *f)
146 {
147 Concrete *self = reinterpret_cast<Concrete *>(
148 // Address of QPropertyBindingPrivate subobject
149 static_cast<std::byte *>(f) - QPropertyBindingPrivate::getSizeEnsuringAlignment());
150
151 const QVariant value = self->m_binding.readSourceValue(
152 [self](const QMetaObject *metaObject, const QMetaProperty &property) {
153 self->captureProperty(metaObject, property);
154 });
155
156 QV4::coerce(
157 self->m_binding.engine->handle(), value.metaType(), value.constData(),
158 metaType, dataPtr);
159 return true;
160 }
161
162protected:
163 QQmlPropertyToPropertyBinding m_binding;
164};
165
168{
169public:
171 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
172
173 void update();
174
175 void captureProperty(const QMetaObject *, const QMetaProperty &property)
176 {
177 m_binding.doConnectNotify(this, property);
178 }
179};
180
182{
183public:
185 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
186
187 void captureProperty(const QMetaObject *, const QMetaProperty &) {}
188};
189
190void QQmlUnbindableToUnbindableGuard_callback(QQmlNotifierEndpoint *e, void **);
191void QQmlUnbindableToBindableGuard_callback(QQmlNotifierEndpoint *e, void **);
192
193QT_END_NAMESPACE
194
195#endif
QQmlBindableToBindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target)
void captureProperty(const QMetaObject *, const QMetaProperty &)
void captureProperty(const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty) final
QQmlBindableToUnbindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target)
static void update(QPropertyObserver *observer, QUntypedPropertyData *)
QQmlPropertyToBindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target, const QtPrivate::BindingFunctionVTable *vtable)
static bool update(QMetaType metaType, QUntypedPropertyData *dataPtr, void *f)
void setEnabled(bool e, QQmlPropertyData::WriteFlags flags) final
QQmlPropertyToUnbindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target)
virtual void captureProperty(const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty)=0
void update(QQmlPropertyData::WriteFlags flags=QQmlPropertyData::DontRemoveBinding)
void captureProperty(const QMetaObject *, const QMetaProperty &property)
QQmlUnbindableToBindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target)
QQmlUnbindableToUnbindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target)
void captureProperty(const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty) final
constexpr BindingFunctionVTable bindingFunctionVTableForQQmlPropertyToBindablePropertyBinding
void QQmlUnbindableToBindableGuard_callback(QQmlNotifierEndpoint *e, void **)
void QQmlUnbindableToUnbindableGuard_callback(QQmlNotifierEndpoint *e, void **)