diff options
Diffstat (limited to 'src/qml/util/qqmladaptormodel.cpp')
-rw-r--r-- | src/qml/util/qqmladaptormodel.cpp | 208 |
1 files changed, 102 insertions, 106 deletions
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp index 5b6ef79338..96a780f1df 100644 --- a/src/qml/util/qqmladaptormodel.cpp +++ b/src/qml/util/qqmladaptormodel.cpp @@ -46,38 +46,30 @@ #include <private/qqmlproperty_p.h> #include <private/qv8engine_p.h> +#include <private/qv4value_p.h> +#include <private/qv4functionobject_p.h> + QT_BEGIN_NAMESPACE class QQmlAdaptorModelEngineData : public QV8Engine::Deletable { public: - enum - { - Index, - ModelData, - HasModelChildren, - StringCount - }; - QQmlAdaptorModelEngineData(QV8Engine *engine); ~QQmlAdaptorModelEngineData(); - v8::Local<v8::String> index() { return strings->Get(Index)->ToString(); } - v8::Local<v8::String> modelData() { return strings->Get(ModelData)->ToString(); } - v8::Local<v8::String> hasModelChildren() { return strings->Get(HasModelChildren)->ToString(); } - - v8::Persistent<v8::Function> constructorListItem; - v8::Persistent<v8::Array> strings; + QV4::ExecutionEngine *v4; + QV4::PersistentValue listItemProto; }; V8_DEFINE_EXTENSION(QQmlAdaptorModelEngineData, engineData) -static v8::Handle<v8::Value> get_index(v8::Local<v8::String>, const v8::AccessorInfo &info) +static QV4::Value get_index(QV4::SimpleCallContext *ctx) { - QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This()); - V8ASSERT_TYPE(data, "Not a valid VisualData object"); + QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>(); + if (!o) + ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); - return v8::Int32::New(data->index); + return QV4::Value::fromInt32(o->item->index); } template <typename T, typename M> static void setModelDataType(QMetaObjectBuilder *builder, M *metaType) @@ -115,9 +107,8 @@ public: void setValue(const QString &role, const QVariant &value); bool resolveIndex(const QQmlAdaptorModel &model, int idx); - static v8::Handle<v8::Value> get_property(v8::Local<v8::String>, const v8::AccessorInfo &info); - static void set_property( - v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info); + static QV4::Value get_property(QV4::SimpleCallContext *ctx, uint propertyId); + static QV4::Value set_property(QV4::SimpleCallContext *ctx, uint propertyId); VDMModelDelegateDataType *type; QVector<QVariant> cachedData; @@ -144,8 +135,6 @@ public: if (propertyCache) propertyCache->release(); free(metaObject); - - qPersistentDispose(constructor); } bool notify( @@ -205,23 +194,45 @@ public: dataType->watchedRoles += newRoles; } + static QV4::Value get_hasModelChildren(QV4::SimpleCallContext *ctx) + { + QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>(); + if (!o) + ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); + + const QQmlAdaptorModel *const model = static_cast<QQmlDMCachedModelData *>(o->item)->type->model; + if (o->item->index >= 0 && *model) { + const QAbstractItemModel * const aim = model->aim(); + return QV4::Value::fromBoolean(aim->hasChildren(aim->index(o->item->index, 0, model->rootIndex))); + } else { + return QV4::Value::fromBoolean(false); + } + } + + void initializeConstructor(QQmlAdaptorModelEngineData *const data) { - constructor = qPersistentNew(v8::ObjectTemplate::New()); - constructor->SetHasExternalResource(true); - constructor->SetAccessor(data->index(), get_index); + QV4::ExecutionEngine *v4 = data->v4; + QV4::Object *proto = v4->newObject(); + QV4::Property *p = proto->insertMember(v4->newString(QStringLiteral("index")), + QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable); + p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, get_index)); + + p = proto->insertMember(v4->newString(QStringLiteral("hasModelChildren")), + QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable); + p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, get_hasModelChildren)); typedef QHash<QByteArray, int>::const_iterator iterator; for (iterator it = roleNames.constBegin(), end = roleNames.constEnd(); it != end; ++it) { const int propertyId = propertyRoles.indexOf(it.value()); const QByteArray &propertyName = it.key(); - constructor->SetAccessor( - v8::String::New(propertyName.constData(), propertyName.length()), - QQmlDMCachedModelData::get_property, - QQmlDMCachedModelData::set_property, - v8::Int32::New(propertyId)); + p = proto->insertMember(v4->newString(QString::fromUtf8(propertyName)), + QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable); + p->setGetter(new (v4->memoryManager) QV4::IndexedBuiltinFunction(v4->rootContext, propertyId, QQmlDMCachedModelData::get_property)); + p->setSetter(new (v4->memoryManager) QV4::IndexedBuiltinFunction(v4->rootContext, propertyId, QQmlDMCachedModelData::set_property)); } + prototype = QV4::Value::fromObject(proto); } // QAbstractDynamicMetaObject @@ -236,7 +247,7 @@ public: return static_cast<QQmlDMCachedModelData *>(object)->metaCall(call, id, arguments); } - v8::Persistent<v8::ObjectTemplate> constructor; + QV4::PersistentValue prototype; QList<int> propertyRoles; QList<int> watchedRoleIds; QList<QByteArray> watchedRoles; @@ -330,43 +341,43 @@ bool QQmlDMCachedModelData::resolveIndex(const QQmlAdaptorModel &, int idx) } } -v8::Handle<v8::Value> QQmlDMCachedModelData::get_property( - v8::Local<v8::String>, const v8::AccessorInfo &info) +QV4::Value QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint propertyId) { - QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This()); - V8ASSERT_TYPE(data, "Not a valid VisualData object"); + QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>(); + if (!o) + ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); - QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(data); - const int propertyId = info.Data()->Int32Value(); - if (data->index == -1) { + QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->item); + if (o->item->index == -1) { if (!modelData->cachedData.isEmpty()) { - return data->engine->fromVariant( + return ctx->engine->v8Engine->fromVariant( modelData->cachedData.at(modelData->type->hasModelData ? 0 : propertyId)); } } else if (*modelData->type->model) { - return data->engine->fromVariant( + return ctx->engine->v8Engine->fromVariant( modelData->value(modelData->type->propertyRoles.at(propertyId))); } - return v8::Undefined(); + return QV4::Value::undefinedValue(); } -void QQmlDMCachedModelData::set_property( - v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info) +QV4::Value QQmlDMCachedModelData::set_property(QV4::SimpleCallContext *ctx, uint propertyId) { - QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This()); - V8ASSERT_TYPE_SETTER(data, "Not a valid VisualData object"); - - const int propertyId = info.Data()->Int32Value(); - if (data->index == -1) { - QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(data); + QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>(); + if (!o) + ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); + if (!ctx->argumentCount) + ctx->throwTypeError(); + + if (o->item->index == -1) { + QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->item); if (!modelData->cachedData.isEmpty()) { if (modelData->cachedData.count() > 1) { - modelData->cachedData[propertyId] = data->engine->toVariant(value, QVariant::Invalid); - QMetaObject::activate(data, data->metaObject(), propertyId, 0); + modelData->cachedData[propertyId] = ctx->engine->v8Engine->toVariant(ctx->arguments[0], QVariant::Invalid); + QMetaObject::activate(o->item, o->item->metaObject(), propertyId, 0); } else if (modelData->cachedData.count() == 1) { - modelData->cachedData[0] = data->engine->toVariant(value, QVariant::Invalid); - QMetaObject::activate(data, data->metaObject(), 0, 0); - QMetaObject::activate(data, data->metaObject(), 1, 0); + modelData->cachedData[0] = ctx->engine->v8Engine->toVariant(ctx->arguments[0], QVariant::Invalid); + QMetaObject::activate(o->item, o->item->metaObject(), 0, 0); + QMetaObject::activate(o->item, o->item->metaObject(), 1, 0); } } } @@ -410,34 +421,19 @@ public: type->model->aim()->index(index, 0, type->model->rootIndex), value, role); } - v8::Handle<v8::Value> get() + QV4::Value get() { - if (type->constructor.IsEmpty()) { - QQmlAdaptorModelEngineData * const data = engineData(engine); - v8::HandleScope handleScope; - v8::Context::Scope contextScope(engine->context()); + if (type->prototype.isEmpty()) { + QQmlAdaptorModelEngineData * const data = engineData(v4->v8Engine); type->initializeConstructor(data); - type->constructor->SetAccessor(data->hasModelChildren(), get_hasModelChildren); } - v8::Local<v8::Object> data = type->constructor->NewInstance(); - data->SetExternalResource(this); + QV4::Object *proto = type->prototype.value().asObject(); + QV4::Object *o = new (proto->engine()->memoryManager) QQmlDelegateModelItemObject(proto->engine(), this); + o->prototype = proto; + QV4::Value data = QV4::Value::fromObject(o); ++scriptRef; return data; } - - static v8::Handle<v8::Value> get_hasModelChildren(v8::Local<v8::String>, const v8::AccessorInfo &info) - { - QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This()); - V8ASSERT_TYPE(data, "Not a valid VisualData object"); - - const QQmlAdaptorModel *const model = static_cast<QQmlDMCachedModelData *>(data)->type->model; - if (data->index >= 0 && *model) { - const QAbstractItemModel * const aim = model->aim(); - return v8::Boolean::New(aim->hasChildren(aim->index(data->index, 0, model->rootIndex))); - } else { - return v8::Boolean::New(false); - } - } }; class VDMAbstractItemModelDataType : public VDMModelDelegateDataType @@ -582,29 +578,34 @@ public: } } - static v8::Handle<v8::Value> get_modelData(v8::Local<v8::String>, const v8::AccessorInfo &info) + static QV4::Value get_modelData(QV4::SimpleCallContext *ctx) { - QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This()); - V8ASSERT_TYPE(data, "Not a valid VisualData object"); + QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>(); + if (!o) + ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); - return data->engine->fromVariant(static_cast<QQmlDMListAccessorData *>(data)->cachedData); + return ctx->engine->v8Engine->fromVariant(static_cast<QQmlDMListAccessorData *>(o->item)->cachedData); } - static void set_modelData(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info) + static QV4::Value set_modelData(QV4::SimpleCallContext *ctx) { - QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This()); - V8ASSERT_TYPE_SETTER(data, "Not a valid VisualData object"); + QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>(); + if (!o) + ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); + if (!ctx->argumentCount) + ctx->throwTypeError(); - static_cast<QQmlDMListAccessorData *>(data)->setModelData( - data->engine->toVariant(value, QVariant::Invalid)); + static_cast<QQmlDMListAccessorData *>(o->item)->setModelData(ctx->engine->v8Engine->toVariant(ctx->arguments[0], QVariant::Invalid)); } - v8::Handle<v8::Value> get() + QV4::Value get() { - v8::Local<v8::Object> data = engineData(engine)->constructorListItem->NewInstance(); - data->SetExternalResource(this); + QQmlAdaptorModelEngineData *data = engineData(v4->v8Engine); + QV4::Object *o = new (v4->memoryManager) QQmlDelegateModelItemObject(v4, this); + o->prototype = data->listItemProto.value().asObject(); + QV4::Value val = QV4::Value::fromObject(o); ++scriptRef; - return data; + return val; } void setValue(const QString &role, const QVariant &value) @@ -949,27 +950,22 @@ void QQmlAdaptorModel::objectDestroyed(QObject *) setModel(QVariant(), 0, 0); } -QQmlAdaptorModelEngineData::QQmlAdaptorModelEngineData(QV8Engine *) +QQmlAdaptorModelEngineData::QQmlAdaptorModelEngineData(QV8Engine *e) + : v4(QV8Engine::getV4(e)) { - 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<v8::FunctionTemplate> listItem = v8::FunctionTemplate::New(); - listItem->InstanceTemplate()->SetHasExternalResource(true); - listItem->InstanceTemplate()->SetAccessor(index(), get_index); - listItem->InstanceTemplate()->SetAccessor( - modelData(), - QQmlDMListAccessorData::get_modelData, - QQmlDMListAccessorData::set_modelData); - constructorListItem = qPersistentNew(listItem->GetFunction()); + QV4::Object *proto = v4->newObject(); + QV4::Property *p = proto->insertMember(v4->newString(QStringLiteral("index")), + QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable); + p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, get_index)); + p = proto->insertMember(v4->newString(QStringLiteral("modelData")), + QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable); + p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, QQmlDMListAccessorData::get_modelData)); + p->setSetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, QQmlDMListAccessorData::set_modelData)); + listItemProto = QV4::Value::fromObject(proto); } QQmlAdaptorModelEngineData::~QQmlAdaptorModelEngineData() { - qPersistentDispose(constructorListItem); - qPersistentDispose(strings); } QT_END_NAMESPACE |