From 007ae316a62670eeff8b08526fad9110fff0bbd4 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Thu, 14 Jul 2016 12:09:23 +0200 Subject: QML: Unify property reads/writes and use accessors Pass property reads/writes through utility functions in QQmlProperty, which in turn will try to use accessors when available (and no interceptors have to be called). Change-Id: I60ecfc202b6024bfe4a33206a46299787b152546 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlabstractbinding_p.h | 2 +- src/qml/qml/qqmlbinding.cpp | 26 +++--- src/qml/qml/qqmlbinding_p.h | 8 +- src/qml/qml/qqmlengine.cpp | 4 +- src/qml/qml/qqmlobjectcreator.cpp | 136 +++++++++--------------------- src/qml/qml/qqmlproperty.cpp | 51 +++++------ src/qml/qml/qqmlproperty_p.h | 18 ++-- src/qml/qml/qqmlpropertycache_p.h | 37 ++++++++ src/qml/qml/qqmlvaluetype.cpp | 2 +- src/qml/qml/qqmlvaluetype_p.h | 2 +- src/qml/qml/qqmlvaluetypeproxybinding.cpp | 2 +- src/qml/qml/qqmlvaluetypeproxybinding_p.h | 2 +- src/qml/qml/qqmlvmemetaobject.cpp | 6 +- 13 files changed, 126 insertions(+), 170 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h index d25c0c6288..0ccfae4610 100644 --- a/src/qml/qml/qqmlabstractbinding_p.h +++ b/src/qml/qml/qqmlabstractbinding_p.h @@ -82,7 +82,7 @@ public: // binding is not enabled or added to the object. QObject *targetObject() const { return m_target.data(); } - virtual void setEnabled(bool e, QQmlPropertyPrivate::WriteFlags f = QQmlPropertyPrivate::DontRemoveBinding) = 0; + virtual void setEnabled(bool e, QQmlPropertyData::WriteFlags f = QQmlPropertyData::DontRemoveBinding) = 0; void addToObject(); void removeFromObject(); diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 9737dfdd6b..10d16a8a12 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -157,7 +157,7 @@ void QQmlBinding::setNotifyOnValueChanged(bool v) QQmlJavaScriptExpression::setNotifyOnValueChanged(v); } -void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags) +void QQmlBinding::update(QQmlPropertyData::WriteFlags flags) { if (!enabledFlag() || !context() || !context()->isValid()) return; @@ -181,6 +181,9 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags) QV4::ScopedFunctionObject f(scope, m_function.value()); Q_ASSERT(f); + if (canUseAccessor()) + flags.setFlag(QQmlPropertyData::BypassInterceptor); + QQmlBindingProfiler prof(ep->profiler, this, f); doUpdate(this, watcher, flags, scope, f); @@ -197,7 +200,7 @@ class QQmlBindingBinding: public QQmlBinding { protected: void doUpdate(QQmlBinding *binding, const DeleteWatcher &, - QQmlPropertyPrivate::WriteFlags flags, QV4::Scope &, + QQmlPropertyData::WriteFlags flags, QV4::Scope &, const QV4::ScopedFunctionObject &) Q_DECL_OVERRIDE Q_DECL_FINAL { QQmlPropertyData pd = getPropertyData(); @@ -216,7 +219,7 @@ class GenericBinding: public QQmlBinding { protected: void doUpdate(QQmlBinding *binding, const DeleteWatcher &watcher, - QQmlPropertyPrivate::WriteFlags flags, QV4::Scope &scope, + QQmlPropertyData::WriteFlags flags, QV4::Scope &scope, const QV4::ScopedFunctionObject &f) Q_DECL_OVERRIDE Q_DECL_FINAL { auto ep = QQmlEnginePrivate::get(scope.engine); @@ -251,7 +254,7 @@ protected: // Returns true if successful, false if an error description was set on expression Q_ALWAYS_INLINE bool write(const QV4::Value &result, bool isUndefined, - QQmlPropertyPrivate::WriteFlags flags) + QQmlPropertyData::WriteFlags flags) { QQmlPropertyData pd = getPropertyData(); int propertyType = StaticPropType; // If the binding is specialized to a type, the if and switch below will be constant-folded. @@ -298,22 +301,15 @@ protected: } template - Q_ALWAYS_INLINE bool doStore(T value, const QQmlPropertyData &pd, QQmlPropertyPrivate::WriteFlags flags) const + Q_ALWAYS_INLINE bool doStore(T value, const QQmlPropertyData &pd, QQmlPropertyData::WriteFlags flags) const { void *o = &value; - if (pd.hasAccessors() && canUseAccessor()) { - pd.accessors->write(m_target.data(), o); - } else { - int status = -1; - void *argv[] = { o, 0, &status, &flags }; - QMetaObject::metacall(targetObject(), QMetaObject::WriteProperty, pd.coreIndex, argv); - } - return true; + return pd.writeProperty(targetObject(), o, flags); } }; Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core, const QV4::Value &result, - bool isUndefined, QQmlPropertyPrivate::WriteFlags flags) + bool isUndefined, QQmlPropertyData::WriteFlags flags) { QQmlEngine *engine = context()->engine; QV8Engine *v8engine = QQmlEnginePrivate::getV8Engine(engine); @@ -458,7 +454,7 @@ void QQmlBinding::refresh() update(); } -void QQmlBinding::setEnabled(bool e, QQmlPropertyPrivate::WriteFlags flags) +void QQmlBinding::setEnabled(bool e, QQmlPropertyData::WriteFlags flags) { setEnabledFlag(e); setNotifyOnValueChanged(e); diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index a7c90603f6..0c797d7df2 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -87,9 +87,9 @@ public: void refresh() Q_DECL_OVERRIDE; - void setEnabled(bool, QQmlPropertyPrivate::WriteFlags flags = QQmlPropertyPrivate::DontRemoveBinding) Q_DECL_OVERRIDE; + void setEnabled(bool, QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding) Q_DECL_OVERRIDE; QString expression() const Q_DECL_OVERRIDE; - void update(QQmlPropertyPrivate::WriteFlags flags = QQmlPropertyPrivate::DontRemoveBinding); + void update(QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding); typedef int Identifier; enum { @@ -103,7 +103,7 @@ public: protected: virtual void doUpdate(QQmlBinding *binding, const DeleteWatcher &watcher, - QQmlPropertyPrivate::WriteFlags flags, QV4::Scope &scope, + QQmlPropertyData::WriteFlags flags, QV4::Scope &scope, const QV4::ScopedFunctionObject &f) = 0; QQmlPropertyData getPropertyData() const; @@ -111,7 +111,7 @@ protected: int getPropertyType() const; bool slowWrite(const QQmlPropertyData &core, const QV4::Value &result, bool isUndefined, - QQmlPropertyPrivate::WriteFlags flags); + QQmlPropertyData::WriteFlags flags); private: inline bool updatingFlag() const; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index d391f38b61..7dac164248 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -848,8 +848,8 @@ void QQmlData::flushPendingBindingImpl(int coreIndex) b = b->nextBinding(); if (b && b->targetPropertyIndex() == coreIndex) - b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor | - QQmlPropertyPrivate::DontRemoveBinding); + b->setEnabled(true, QQmlPropertyData::BypassInterceptor | + QQmlPropertyData::DontRemoveBinding); } bool QQmlEnginePrivate::baseModulesUninitialized = true; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 7cb7047b04..87212ef713 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -275,11 +275,7 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance) void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding) { - QQmlPropertyPrivate::WriteFlags propertyWriteFlags = QQmlPropertyPrivate::BypassInterceptor | - QQmlPropertyPrivate::RemoveBindingOnAliasWrite; - int propertyWriteStatus = -1; - void *argv[] = { 0, 0, &propertyWriteStatus, &propertyWriteFlags }; - + QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite; QV4::Scope scope(v4); int propertyType = property->propType; @@ -307,16 +303,14 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const } else { int i = int(n); QVariant value(i); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } } else { if (property->isVarProperty()) { _vmeMetaObject->setVMEProperty(property->coreIndex, QV4::Primitive::fromDouble(n)); } else { QVariant value(n); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } } } else if (binding->type == QV4::CompiledData::Binding::Type_Boolean) { @@ -324,8 +318,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const _vmeMetaObject->setVMEProperty(property->coreIndex, QV4::Primitive::fromBoolean(binding->valueAsBoolean())); } else { QVariant value(binding->valueAsBoolean()); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } } else { QString stringValue = binding->valueAsString(qmlUnit); @@ -334,8 +327,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const _vmeMetaObject->setVMEProperty(property->coreIndex, s); } else { QVariant value = QQmlStringConverters::variantFromString(stringValue); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } } } @@ -343,26 +335,19 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const case QVariant::String: { Q_ASSERT(binding->evaluatesToString()); QString value = binding->valueAsString(qmlUnit); - if (property->hasAccessors()) { - property->accessors->write(_qobject, &value); - } else { - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); - } + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::StringList: { Q_ASSERT(binding->evaluatesToString()); QStringList value(binding->valueAsString(qmlUnit)); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::ByteArray: { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String); QByteArray value(binding->valueAsString(qmlUnit).toUtf8()); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Url: { @@ -374,16 +359,14 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const // Apply URL interceptor if (engine->urlInterceptor()) value = engine->urlInterceptor()->intercept(value, QQmlAbstractUrlInterceptor::UrlString); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::UInt: { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); double d = binding->valueAsNumber(); uint value = uint(d); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); break; } break; @@ -391,35 +374,20 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); double d = binding->valueAsNumber(); int value = int(d); - if (property->hasAccessors()) { - property->accessors->write(_qobject, &value); - } else { - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); - } + property->writeProperty(_qobject, &value, propertyWriteFlags); break; } break; case QMetaType::Float: { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); float value = float(binding->valueAsNumber()); - if (property->hasAccessors()) { - property->accessors->write(_qobject, &value); - } else { - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); - } + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Double: { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); double value = binding->valueAsNumber(); - if (property->hasAccessors()) { - property->accessors->write(_qobject, &value); - } else { - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); - } + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Color: { @@ -428,8 +396,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const Q_ASSERT(ok); struct { void *data[4]; } buffer; if (QQml_valueTypeProvider()->storeValueType(property->propType, &colorValue, &buffer, sizeof(buffer))) { - argv[0] = reinterpret_cast(&buffer); - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &buffer, propertyWriteFlags); } } break; @@ -438,16 +405,14 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const bool ok = false; QDate value = QQmlStringConverters::dateFromString(binding->valueAsString(qmlUnit), &ok); Q_ASSERT(ok); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Time: { bool ok = false; QTime value = QQmlStringConverters::timeFromString(binding->valueAsString(qmlUnit), &ok); Q_ASSERT(ok); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::DateTime: { @@ -460,8 +425,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const value = QDateTime(QDate::fromJulianDay(date), QTime::fromMSecsSinceStartOfDay(msecsSinceStartOfDay)); } Q_ASSERT(ok); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; #endif // QT_NO_DATESTRING @@ -469,59 +433,48 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const bool ok = false; QPoint value = QQmlStringConverters::pointFFromString(binding->valueAsString(qmlUnit), &ok).toPoint(); Q_ASSERT(ok); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::PointF: { bool ok = false; QPointF value = QQmlStringConverters::pointFFromString(binding->valueAsString(qmlUnit), &ok); Q_ASSERT(ok); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Size: { bool ok = false; QSize value = QQmlStringConverters::sizeFFromString(binding->valueAsString(qmlUnit), &ok).toSize(); Q_ASSERT(ok); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::SizeF: { bool ok = false; QSizeF value = QQmlStringConverters::sizeFFromString(binding->valueAsString(qmlUnit), &ok); Q_ASSERT(ok); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Rect: { bool ok = false; QRect value = QQmlStringConverters::rectFFromString(binding->valueAsString(qmlUnit), &ok).toRect(); Q_ASSERT(ok); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::RectF: { bool ok = false; QRectF value = QQmlStringConverters::rectFFromString(binding->valueAsString(qmlUnit), &ok); Q_ASSERT(ok); - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Bool: { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Boolean); bool value = binding->valueAsBoolean(); - if (property->hasAccessors()) { - property->accessors->write(_qobject, &value); - } else { - argv[0] = &value; - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); - } + property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Vector3D: { @@ -533,8 +486,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const bool ok = QQmlStringConverters::createFromString(QMetaType::QVector3D, binding->valueAsString(qmlUnit), &vec, sizeof(vec)); Q_ASSERT(ok); Q_UNUSED(ok); - argv[0] = reinterpret_cast(&vec); - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &vec, propertyWriteFlags); } break; case QVariant::Vector4D: { @@ -547,8 +499,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const bool ok = QQmlStringConverters::createFromString(QMetaType::QVector4D, binding->valueAsString(qmlUnit), &vec, sizeof(vec)); Q_ASSERT(ok); Q_UNUSED(ok); - argv[0] = reinterpret_cast(&vec); - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &vec, propertyWriteFlags); } break; case QVariant::RegExp: @@ -560,23 +511,20 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); QList value; value.append(binding->valueAsNumber()); - argv[0] = reinterpret_cast(&value); - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); break; } else if (property->propType == qMetaTypeId >()) { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); double n = binding->valueAsNumber(); QList value; value.append(int(n)); - argv[0] = reinterpret_cast(&value); - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); break; } else if (property->propType == qMetaTypeId >()) { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Boolean); QList value; value.append(binding->valueAsBoolean()); - argv[0] = reinterpret_cast(&value); - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); break; } else if (property->propType == qMetaTypeId >()) { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String); @@ -584,15 +532,13 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const QUrl u = urlString.isEmpty() ? QUrl() : compilationUnit->url().resolved(QUrl(urlString)); QList value; value.append(u); - argv[0] = reinterpret_cast(&value); - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); break; } else if (property->propType == qMetaTypeId >()) { Q_ASSERT(binding->evaluatesToString()); QList value; value.append(binding->valueAsString(qmlUnit)); - argv[0] = reinterpret_cast(&value); - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); break; } else if (property->propType == qMetaTypeId()) { QJSValue value; @@ -607,8 +553,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const } else { value = QJSValue(binding->valueAsString(qmlUnit)); } - argv[0] = reinterpret_cast(&value); - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, &value, propertyWriteFlags); break; } @@ -624,8 +569,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; } - argv[0] = value.data(); - QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); + property->writeProperty(_qobject, value.data(), propertyWriteFlags); } break; } @@ -755,8 +699,8 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con ss.d.data()->isNumberLiteral = binding->type == QV4::CompiledData::Binding::Type_Number; ss.d.data()->numberValue = binding->valueAsNumber(); - QQmlPropertyPrivate::WriteFlags propertyWriteFlags = QQmlPropertyPrivate::BypassInterceptor | - QQmlPropertyPrivate::RemoveBindingOnAliasWrite; + QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | + QQmlPropertyData::RemoveBindingOnAliasWrite; int propertyWriteStatus = -1; void *argv[] = { &ss, 0, &propertyWriteStatus, &propertyWriteFlags }; QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv); @@ -808,7 +752,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con return false; if (valueType) - valueType->write(_qobject, property->coreIndex, QQmlPropertyPrivate::BypassInterceptor); + valueType->write(_qobject, property->coreIndex, QQmlPropertyData::BypassInterceptor); return true; } @@ -934,8 +878,8 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con return true; } - QQmlPropertyPrivate::WriteFlags propertyWriteFlags = QQmlPropertyPrivate::BypassInterceptor | - QQmlPropertyPrivate::RemoveBindingOnAliasWrite; + QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | + QQmlPropertyData::RemoveBindingOnAliasWrite; int propertyWriteStatus = -1; void *argv[] = { 0, 0, &propertyWriteStatus, &propertyWriteFlags }; @@ -1213,8 +1157,8 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru QQmlData *data = QQmlData::get(b->targetObject()); Q_ASSERT(data); data->clearPendingBindingBit(b->targetPropertyIndex()); - b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor | - QQmlPropertyPrivate::DontRemoveBinding); + b->setEnabled(true, QQmlPropertyData::BypassInterceptor | + QQmlPropertyData::DontRemoveBinding); if (watcher.hasRecursed() || interrupt.shouldInterrupt()) return 0; diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index e04b1114ad..64852f1cfe 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -42,6 +42,7 @@ #include "qqml.h" #include "qqmlbinding_p.h" +#include "qqmlboundsignal_p.h" #include "qqmlcontext.h" #include "qqmlcontext_p.h" #include "qqmlboundsignal_p.h" @@ -316,8 +317,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name) if (!property->isQObject()) return; // Not an object property - void *args[] = { ¤tObject, 0 }; - QMetaObject::metacall(currentObject, QMetaObject::ReadProperty, property->coreIndex, args); + property->readProperty(currentObject, ¤tObject); if (!currentObject) return; // No value } @@ -858,7 +858,7 @@ void QQmlPropertyPrivate::findAliasTarget(QObject *object, int bindingIndex, } -void QQmlPropertyPrivate::setBinding(QQmlAbstractBinding *binding, BindingFlags flags, WriteFlags writeFlags) +void QQmlPropertyPrivate::setBinding(QQmlAbstractBinding *binding, BindingFlags flags, QQmlPropertyData::WriteFlags writeFlags) { Q_ASSERT(binding); @@ -1034,15 +1034,13 @@ QVariant QQmlPropertyPrivate::readValueProperty() } else if (core.isQList()) { QQmlListProperty prop; - void *args[] = { &prop, 0 }; - QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args); + core.readProperty(object, &prop); return QVariant::fromValue(QQmlListReferencePrivate::init(prop, core.propType, engine)); } else if (core.isQObject()) { QObject *rv = 0; - void *args[] = { &rv, 0 }; - QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args); + core.readProperty(object, &rv); return QVariant::fromValue(rv); } else { @@ -1059,7 +1057,7 @@ QVariant QQmlPropertyPrivate::readValueProperty() value = QVariant(core.propType, (void*)0); args[0] = value.data(); } - QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args); + core.readPropertyWithArgs(object, args); if (core.propType != QMetaType::QVariant && args[0] != value.data()) return QVariant((QVariant::Type)core.propType, args[0]); @@ -1147,7 +1145,7 @@ bool QQmlPropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx, return status; } -bool QQmlPropertyPrivate::writeValueProperty(const QVariant &value, WriteFlags flags) +bool QQmlPropertyPrivate::writeValueProperty(const QVariant &value, QQmlPropertyData::WriteFlags flags) { return writeValueProperty(object, core, value, effectiveContext(), flags); } @@ -1156,10 +1154,10 @@ bool QQmlPropertyPrivate::writeValueProperty(QObject *object, const QQmlPropertyData &core, const QVariant &value, - QQmlContextData *context, WriteFlags flags) + QQmlContextData *context,QQmlPropertyData::WriteFlags flags) { // Remove any existing bindings on this property - if (!(flags & DontRemoveBinding) && object) + if (!(flags & QQmlPropertyData::DontRemoveBinding) && object) removeBinding(object, core.encodedIndex()); bool rv = false; @@ -1189,10 +1187,9 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object, bool QQmlPropertyPrivate::write(QObject *object, const QQmlPropertyData &property, const QVariant &value, QQmlContextData *context, - WriteFlags flags) + QQmlPropertyData::WriteFlags flags) { int coreIdx = property.coreIndex; - int status = -1; //for dbus if (property.isEnum()) { QMetaProperty prop = object->metaObject()->property(property.coreIndex); @@ -1238,24 +1235,18 @@ bool QQmlPropertyPrivate::write(QObject *object, if (context && u.isRelative() && !u.isEmpty()) u = context->resolvedUrl(u); - int status = -1; - void *argv[] = { &u, 0, &status, &flags }; - QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv); + return property.writeProperty(object, &u, flags); } else if (propertyType == qMetaTypeId >()) { QList urlSeq = resolvedUrlSequence(value, context).value >(); - int status = -1; - void *argv[] = { &urlSeq, 0, &status, &flags }; - QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv); + return property.writeProperty(object, &urlSeq, flags); } else if (variantType == propertyType) { - void *a[] = { const_cast(value.constData()), 0, &status, &flags }; - QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); + return property.writeProperty(object, const_cast(value.constData()), flags); } else if (qMetaTypeId() == propertyType) { - void *a[] = { const_cast(&value), 0, &status, &flags }; - QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); + return property.writeProperty(object, const_cast(&value), flags); } else if (property.isQObject()) { @@ -1270,14 +1261,12 @@ bool QQmlPropertyPrivate::write(QObject *object, if (o) valMo = o; if (QQmlMetaObject::canConvert(valMo, propMo)) { - void *args[] = { &o, 0, &status, &flags }; - QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, args); + return property.writeProperty(object, &o, flags); } else if (!o && QQmlMetaObject::canConvert(propMo, valMo)) { // In the case of a null QObject, we assign the null if there is // any change that the null variant type could be up or down cast to // the property type. - void *args[] = { &o, 0, &status, &flags }; - QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, args); + return property.writeProperty(object, &o, flags); } else { return false; } @@ -1296,8 +1285,7 @@ bool QQmlPropertyPrivate::write(QObject *object, if (listType.isNull()) return false; QQmlListProperty prop; - void *args[] = { &prop, 0 }; - QMetaObject::metacall(object, QMetaObject::ReadProperty, coreIdx, args); + property.readProperty(object, &prop); if (!prop.clear) return false; @@ -1410,8 +1398,7 @@ bool QQmlPropertyPrivate::write(QObject *object, } if (ok) { - void *a[] = { const_cast(v.constData()), 0, &status, &flags}; - QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); + return property.writeProperty(object, const_cast(v.constData()), flags); } else { return false; } @@ -1512,7 +1499,7 @@ bool QQmlProperty::reset() const } bool QQmlPropertyPrivate::write(const QQmlProperty &that, - const QVariant &value, WriteFlags flags) + const QVariant &value, QQmlPropertyData::WriteFlags flags) { if (!that.d) return false; diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h index 58fea9c239..9398c74621 100644 --- a/src/qml/qml/qqmlproperty_p.h +++ b/src/qml/qml/qqmlproperty_p.h @@ -68,13 +68,6 @@ class QQmlJavaScriptExpression; class Q_QML_PRIVATE_EXPORT QQmlPropertyPrivate : public QQmlRefCount { public: - enum WriteFlag { - BypassInterceptor = 0x01, - DontRemoveBinding = 0x02, - RemoveBindingOnAliasWrite = 0x04 - }; - Q_DECLARE_FLAGS(WriteFlags, WriteFlag) - QQmlContextData *context; QPointer engine; QPointer object; @@ -97,7 +90,7 @@ public: QQmlProperty::PropertyTypeCategory propertyTypeCategory() const; QVariant readValueProperty(); - bool writeValueProperty(const QVariant &, WriteFlags); + bool writeValueProperty(const QVariant &, QQmlPropertyData::WriteFlags); static QQmlMetaObject rawMetaObjectForType(QQmlEnginePrivate *, int); static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, @@ -105,9 +98,9 @@ public: static bool writeValueProperty(QObject *, const QQmlPropertyData &, const QVariant &, QQmlContextData *, - WriteFlags flags = 0); + QQmlPropertyData::WriteFlags flags = 0); static bool write(QObject *, const QQmlPropertyData &, const QVariant &, - QQmlContextData *, WriteFlags flags = 0); + QQmlContextData *, QQmlPropertyData::WriteFlags flags = 0); static void findAliasTarget(QObject *, int, QObject **, int *); enum BindingFlag { @@ -116,7 +109,7 @@ public: }; Q_DECLARE_FLAGS(BindingFlags, BindingFlag) - static void setBinding(QQmlAbstractBinding *binding, BindingFlags flags = None, WriteFlags writeFlags = DontRemoveBinding); + static void setBinding(QQmlAbstractBinding *binding, BindingFlags flags = None, QQmlPropertyData::WriteFlags writeFlags = QQmlPropertyData::DontRemoveBinding); static void removeBinding(const QQmlProperty &that); static void removeBinding(QObject *o, int index); @@ -144,7 +137,7 @@ public: QQmlBoundSignalExpression *); static void takeSignalExpression(const QQmlProperty &that, QQmlBoundSignalExpression *); - static bool write(const QQmlProperty &that, const QVariant &, WriteFlags); + static bool write(const QQmlProperty &that, const QVariant &, QQmlPropertyData::WriteFlags); static int valueTypeCoreIndex(const QQmlProperty &that); static int bindingIndex(const QQmlProperty &that); static int bindingIndex(const QQmlPropertyData &that); @@ -157,7 +150,6 @@ public: static QVariant resolvedUrlSequence(const QVariant &value, QQmlContextData *context); }; -Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyPrivate::WriteFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyPrivate::BindingFlags) QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index baba5347a7..ad6db9756f 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -61,6 +61,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -228,6 +229,13 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyRawData::Flags) class QQmlPropertyData : public QQmlPropertyRawData { public: + enum WriteFlag { + BypassInterceptor = 0x01, + DontRemoveBinding = 0x02, + RemoveBindingOnAliasWrite = 0x04 + }; + Q_DECLARE_FLAGS(WriteFlags, WriteFlag) + inline QQmlPropertyData(); inline QQmlPropertyData(const QQmlPropertyRawData &); @@ -241,6 +249,33 @@ public: void markAsOverrideOf(QQmlPropertyData *predecessor); + inline void readProperty(QObject *target, void *property) const + { + void *args[] = { property, 0 }; + readPropertyWithArgs(target, args); + } + + inline void readPropertyWithArgs(QObject *target, void *args[]) const + { + if (hasAccessors()) { + accessors->read(target, args[0]); + } else { + QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, args); + } + } + + bool writeProperty(QObject *target, void *value, WriteFlags flags) const + { + if (flags.testFlag(BypassInterceptor) && hasAccessors() && accessors->write) { + accessors->write(target, value); + } else { + int status = -1; + void *argv[] = { value, 0, &status, &flags }; + QMetaObject::metacall(target, QMetaObject::WriteProperty, coreIndex, argv); + } + return true; + } + private: friend class QQmlPropertyCache; void lazyLoad(const QMetaProperty &); @@ -770,6 +805,8 @@ private: QVector> data; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyData::WriteFlags) + QT_END_NAMESPACE #endif // QQMLPROPERTYCACHE_P_H diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index 44fd47244d..8e87ec7f63 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -219,7 +219,7 @@ void QQmlValueType::read(QObject *obj, int idx) QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a); } -void QQmlValueType::write(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags) +void QQmlValueType::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags) { Q_ASSERT(gadgetPtr); int status = -1; diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index 910d39cf0a..11e1dfdb00 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -69,7 +69,7 @@ public: QQmlValueType(int userType, const QMetaObject *metaObject); ~QQmlValueType(); void read(QObject *, int); - void write(QObject *, int, QQmlPropertyPrivate::WriteFlags flags); + void write(QObject *, int, QQmlPropertyData::WriteFlags flags); QVariant value(); void setValue(const QVariant &); diff --git a/src/qml/qml/qqmlvaluetypeproxybinding.cpp b/src/qml/qml/qqmlvaluetypeproxybinding.cpp index 6858215a79..595cd01d05 100644 --- a/src/qml/qml/qqmlvaluetypeproxybinding.cpp +++ b/src/qml/qml/qqmlvaluetypeproxybinding.cpp @@ -58,7 +58,7 @@ QQmlValueTypeProxyBinding::~QQmlValueTypeProxyBinding() } } -void QQmlValueTypeProxyBinding::setEnabled(bool e, QQmlPropertyPrivate::WriteFlags flags) +void QQmlValueTypeProxyBinding::setEnabled(bool e, QQmlPropertyData::WriteFlags flags) { QQmlAbstractBinding *b = m_bindings.data(); while (b) { diff --git a/src/qml/qml/qqmlvaluetypeproxybinding_p.h b/src/qml/qml/qqmlvaluetypeproxybinding_p.h index de5acc2984..6e297bb3ea 100644 --- a/src/qml/qml/qqmlvaluetypeproxybinding_p.h +++ b/src/qml/qml/qqmlvaluetypeproxybinding_p.h @@ -63,7 +63,7 @@ public: QQmlAbstractBinding *binding(int targetPropertyIndex); void removeBindings(quint32 mask); - virtual void setEnabled(bool, QQmlPropertyPrivate::WriteFlags); + virtual void setEnabled(bool, QQmlPropertyData::WriteFlags); virtual bool isValueTypeProxy() const; protected: diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index d7f6c5b3af..d5001674ad 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -220,7 +220,7 @@ int QQmlInterceptorMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a) { if (c == QMetaObject::WriteProperty && interceptors && - !(*reinterpret_cast(a[3]) & QQmlPropertyPrivate::BypassInterceptor)) { + !(*reinterpret_cast(a[3]) & QQmlPropertyData::BypassInterceptor)) { for (QQmlPropertyValueInterceptor *vi = interceptors; vi; vi = vi->m_next) { if (vi->m_coreIndex != id) @@ -278,7 +278,7 @@ bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a) bool updated = false; if (newComponentValue != prevComponentValue) { valueProp.write(valueType, prevComponentValue); - valueType->write(object, id, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor); + valueType->write(object, id, QQmlPropertyData::DontRemoveBinding | QQmlPropertyData::BypassInterceptor); vi->write(newComponentValue); updated = true; @@ -872,7 +872,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * // Remove binding (if any) on write if(c == QMetaObject::WriteProperty) { int flags = *reinterpret_cast(a[3]); - if (flags & QQmlPropertyPrivate::RemoveBindingOnAliasWrite) { + if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) { QQmlData *targetData = QQmlData::get(target); if (targetData && targetData->hasBindingBit(coreIndex)) QQmlPropertyPrivate::removeBinding(target, aliasData->encodedMetaPropertyIndex); -- cgit v1.2.3