4#ifndef QQMLPROPERTYBINDING_P_H
5#define QQMLPROPERTYBINDING_P_H
18#include <private/qqmljavascriptexpression_p.h>
19#include <private/qqmlpropertydata_p.h>
20#include <private/qv4alloca_p.h>
21#include <private/qqmltranslation_p.h>
23#include <QtCore/qproperty.h>
41 void expressionChanged()
override;
62 static constexpr std::size_t jsExpressionOffsetLength() {
79 reinterpret_cast<std::byte const*
>(
this)
81 + jsExpressionOffsetLength()));
85 QObject *
obj,
const QQmlRefPointer<QQmlContextData> &ctxt,
89 QObject *
obj,
const QQmlRefPointer<QQmlContextData> &ctxt,
94 const QQmlRefPointer<QQmlContextData> &ctxt,
103 QObject *
obj,
const QQmlRefPointer<QQmlContextData> &ctxt,
119 template<QMetaType::Type type>
121 auto address =
static_cast<std::byte*
>(
f);
129 return (dependencyObserverCount > 0) || !jsExpression()->activeGuards.isEmpty();
133 template <QMetaType::Type type>
138 QString createBindingLoopErrorDescription();
141 enum BoundFunction :
bool {
142 WithoutBoundFunction =
false,
143 HasBoundFunction =
true,
150 bool hasBoundFunction;
151 bool isUndefined =
false;
157 return std::launder(
reinterpret_cast<TargetData *
>(&declarativeExtraData))->target;
162 return std::launder(
reinterpret_cast<TargetData *
>(&declarativeExtraData))->targetIndex;
165 bool hasBoundFunction()
167 return std::launder(
reinterpret_cast<TargetData *
>(&declarativeExtraData))->hasBoundFunction;
170 bool isUndefined()
const
172 return std::launder(
reinterpret_cast<TargetData
const *
>(&declarativeExtraData))->isUndefined;
175 void setIsUndefined(
bool isUndefined)
177 std::launder(
reinterpret_cast<TargetData *
>(&declarativeExtraData))->isUndefined = isUndefined;
187template<QMetaType::Type type>
189 &QQmlPropertyBinding::doEvaluate<type>,
190 [](
void *qpropertyBinding){
193 binding->~QQmlPropertyBinding();
194 auto address =
static_cast<std::byte*
>(qpropertyBinding);
197 [](
void *,
void *){},
204#define FOR_TYPE(TYPE) \
205 case TYPE: return &QtPrivate::bindingFunctionVTableForQQmlPropertyBinding<TYPE>
214 return &QtPrivate::bindingFunctionVTableForQQmlPropertyBinding<QMetaType::QObjectStar>;
215 return &QtPrivate::bindingFunctionVTableForQQmlPropertyBinding<QMetaType::UnknownType>;
224 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
228 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
235 reinterpret_cast<std::byte const*
>(
this)
237 - QQmlPropertyBinding::jsExpressionOffsetLength()));
244 if (*
static_cast<const T *
>(
result) == *
static_cast<const T *
>(dataPtr))
246 *
static_cast<T *
>(dataPtr) = *
static_cast<const T *
>(
result);
250template <QMetaType::Type type>
251bool QQmlPropertyBinding::evaluate(
QMetaType metaType,
void *dataPtr)
258 currentBinding->setError(std::move(error));
264 const auto handleErrorAndUndefined = [&](
bool evaluatedToUndefined) {
270 bindingErrorCallback(
this);
274 if (evaluatedToUndefined) {
275 handleUndefinedAssignment(ep, dataPtr);
280 setIsUndefined(
false);
286 if (!hasBoundFunction()) {
289 using Tuple = std::tuple<qsizetype, bool, bool>;
290 const auto [
size, needsConstruction, needsDestruction] = [&]() -> Tuple {
292 case QMetaType::QObjectStar:
return Tuple(
sizeof(
QObject *),
false,
false);
293 case QMetaType::Bool:
return Tuple(
sizeof(
bool),
false,
false);
294 case QMetaType::Int:
return Tuple(
sizeof(
int),
false,
false);
295 case QMetaType::Double:
return Tuple(
sizeof(
double),
false,
false);
296 case QMetaType::Float:
return Tuple(
sizeof(
float),
false,
false);
297 case QMetaType::QString:
return Tuple(
sizeof(
QString),
true,
true);
308 if (needsConstruction)
312 if (!handleErrorAndUndefined(evaluatedToUndefined))
316 case QMetaType::QObjectStar:
317 return compareAndAssign<QObject *>(dataPtr,
result);
318 case QMetaType::Bool:
319 return compareAndAssign<bool>(dataPtr,
result);
321 return compareAndAssign<int>(dataPtr,
result);
322 case QMetaType::Double:
323 return compareAndAssign<double>(dataPtr,
result);
324 case QMetaType::Float:
325 return compareAndAssign<float>(dataPtr,
result);
326 case QMetaType::QString: {
327 const bool hasChanged = compareAndAssign<QString>(dataPtr,
result);
335 const bool hasChanged = !metaType.
equals(
result, dataPtr);
337 if (needsDestruction)
341 if (needsDestruction)
346 bool evaluatedToUndefined =
false;
351 if (!handleErrorAndUndefined(evaluatedToUndefined))
355 case QMetaType::Bool: {
361 if (
b == *
static_cast<bool *
>(dataPtr))
363 *
static_cast<bool *
>(dataPtr) =
b;
366 case QMetaType::Int: {
370 else if (
result->isNumber()) {
375 if (
i == *
static_cast<int *
>(dataPtr))
377 *
static_cast<int *
>(dataPtr) =
i;
380 case QMetaType::Double:
383 if (
d == *
static_cast<double *
>(dataPtr))
385 *
static_cast<double *
>(dataPtr) =
d;
389 case QMetaType::Float:
391 float d = float(
result->asDouble());
392 if (
d == *
static_cast<float *
>(dataPtr))
394 *
static_cast<float *
>(dataPtr) =
d;
398 case QMetaType::QString:
401 if (
s == *
static_cast<QString *
>(dataPtr))
403 *
static_cast<QString *
>(dataPtr) =
s;
412 resultVariant.convert(metaType);
413 const bool hasChanged = !metaType.
equals(resultVariant.constData(), dataPtr);
415 metaType.
construct(dataPtr, resultVariant.constData());
QV4::ExecutionEngine * handle() const
static QPropertyBindingPrivate * currentlyEvaluatingBinding()
static constexpr size_t getSizeEnsuringAlignment()
bool hasCustomVTable() const
static QPropertyBindingPrivate * get(const QUntypedPropertyBinding &binding)
The QQmlContext class defines a context within a QML engine.
static QQmlEnginePrivate * get(QQmlEngine *e)
void referenceScarceResources()
void dereferenceScarceResources()
The QQmlEngine class provides an environment for instantiating QML components.
QV4::ReturnedValue evaluate(bool *isUndefined)
QQmlRefPointer< QQmlContextData > context() const
QV4::PersistentValue m_boundFunction
bool mustCaptureBindableProperty() const final
static bool doEvaluate(QMetaType metaType, QUntypedPropertyData *dataPtr, void *f)
QQmlPropertyBindingJS const * jsExpression() const
static bool isUndefined(const QPropertyBindingPrivate *binding)
static bool isUndefined(const QUntypedPropertyBinding &binding)
QQmlPropertyBindingJS * jsExpression()
The QQmlScriptString class encapsulates a script and its context.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Combined button and popup list for selecting options.
constexpr BindingFunctionVTable bindingFunctionVTableForQQmlPropertyBinding
#define QT_WARNING_DISABLE_INVALID_OFFSETOF
DBusConnection const char DBusError * error
GLboolean GLboolean GLboolean b
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLuint64EXT address
const QtPrivate::BindingFunctionVTable * bindingFunctionVTableForQQmlPropertyBinding(QMetaType type)
bool compareAndAssign(void *dataPtr, const void *result)
#define Q_ALLOCA_VAR(type, name, size)
QUrl url("example.com")
[constructor-url-reference]
engine evaluate("var myObject = new MyObject()")
[8]
static QVariant toVariant(const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjectsAndSymbols=true)
static double toInteger(double d)