diff options
author | Chris Adams <christopher.adams@nokia.com> | 2012-07-16 16:32:49 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-08-09 07:58:06 +0200 |
commit | 42f9444e983b5257241c17242471ca63f208c3f6 (patch) | |
tree | 4847ae743a0e05b0ff9d3d4ab6003ea257a6c682 /src/qml/qml/v8/qv8qobjectwrapper.cpp | |
parent | f09517bd9c907698a05ee92ccf158a06db3340b8 (diff) |
Allow invokable functions of value-type classes to be called
Previously, invokable functions of value-type classes were returned as
properties. This commit fixes that bug by allowing such functions to
be invoked normally. It also improves copy-value type handling.
This commit also ensures that QMatrix4x4 value types are constructed
with qreal values as this is the storage type used internally.
Change-Id: Iab0fe4c522ed53d60154e8a8d46dda925fb9f4de
Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src/qml/qml/v8/qv8qobjectwrapper.cpp')
-rw-r--r-- | src/qml/qml/v8/qv8qobjectwrapper.cpp | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index 01ab252d7b..bee176f829 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -1552,16 +1552,29 @@ static v8::Handle<v8::Value> CallMethod(QObject *object, int index, int returnTy { if (argCount > 0) { + // Special handling is required for value types. + // We need to save the current value in a temporary, + // and reapply it after converting all arguments. + // This avoids the "overwriting copy-value-type-value" + // problem during Q_INVOKABLE function invocation. + QQmlValueType *valueTypeObject = qobject_cast<QQmlValueType*>(object); + QVariant valueTypeValue; + if (valueTypeObject) + valueTypeValue = valueTypeObject->value(); + + // Convert all arguments. QVarLengthArray<CallArgument, 9> args(argCount + 1); args[0].initAsType(returnType); - for (int ii = 0; ii < argCount; ++ii) args[ii + 1].fromValue(argTypes[ii], engine, callArgs[ii]); - QVarLengthArray<void *, 9> argData(args.count()); for (int ii = 0; ii < args.count(); ++ii) argData[ii] = args[ii].dataPtr(); + // Reinstate saved value type object value if required. + if (valueTypeObject) + valueTypeObject->setValue(valueTypeValue); + QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, argData.data()); return args[0].toValue(engine); @@ -1664,6 +1677,11 @@ static int MatchScore(v8::Handle<v8::Value> actual, int conversionType) case QMetaType::QStringList: case QMetaType::QVariantList: return 5; + case QMetaType::QVector4D: + case QMetaType::QMatrix4x4: + return 6; + case QMetaType::QVector3D: + return 7; default: return 10; } @@ -1699,6 +1717,10 @@ static int MatchScore(v8::Handle<v8::Value> actual, int conversionType) return 0; else return 10; + } else if (r && r->resourceType() == QV8ObjectResource::ValueTypeType) { + if (r->engine->toVariant(actual, -1).userType() == conversionType) + return 0; + return 10; } else if (conversionType == QMetaType::QJsonObject) { return 5; } else { @@ -1831,6 +1853,16 @@ static v8::Handle<v8::Value> CallOverloaded(QObject *object, const QQmlPropertyD int bestParameterScore = INT_MAX; int bestMatchScore = INT_MAX; + // Special handling is required for value types. + // We need to save the current value in a temporary, + // and reapply it after converting all arguments. + // This avoids the "overwriting copy-value-type-value" + // problem during Q_INVOKABLE function invocation. + QQmlValueType *valueTypeObject = qobject_cast<QQmlValueType*>(object); + QVariant valueTypeValue; + if (valueTypeObject) + valueTypeValue = valueTypeObject->value(); + QQmlPropertyData dummy; const QQmlPropertyData *attempt = &data; @@ -1871,6 +1903,8 @@ static v8::Handle<v8::Value> CallOverloaded(QObject *object, const QQmlPropertyD } while((attempt = RelatedMethod(object, attempt, dummy)) != 0); if (best) { + if (valueTypeObject) + valueTypeObject->setValue(valueTypeValue); return CallPrecise(object, *best, engine, callArgs); } else { QString error = QLatin1String("Unable to determine callable overload. Candidates are:"); |