From: Andrew den Exter Date: Tue, 10 Jul 2012 05:24:59 +0000 (+1000) Subject: Add a static object template for variant list model types. X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=231e73b400fdc7eae84cb8beaf246617dcf8557e;p=konrad%2Fqtdeclarative.git Add a static object template for variant list model types. Also cache any reused strings so a copy isn't created per model. Change-Id: I32f6685df8c1ecc965c9dd7192fa9972655f0ce4 Reviewed-by: Chris Adams --- diff --git a/src/quick/items/qquickvisualadaptormodel.cpp b/src/quick/items/qquickvisualadaptormodel.cpp index f298346..f7cd3e2 100644 --- a/src/quick/items/qquickvisualadaptormodel.cpp +++ b/src/quick/items/qquickvisualadaptormodel.cpp @@ -44,9 +44,42 @@ #include #include +#include QT_BEGIN_NAMESPACE +class QQuickVisualAdaptorModelEngineData : public QV8Engine::Deletable +{ +public: + enum + { + Index, + ModelData, + HasModelChildren, + StringCount + }; + + QQuickVisualAdaptorModelEngineData(QV8Engine *engine); + ~QQuickVisualAdaptorModelEngineData(); + + v8::Local index() { return strings->Get(Index)->ToString(); } + v8::Local modelData() { return strings->Get(ModelData)->ToString(); } + v8::Local hasModelChildren() { return strings->Get(HasModelChildren)->ToString(); } + + v8::Persistent constructorListItem; + v8::Persistent strings; +}; + +V8_DEFINE_EXTENSION(QQuickVisualAdaptorModelEngineData, engineData) + +static v8::Handle get_index(v8::Local, const v8::AccessorInfo &info) +{ + QQuickVisualDataModelItem *data = v8_resource_cast(info.This()); + V8ASSERT_TYPE(data, "Not a valid VisualData object"); + + return v8::Int32::New(data->index); +} + template static void setModelDataType(QMetaObjectBuilder *builder, M *metaType) { builder->setFlags(QMetaObjectBuilder::DynamicMetaObject); @@ -64,22 +97,6 @@ static void addProperty(QMetaObjectBuilder *builder, int propertyId, const QByte property.setWritable(true); } -static v8::Handle get_index(v8::Local, const v8::AccessorInfo &info) -{ - QQuickVisualDataModelItem *data = v8_resource_cast(info.This()); - V8ASSERT_TYPE(data, "Not a valid VisualData object"); - - return v8::Int32::New(data->index); -} - -static v8::Local createConstructor() -{ - v8::Local constructor = v8::ObjectTemplate::New(); - constructor->SetHasExternalResource(true); - constructor->SetAccessor(v8::String::New("index"), get_index); - return constructor; -} - class VDMModelDelegateDataType; class QQuickVDMCachedModelData : public QQuickVisualDataModelItem @@ -188,9 +205,11 @@ public: dataType->watchedRoles += newRoles; } - void initializeConstructor() + void initializeConstructor(QQuickVisualAdaptorModelEngineData *const data) { - constructor = qPersistentNew(createConstructor()); + constructor = qPersistentNew(v8::ObjectTemplate::New()); + constructor->SetHasExternalResource(true); + constructor->SetAccessor(data->index(), get_index); typedef QHash::const_iterator iterator; for (iterator it = roleNames.constBegin(), end = roleNames.constEnd(); it != end; ++it) { @@ -394,10 +413,11 @@ public: v8::Handle get() { if (type->constructor.IsEmpty()) { + QQuickVisualAdaptorModelEngineData * const data = engineData(engine); v8::HandleScope handleScope; v8::Context::Scope contextScope(engine->context()); - type->initializeConstructor(); - type->constructor->SetAccessor(v8::String::New("hasModelChildren"), get_hasModelChildren); + type->initializeConstructor(data); + type->constructor->SetAccessor(data->hasModelChildren(), get_hasModelChildren); } v8::Local data = type->constructor->NewInstance(); data->SetExternalResource(this); @@ -556,7 +576,7 @@ public: if (type->constructor.IsEmpty()) { v8::HandleScope handleScope; v8::Context::Scope contextScope(engine->context()); - type->initializeConstructor(); + type->initializeConstructor(engineData(engine)); } v8::Local data = type->constructor->NewInstance(); data->SetExternalResource(this); @@ -685,7 +705,7 @@ public: return data->engine->fromVariant(static_cast(data)->cachedData); } - static void set_modelData(v8::Local, const v8::Handle &value, const v8::AccessorInfo &info) + static void set_modelData(v8::Local, v8::Local value, const v8::AccessorInfo &info) { QQuickVisualDataModelItem *data = v8_resource_cast(info.This()); V8ASSERT_TYPE_SETTER(data, "Not a valid VisualData object"); @@ -694,6 +714,14 @@ public: data->engine->toVariant(value, QVariant::Invalid)); } + v8::Handle get() + { + v8::Local data = engineData(engine)->constructorListItem->NewInstance(); + data->SetExternalResource(this); + ++scriptRef; + return data; + } + void setValue(const QString &role, const QVariant &value) { if (role == QLatin1String("modelData")) @@ -713,6 +741,7 @@ public: } } + Q_SIGNALS: void modelDataChanged(); @@ -1026,6 +1055,29 @@ void QQuickVisualAdaptorModel::objectDestroyed(QObject *) setModel(QVariant(), 0, 0); } +QQuickVisualAdaptorModelEngineData::QQuickVisualAdaptorModelEngineData(QV8Engine *) +{ + strings = qPersistentNew(v8::Array::New(StringCount)); + strings->Set(Index, v8::String::New("index")); + strings->Set(ModelData, v8::String::New("modelData")); + strings->Set(HasModelChildren, v8::String::New("hasModelChildren")); + + v8::Local listItem = v8::FunctionTemplate::New(); + listItem->InstanceTemplate()->SetHasExternalResource(true); + listItem->InstanceTemplate()->SetAccessor(index(), get_index); + listItem->InstanceTemplate()->SetAccessor( + modelData(), + QQuickVDMListAccessorData::get_modelData, + QQuickVDMListAccessorData::set_modelData); + constructorListItem = qPersistentNew(listItem->GetFunction()); +} + +QQuickVisualAdaptorModelEngineData::~QQuickVisualAdaptorModelEngineData() +{ + qPersistentDispose(constructorListItem); + qPersistentDispose(strings); +} + QT_END_NAMESPACE QML_DECLARE_TYPE(QListModelInterface)