From f60a61157cb361e19c50eb53391f18b82990a026 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 20 Jun 2011 14:57:10 +1000 Subject: Optimize common binding writes --- src/declarative/qml/qdeclarativebinding.cpp | 54 +--------------- src/declarative/qml/qdeclarativebinding_p_p.h | 3 - src/declarative/qml/qdeclarativeproperty.cpp | 89 ++++++++++++++++++++++++++- src/declarative/qml/qdeclarativeproperty_p.h | 7 ++- src/declarative/qml/v8/qv8bindings.cpp | 4 +- 5 files changed, 98 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index fee55545cf..684726d346 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -335,57 +335,6 @@ public: } }; -bool QDeclarativeBindingPrivate::writeBindingResult(QDeclarativeJavaScriptExpression *expression, - QDeclarativeProperty &prop, v8::Handle result, - bool isUndefined, QDeclarativePropertyPrivate::WriteFlags flags) -{ - QV8Engine *engine = QDeclarativeEnginePrivate::getV8Engine(expression->context()->engine); - QDeclarativeDeleteWatcher watcher(expression); - - QVariant value; - - if (isUndefined) { - } else if (prop.propertyTypeCategory() == QDeclarativeProperty::List) { - value = engine->toVariant(result, qMetaTypeId >()); - } else if (result->IsNull() && prop.propertyTypeCategory() == QDeclarativeProperty::Object) { - value = QVariant::fromValue((QObject *)0); - } else { - value = engine->toVariant(result, prop.propertyType()); - } - - if (expression->error.isValid()) { - return false; - } else if (isUndefined && prop.isResettable()) { - prop.reset(); - } else if (isUndefined && prop.propertyType() == qMetaTypeId()) { - QDeclarativePropertyPrivate::write(prop, QVariant(), flags); - } else if (isUndefined) { - expression->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + - QLatin1String(QMetaType::typeName(prop.propertyType())) + - QLatin1String(" ") + prop.name()); - return false; - } else if (result->IsFunction()) { - expression->error.setDescription(QLatin1String("Unable to assign a function to a property.")); - return false; - } else if (prop.object() && !QDeclarativePropertyPrivate::write(prop, value, flags)) { - - if (watcher.wasDeleted()) - return true; - - const char *valueType = 0; - if (value.userType() == QVariant::Invalid) valueType = "null"; - else valueType = QMetaType::typeName(value.userType()); - - expression->error.setDescription(QLatin1String("Unable to assign ") + - QLatin1String(valueType) + - QLatin1String(" to ") + - QLatin1String(QMetaType::typeName(prop.propertyType()))); - return false; - } - - return true; -} - void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) { Q_D(QDeclarativeBinding); @@ -423,7 +372,8 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) bool needsErrorData = false; if (!watcher.wasDeleted() && !d->error.isValid()) - needsErrorData = !d->writeBindingResult(d, d->property, result, isUndefined, flags); + needsErrorData = !QDeclarativePropertyPrivate::writeBinding(d->property, d, result, + isUndefined, flags); if (!watcher.wasDeleted()) { diff --git a/src/declarative/qml/qdeclarativebinding_p_p.h b/src/declarative/qml/qdeclarativebinding_p_p.h index 6caf13635f..dc7ec074c8 100644 --- a/src/declarative/qml/qdeclarativebinding_p_p.h +++ b/src/declarative/qml/qdeclarativebinding_p_p.h @@ -69,9 +69,6 @@ public: virtual void emitValueChanged(); - static bool writeBindingResult(QDeclarativeJavaScriptExpression *expression, - QDeclarativeProperty &prop, v8::Handle value, bool isUndefined, - QDeclarativePropertyPrivate::WriteFlags flags); static void printBindingLoopError(QDeclarativeProperty &prop); protected: diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index 71bc748be9..ba108e3f43 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -54,6 +54,7 @@ #include "private/qdeclarativelist_p.h" #include "private/qdeclarativecompiler_p.h" #include "private/qdeclarativevmemetaobject_p.h" +#include "private/qdeclarativeexpression_p.h" #include #include @@ -1246,6 +1247,92 @@ bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePrope return true; } +// Returns true if successful, false if an error description was set on expression +bool QDeclarativePropertyPrivate::writeBinding(const QDeclarativeProperty &that, + QDeclarativeJavaScriptExpression *expression, + v8::Handle result, bool isUndefined, + WriteFlags flags) +{ + QV8Engine *engine = QDeclarativeEnginePrivate::getV8Engine(expression->context()->engine); + + QDeclarativePropertyPrivate *pp = that.d; + + if (!pp) + return true; + + QObject *object = that.object(); + int type = that.propertyType(); + +#define QUICK_STORE(cpptype, metatype, test, conversion) \ + case QMetaType:: metatype: \ + if (test) { \ + cpptype o = (conversion); \ + int status = -1; \ + void *argv[] = { &o, 0, &status, &flags }; \ + QMetaObject::metacall(object, QMetaObject::WriteProperty, pp->core.coreIndex, argv); \ + return true; \ + } \ + break; + + + if (object && pp->valueType.valueTypeCoreIdx == -1) { + switch (type) { + QUICK_STORE(int, Int, result->IsNumber(), result->Int32Value()); + QUICK_STORE(double, Double, result->IsNumber(), result->NumberValue()); + QUICK_STORE(float, Float, result->IsNumber(), result->NumberValue()); + QUICK_STORE(QString, QString, result->IsString(), engine->toString(result)); + default: + break; + } + } +#undef QUICK_STORE + + QDeclarativeDeleteWatcher watcher(expression); + + QVariant value; + + if (isUndefined) { + } else if (that.propertyTypeCategory() == QDeclarativeProperty::List) { + value = engine->toVariant(result, qMetaTypeId >()); + } else if (result->IsNull() && that.propertyTypeCategory() == QDeclarativeProperty::Object) { + value = QVariant::fromValue((QObject *)0); + } else { + value = engine->toVariant(result, type); + } + + if (expression->error.isValid()) { + return false; + } else if (isUndefined && that.isResettable()) { + that.reset(); + } else if (isUndefined && type == qMetaTypeId()) { + QDeclarativePropertyPrivate::write(that, QVariant(), flags); + } else if (isUndefined) { + expression->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + + QLatin1String(QMetaType::typeName(type)) + + QLatin1String(" ") + that.name()); + return false; + } else if (result->IsFunction()) { + expression->error.setDescription(QLatin1String("Unable to assign a function to a property.")); + return false; + } else if (object && !QDeclarativePropertyPrivate::write(that, value, flags)) { + + if (watcher.wasDeleted()) + return true; + + const char *valueType = 0; + if (value.userType() == QVariant::Invalid) valueType = "null"; + else valueType = QMetaType::typeName(value.userType()); + + expression->error.setDescription(QLatin1String("Unable to assign ") + + QLatin1String(valueType) + + QLatin1String(" to ") + + QLatin1String(QMetaType::typeName(type))); + return false; + } + + return true; +} + const QMetaObject *QDeclarativePropertyPrivate::rawMetaObjectForType(QDeclarativeEnginePrivate *engine, int userType) { if (engine) { @@ -1335,7 +1422,7 @@ bool QDeclarativeProperty::reset() const } bool QDeclarativePropertyPrivate::write(const QDeclarativeProperty &that, - const QVariant &value, WriteFlags flags) + const QVariant &value, WriteFlags flags) { if (!that.d) return false; diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h index 4f53adb71c..efebf0ca48 100644 --- a/src/declarative/qml/qdeclarativeproperty_p.h +++ b/src/declarative/qml/qdeclarativeproperty_p.h @@ -63,8 +63,9 @@ QT_BEGIN_NAMESPACE class QDeclarativeContext; -class QDeclarativeEnginePrivate; class QDeclarativeExpression; +class QDeclarativeEnginePrivate; +class QDeclarativeJavaScriptExpression; class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativePropertyPrivate : public QDeclarativeRefCount { public: @@ -131,6 +132,10 @@ public: static QDeclarativeExpression *setSignalExpression(const QDeclarativeProperty &that, QDeclarativeExpression *) ; static bool write(const QDeclarativeProperty &that, const QVariant &, WriteFlags); + static bool writeBinding(const QDeclarativeProperty &that, + QDeclarativeJavaScriptExpression *expression, + v8::Handle result, bool isUndefined, + WriteFlags flags); static int valueTypeCoreIndex(const QDeclarativeProperty &that); static int bindingIndex(const QDeclarativeProperty &that); static QMetaMethod findSignalByName(const QMetaObject *mo, const QByteArray &); diff --git a/src/declarative/qml/v8/qv8bindings.cpp b/src/declarative/qml/v8/qv8bindings.cpp index 49cc00ca68..2e901a5a19 100644 --- a/src/declarative/qml/v8/qv8bindings.cpp +++ b/src/declarative/qml/v8/qv8bindings.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -123,8 +124,7 @@ void QV8BindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags bool needsErrorData = false; if (!watcher.wasDeleted() && !error.isValid()) - needsErrorData = !QDeclarativeBindingPrivate::writeBindingResult(this, property, result, - isUndefined, flags); + needsErrorData = !QDeclarativePropertyPrivate::writeBinding(property, this, result, isUndefined, flags); if (!watcher.wasDeleted()) { -- cgit v1.2.3