aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-06-20 14:57:10 +1000
committerAaron Kennedy <aaron.kennedy@nokia.com>2011-06-20 14:57:10 +1000
commitf60a61157cb361e19c50eb53391f18b82990a026 (patch)
treea357cc0c308c5ba922fb5c24760c8b5d20e5c32e /src
parent4266185d161be64926f43ed70b6ed2090fca17f1 (diff)
Optimize common binding writes
Diffstat (limited to 'src')
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp54
-rw-r--r--src/declarative/qml/qdeclarativebinding_p_p.h3
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp89
-rw-r--r--src/declarative/qml/qdeclarativeproperty_p.h7
-rw-r--r--src/declarative/qml/v8/qv8bindings.cpp4
5 files changed, 98 insertions, 59 deletions
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<v8::Value> 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<QList<QObject *> >());
- } 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<QVariant>()) {
- 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<v8::Value> 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 <QStringList>
#include <QtCore/qdebug.h>
@@ -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<v8::Value> 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<QList<QObject *> >());
+ } 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<QVariant>()) {
+ 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<v8::Value> 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 <private/qv8_p.h>
#include <private/qdeclarativebinding_p.h>
#include <private/qdeclarativecompiler_p.h>
+#include <private/qdeclarativeproperty_p.h>
#include <private/qdeclarativebinding_p_p.h>
#include <private/qdeclarativeexpression_p.h>
#include <private/qobject_p.h>
@@ -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()) {