1 | // Copyright (C) 2016 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 QQMLBINDING_P_H |
5 | #define QQMLBINDING_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 "qqmlproperty.h" |
19 | #include "qqmlscriptstring.h" |
20 | |
21 | #include <QtCore/QObject> |
22 | #include <QtCore/QMetaProperty> |
23 | |
24 | #include <private/qqmlabstractbinding_p.h> |
25 | #include <private/qqmljavascriptexpression_p.h> |
26 | #include <private/qv4functionobject_p.h> |
27 | #include <private/qqmltranslation_p.h> |
28 | |
29 | QT_BEGIN_NAMESPACE |
30 | |
31 | class QQmlContext; |
32 | class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression, |
33 | public QQmlAbstractBinding |
34 | { |
35 | friend class QQmlAbstractBinding; |
36 | public: |
37 | typedef QExplicitlySharedDataPointer<QQmlBinding> Ptr; |
38 | |
39 | static QQmlBinding *create(const QQmlPropertyData *, const QQmlScriptString &, QObject *, QQmlContext *); |
40 | |
41 | static QQmlBinding *create( |
42 | const QQmlPropertyData *, const QString &, QObject *, |
43 | const QQmlRefPointer<QQmlContextData> &, const QString &url = QString(), |
44 | quint16 lineNumber = 0); |
45 | |
46 | static QQmlBinding *create( |
47 | const QQmlPropertyData *property, QV4::Function *function, QObject *obj, |
48 | const QQmlRefPointer<QQmlContextData> &ctxt, QV4::ExecutionContext *scope); |
49 | |
50 | static QQmlBinding *create(QMetaType propertyType, QV4::Function *function, QObject *obj, |
51 | const QQmlRefPointer<QQmlContextData> &ctxt, |
52 | QV4::ExecutionContext *scope); |
53 | |
54 | static QQmlBinding *createTranslationBinding( |
55 | const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit, |
56 | const QV4::CompiledData::Binding *binding, QObject *obj, |
57 | const QQmlRefPointer<QQmlContextData> &ctxt); |
58 | |
59 | static QQmlBinding * |
60 | createTranslationBinding(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit, |
61 | const QQmlRefPointer<QQmlContextData> &ctxt, |
62 | const QString &propertyName, const QQmlTranslation &translationData, |
63 | const QQmlSourceLocation &location, QObject *obj); |
64 | |
65 | Kind kind() const final { return QQmlAbstractBinding::QmlBinding; } |
66 | |
67 | ~QQmlBinding() override; |
68 | |
69 | bool mustCaptureBindableProperty() const final {return true;} |
70 | void refresh() override; |
71 | |
72 | void setEnabled(bool, QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding) override; |
73 | QString expression() const override; |
74 | void update(QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding); |
75 | |
76 | typedef int Identifier; |
77 | enum { |
78 | Invalid = -1 |
79 | }; |
80 | |
81 | QVariant evaluate(); |
82 | bool evaluate(void *result, QMetaType type) |
83 | { |
84 | return QQmlJavaScriptExpression::evaluate(a: &result, types: &type, argc: 0); |
85 | } |
86 | |
87 | void expressionChanged() override; |
88 | |
89 | QQmlSourceLocation sourceLocation() const override; |
90 | void setSourceLocation(const QQmlSourceLocation &location); |
91 | void setBoundFunction(QV4::BoundFunction *boundFunction) { |
92 | m_boundFunction.set(engine: boundFunction->engine(), value: *boundFunction); |
93 | } |
94 | bool hasBoundFunction() const { return m_boundFunction.valueRef(); } |
95 | |
96 | /** |
97 | * This method returns a snapshot of the currently tracked dependencies of |
98 | * this binding. The dependencies can change upon reevaluation. This method is |
99 | * used in GammaRay to visualize binding hierarchies. |
100 | * |
101 | * Call this method from the UI thread. |
102 | */ |
103 | QVector<QQmlProperty> dependencies() const; |
104 | // This method is used internally to check whether a binding is constant and can be removed |
105 | virtual bool hasDependencies() const; |
106 | |
107 | protected: |
108 | virtual void doUpdate(const DeleteWatcher &watcher, |
109 | QQmlPropertyData::WriteFlags flags, QV4::Scope &scope); |
110 | |
111 | virtual bool write(const QV4::Value &result, bool isUndefined, QQmlPropertyData::WriteFlags flags) = 0; |
112 | virtual bool write(void *result, QMetaType type, bool isUndefined, QQmlPropertyData::WriteFlags flags) = 0; |
113 | |
114 | int getPropertyType() const; |
115 | |
116 | bool slowWrite(const QQmlPropertyData &core, const QQmlPropertyData &valueTypeData, |
117 | const QV4::Value &result, bool isUndefined, QQmlPropertyData::WriteFlags flags); |
118 | bool slowWrite(const QQmlPropertyData &core, const QQmlPropertyData &valueTypeData, |
119 | const void *result, QMetaType resultType, bool isUndefined, |
120 | QQmlPropertyData::WriteFlags flags); |
121 | |
122 | QV4::ReturnedValue evaluate(bool *isUndefined); |
123 | |
124 | private: |
125 | static QQmlBinding *newBinding(const QQmlPropertyData *property); |
126 | static QQmlBinding *newBinding(QMetaType propertyType); |
127 | |
128 | QQmlSourceLocation *m_sourceLocation = nullptr; // used for Qt.binding() created functions |
129 | QV4::PersistentValue m_boundFunction; // used for Qt.binding() that are created from a bound function object |
130 | void handleWriteError(const void *result, QMetaType resultType, QMetaType metaType); |
131 | }; |
132 | |
133 | QT_END_NAMESPACE |
134 | |
135 | Q_DECLARE_METATYPE(QQmlBinding*) |
136 | |
137 | #endif // QQMLBINDING_P_H |
138 | |