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>
62 static constexpr std::size_t jsExpressionOffsetLength() {
79 reinterpret_cast<std::byte const*
>(
this)
81 + jsExpressionOffsetLength()));
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>;
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()) {
292 case QMetaType::QObjectStar:
return sizeof(
QObject *);
293 case QMetaType::Bool:
return sizeof(bool);
294 case QMetaType::Int:
return (
sizeof(
int));
295 case QMetaType::Double:
return (
sizeof(
double));
296 case QMetaType::Float:
return (
sizeof(
float));
297 case QMetaType::QString:
return (
sizeof(
QString));
298 default:
return metaType.
sizeOf();
304 if (!handleErrorAndUndefined(evaluatedToUndefined))
308 case QMetaType::QObjectStar:
309 return compareAndAssign<QObject *>(dataPtr,
result);
310 case QMetaType::Bool:
311 return compareAndAssign<bool>(dataPtr,
result);
313 return compareAndAssign<int>(dataPtr,
result);
314 case QMetaType::Double:
315 return compareAndAssign<double>(dataPtr,
result);
316 case QMetaType::Float:
317 return compareAndAssign<float>(dataPtr,
result);
318 case QMetaType::QString: {
319 const bool hasChanged = compareAndAssign<QString>(dataPtr,
result);
327 const bool hasChanged = !metaType.
equals(
result, dataPtr);
336 bool evaluatedToUndefined =
false;
341 if (!handleErrorAndUndefined(evaluatedToUndefined))
345 case QMetaType::Bool: {
351 if (
b == *
static_cast<bool *
>(dataPtr))
353 *
static_cast<bool *
>(dataPtr) =
b;
356 case QMetaType::Int: {
360 else if (
result->isNumber()) {
365 if (
i == *
static_cast<int *
>(dataPtr))
367 *
static_cast<int *
>(dataPtr) =
i;
370 case QMetaType::Double:
373 if (
d == *
static_cast<double *
>(dataPtr))
375 *
static_cast<double *
>(dataPtr) =
d;
379 case QMetaType::Float:
381 float d = float(
result->asDouble());
382 if (
d == *
static_cast<float *
>(dataPtr))
384 *
static_cast<float *
>(dataPtr) =
d;
388 case QMetaType::QString:
391 if (
s == *
static_cast<QString *
>(dataPtr))
393 *
static_cast<QString *
>(dataPtr) =
s;
402 resultVariant.convert(metaType);
403 const bool hasChanged = !metaType.
equals(resultVariant.constData(), dataPtr);
405 metaType.
construct(dataPtr, resultVariant.constData());
QV4::ExecutionEngine * handle() const
static QPropertyBindingPrivate * currentlyEvaluatingBinding()
static constexpr size_t getSizeEnsuringAlignment()
bool hasCustomVTable() const
void setError(QPropertyBindingError &&e)
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
virtual void expressionChanged()=0
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.
\qmltype Particle \inqmlmodule QtQuick.Particles
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)