diff options
author | Chris Adams <christopher.adams@nokia.com> | 2011-08-02 10:04:16 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-08-02 08:50:21 +0200 |
commit | 0db6db0263defcd6ff84769b7d927d5a51606f6c (patch) | |
tree | ec30dca485b9cf576a70d4b232d6525f3d569c90 /src/declarative/qml/v8 | |
parent | 29e71ca376f48bafc2105b656a702f3edd4501a8 (diff) |
Add support for comparing value-type properties
This commit allows value-types to be compared with each other and
with variants. It also adds a toString() function for each value
type, to allow conversion to (and comparison with) string.
Task-number: QTBUG-14731
Change-Id: I5bde2820917b2fe19b581724977398680617de34
Reviewed-on: http://codereview.qt.nokia.com/1636
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src/declarative/qml/v8')
-rw-r--r-- | src/declarative/qml/v8/qv8engine.cpp | 13 | ||||
-rw-r--r-- | src/declarative/qml/v8/qv8engine_p.h | 1 | ||||
-rw-r--r-- | src/declarative/qml/v8/qv8valuetypewrapper.cpp | 63 | ||||
-rw-r--r-- | src/declarative/qml/v8/qv8valuetypewrapper_p.h | 6 |
4 files changed, 82 insertions, 1 deletions
diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp index acbfb92b15..a538109c2c 100644 --- a/src/declarative/qml/v8/qv8engine.cpp +++ b/src/declarative/qml/v8/qv8engine.cpp @@ -42,6 +42,7 @@ #include "qv8engine_p.h" #include "qv8contextwrapper_p.h" +#include "qv8valuetypewrapper_p.h" #include "qv8include_p.h" #include "../../../3rdparty/javascriptcore/DateMath.h" @@ -87,10 +88,20 @@ static bool ObjectComparisonCallback(v8::Local<v8::Object> lhs, v8::Local<v8::Ob QV8ObjectResource::ResourceType rhst = rhsr->resourceType(); switch (lhst) { + case QV8ObjectResource::ValueTypeType: + if (rhst == QV8ObjectResource::ValueTypeType) { + return lhsr->engine->valueTypeWrapper()->isEqual(lhsr, lhsr->engine->valueTypeWrapper()->toVariant(rhsr)); + } else if (rhst == QV8ObjectResource::VariantType) { + return lhsr->engine->valueTypeWrapper()->isEqual(lhsr, lhsr->engine->variantWrapper()->toVariant(rhsr)); + } + break; case QV8ObjectResource::VariantType: - if (rhst == QV8ObjectResource::VariantType) + if (rhst == QV8ObjectResource::VariantType) { return lhsr->engine->variantWrapper()->toVariant(lhsr) == lhsr->engine->variantWrapper()->toVariant(rhsr); + } else if (rhst == QV8ObjectResource::ValueTypeType) { + return rhsr->engine->valueTypeWrapper()->isEqual(rhsr, rhsr->engine->variantWrapper()->toVariant(lhsr)); + } break; default: break; diff --git a/src/declarative/qml/v8/qv8engine_p.h b/src/declarative/qml/v8/qv8engine_p.h index b95e55002b..938454c901 100644 --- a/src/declarative/qml/v8/qv8engine_p.h +++ b/src/declarative/qml/v8/qv8engine_p.h @@ -265,6 +265,7 @@ public: QV8TypeWrapper *typeWrapper() { return &m_typeWrapper; } QV8ListWrapper *listWrapper() { return &m_listWrapper; } QV8VariantWrapper *variantWrapper() { return &m_variantWrapper; } + QV8ValueTypeWrapper *valueTypeWrapper() { return &m_valueTypeWrapper; } void *xmlHttpRequestData() { return m_xmlHttpRequestData; } void *sqlDatabaseData() { return m_sqlDatabaseData; } diff --git a/src/declarative/qml/v8/qv8valuetypewrapper.cpp b/src/declarative/qml/v8/qv8valuetypewrapper.cpp index f3100cf7b5..a55626061d 100644 --- a/src/declarative/qml/v8/qv8valuetypewrapper.cpp +++ b/src/declarative/qml/v8/qv8valuetypewrapper.cpp @@ -103,15 +103,21 @@ QV8ValueTypeWrapper::~QV8ValueTypeWrapper() void QV8ValueTypeWrapper::destroy() { + qPersistentDispose(m_toString); qPersistentDispose(m_constructor); } void QV8ValueTypeWrapper::init(QV8Engine *engine) { m_engine = engine; + m_toString = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ToString)->GetFunction()); v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); ft->InstanceTemplate()->SetNamedPropertyHandler(Getter, Setter); ft->InstanceTemplate()->SetHasExternalResource(true); + ft->InstanceTemplate()->MarkAsUseUserObjectComparison(); + ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0, + m_toString, v8::DEFAULT, + v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); m_constructor = qPersistentNew<v8::Function>(ft->GetFunction()); } @@ -166,6 +172,59 @@ QVariant QV8ValueTypeWrapper::toVariant(QV8ObjectResource *r) } } +bool QV8ValueTypeWrapper::isEqual(QV8ObjectResource *r, const QVariant& value) +{ + Q_ASSERT(r->resourceType() == QV8ObjectResource::ValueTypeType); + QV8ValueTypeResource *resource = static_cast<QV8ValueTypeResource *>(r); + + if (resource->objectType == QV8ValueTypeResource::Reference) { + QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource); + if (reference->object) { + reference->type->read(reference->object, reference->property); + return reference->type->isEqual(value); + } else { + return false; + } + } else { + Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy); + QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource); + return (value == copy->value); + } +} + +v8::Handle<v8::Value> QV8ValueTypeWrapper::ToStringGetter(v8::Local<v8::String> property, + const v8::AccessorInfo &info) +{ + Q_UNUSED(property); + return info.Data(); +} + +v8::Handle<v8::Value> QV8ValueTypeWrapper::ToString(const v8::Arguments &args) +{ + QV8ValueTypeResource *resource = v8_resource_cast<QV8ValueTypeResource>(args.This()); + if (resource) { + if (resource->objectType == QV8ValueTypeResource::Reference) { + QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource); + if (reference->object) { + reference->type->read(reference->object, reference->property); + return resource->engine->toString(resource->type->toString()); + } else { + return v8::Undefined(); + } + } else { + Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy); + QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource); + QString result = copy->value.toString(); + if (result.isEmpty() && !copy->value.canConvert(QVariant::String)) { + result = QString::fromLatin1("QVariant(%0)").arg(QString::fromLatin1(copy->value.typeName())); + } + return resource->engine->toString(result); + } + } else { + return v8::Undefined(); + } +} + v8::Handle<v8::Value> QV8ValueTypeWrapper::Getter(v8::Local<v8::String> property, const v8::AccessorInfo &info) { @@ -177,6 +236,10 @@ v8::Handle<v8::Value> QV8ValueTypeWrapper::Getter(v8::Local<v8::String> property // We should probably just replace all value properties with dedicated accessors. QByteArray propName = r->engine->toString(property).toUtf8(); + if (propName == QByteArray("toString")) { + return r->engine->valueTypeWrapper()->m_toString; + } + int index = r->type->metaObject()->indexOfProperty(propName.constData()); if (index == -1) return v8::Undefined(); diff --git a/src/declarative/qml/v8/qv8valuetypewrapper_p.h b/src/declarative/qml/v8/qv8valuetypewrapper_p.h index d08d89392c..2582560c0f 100644 --- a/src/declarative/qml/v8/qv8valuetypewrapper_p.h +++ b/src/declarative/qml/v8/qv8valuetypewrapper_p.h @@ -77,7 +77,12 @@ public: QVariant toVariant(v8::Handle<v8::Object>); QVariant toVariant(QV8ObjectResource *); + static bool isEqual(QV8ObjectResource *, const QVariant& value); + private: + static v8::Handle<v8::Value> ToStringGetter(v8::Local<v8::String> property, + const v8::AccessorInfo &info); + static v8::Handle<v8::Value> ToString(const v8::Arguments &args); static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, const v8::AccessorInfo &info); static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property, @@ -86,6 +91,7 @@ private: QV8Engine *m_engine; v8::Persistent<v8::Function> m_constructor; + v8::Persistent<v8::Function> m_toString; }; QT_END_NAMESPACE |