From d3243caf5a181855f6344c072f8dddea193d48fa Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 7 Jun 2013 13:10:29 +0200 Subject: [PATCH] Remove the last v8 dependency from the delegate model Don't use a qv8objectresource for the items anymore. Change-Id: I5aadd58bf432e0a8984234c03a369aaea92c5f9e Reviewed-by: Simon Hausmann --- src/qml/qml/v8/qv8engine.cpp | 1 - src/qml/types/qqmldelegatemodel.cpp | 64 +++++++++++++++++++------------- src/qml/types/qqmldelegatemodel_p_p.h | 21 +++++++++-- src/qml/util/qqmladaptormodel.cpp | 69 +++++++++++++++++------------------ 4 files changed, 89 insertions(+), 66 deletions(-) diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index c4e6ee7..cd1d48e 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -141,7 +141,6 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint) switch (r->resourceType()) { case QV8ObjectResource::Context2DStyleType: case QV8ObjectResource::Context2DPixelArrayType: - case QV8ObjectResource::VisualDataItemType: case QV8ObjectResource::XMLHttpRequestType: case QV8ObjectResource::DOMNodeType: case QV8ObjectResource::ParticleDataType: diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index bf4a5f6..7e9585c 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -84,12 +84,12 @@ struct DelegateModelGroupFunction: QV4::FunctionObject static QV4::Value call(QV4::Managed *that, QV4::ExecutionContext *ctx, const QV4::Value &thisObject, QV4::Value *args, int argc) { DelegateModelGroupFunction *f = static_cast(that); - QQmlDelegateModelItem *cacheItem = v8_resource_cast(v8::Handle(thisObject)); - if (!cacheItem) + QQmlDelegateModelItemObject *o = thisObject.as(); + if (!o) ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); QV4::Value v = argc ? args[0] : QV4::Value::undefinedValue(); - return f->code(cacheItem, f->flag, v); + return f->code(o->item, f->flag, v); } }; @@ -1665,44 +1665,44 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const QV4::Value QQmlDelegateModelItem::get_model(QV4::SimpleCallContext *ctx) { - QQmlDelegateModelItem *cacheItem = v8_resource_cast(v8::Handle(ctx->thisObject)); - if (!cacheItem) + QQmlDelegateModelItemObject *o = ctx->thisObject.as(); + if (!o) ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); - if (!cacheItem->metaType->model) + if (!o->item->metaType->model) return QV4::Value::undefinedValue(); - return cacheItem->get(); + return o->item->get(); } QV4::Value QQmlDelegateModelItem::get_groups(QV4::SimpleCallContext *ctx) { - QQmlDelegateModelItem *cacheItem = v8_resource_cast(v8::Handle(ctx->thisObject)); - if (!cacheItem) + QQmlDelegateModelItemObject *o = ctx->thisObject.as(); + if (!o) ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); QStringList groups; - for (int i = 1; i < cacheItem->metaType->groupCount; ++i) { - if (cacheItem->groups & (1 << i)) - groups.append(cacheItem->metaType->groupNames.at(i - 1)); + for (int i = 1; i < o->item->metaType->groupCount; ++i) { + if (o->item->groups & (1 << i)) + groups.append(o->item->metaType->groupNames.at(i - 1)); } - return cacheItem->engine->fromVariant(groups); + return ctx->engine->v8Engine->fromVariant(groups); } QV4::Value QQmlDelegateModelItem::set_groups(QV4::SimpleCallContext *ctx) { - QQmlDelegateModelItem *cacheItem = v8_resource_cast(v8::Handle(ctx->thisObject)); - if (!cacheItem) + QQmlDelegateModelItemObject *o = ctx->thisObject.as(); + if (!o) ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); if (!ctx->argumentCount) ctx->throwTypeError(); - if (!cacheItem->metaType->model) + if (!o->item->metaType->model) return QV4::Value::undefinedValue(); - QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(cacheItem->metaType->model); + QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(o->item->metaType->model); const int groupFlags = model->m_cacheMetaType->parseGroups(ctx->arguments[0]); - const int cacheIndex = model->m_cache.indexOf(cacheItem); + const int cacheIndex = model->m_cache.indexOf(o->item); Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex); model->setGroups(it, 1, Compositor::Cache, groupFlags); return QV4::Value::undefinedValue(); @@ -1742,9 +1742,23 @@ QV4::Value QQmlDelegateModelItem::get_index(QQmlDelegateModelItem *thisItem, uin //--------------------------------------------------------------------------- +DEFINE_MANAGED_VTABLE(QQmlDelegateModelItemObject); + +QQmlDelegateModelItemObject::~QQmlDelegateModelItemObject() +{ + item->Dispose(); +} + +void QQmlDelegateModelItemObject::destroy(Managed *that) +{ + static_cast(that)->~QQmlDelegateModelItemObject(); +} + + + QQmlDelegateModelItem::QQmlDelegateModelItem( QQmlDelegateModelItemMetaType *metaType, int modelIndex) - : QV8ObjectResource(metaType->v8Engine) + : v4(QV8Engine::getV4(metaType->v8Engine)) , metaType(metaType) , contextData(0) , object(0) @@ -2332,13 +2346,11 @@ QQmlV4Handle QQmlDelegateModelGroup::get(int index) model->m_cacheMetaType->initializePrototype(); QV8Engine *v8 = model->m_cacheMetaType->v8Engine; QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8); - QV4::Object *o = v4->newObject(); + QV4::Object *o = new (v4->memoryManager) QQmlDelegateModelItemObject(v4, cacheItem); o->prototype = model->m_cacheMetaType->modelItemProto.value().asObject(); - v8::Handle handle = QV4::Value::fromObject(o); - handle->SetExternalResource(cacheItem); ++cacheItem->scriptRef; - return QQmlV4Handle(handle->v4Value()); + return QQmlV4Handle(QV4::Value::fromObject(o)); } bool QQmlDelegateModelGroupPrivate::parseIndex(const QV4::Value &value, int *index, Compositor::Group *group) const @@ -2346,9 +2358,9 @@ bool QQmlDelegateModelGroupPrivate::parseIndex(const QV4::Value &value, int *ind if (value.isNumber()) { *index = value.toInt32(); return true; - } else if (/*QV4::Object *object = */value.asObject()) { - QQmlDelegateModelItem * const cacheItem = v8_resource_cast(v8::Handle(value)); - if (QQmlDelegateModelPrivate *model = cacheItem && cacheItem->metaType->model + } else if (QQmlDelegateModelItemObject *object = value.as()) { + QQmlDelegateModelItem * const cacheItem = object->item; + if (QQmlDelegateModelPrivate *model = cacheItem->metaType->model ? QQmlDelegateModelPrivate::get(cacheItem->metaType->model) : 0) { *index = model->m_cache.indexOf(cacheItem); diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index d2ba84c..4e1adf1 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -91,12 +91,11 @@ public: class QQmlAdaptorModel; class QQDMIncubationTask; -class QQmlDelegateModelItem : public QObject, public QV8ObjectResource +class QQmlDelegateModelItem : public QObject { Q_OBJECT Q_PROPERTY(int index READ modelIndex NOTIFY modelIndexChanged) Q_PROPERTY(QObject *model READ modelObject CONSTANT) - V8_RESOURCE_TYPE(VisualDataItemType) public: QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType, int modelIndex); ~QQmlDelegateModelItem(); @@ -129,7 +128,7 @@ public: int modelIndex() const { return index; } void setModelIndex(int idx) { index = idx; emit modelIndexChanged(); } - virtual QV4::Value get() { return QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), this); } + virtual QV4::Value get() { return QV4::QObjectWrapper::wrap(v4, this); } virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); } virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; } @@ -141,6 +140,7 @@ public: static QV4::Value set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg); static QV4::Value get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg); + QV4::ExecutionEngine *v4; QQmlDelegateModelItemMetaType * const metaType; QQmlContextData *contextData; QObject *object; @@ -159,6 +159,21 @@ protected: void objectDestroyed(QObject *); }; +struct QQmlDelegateModelItemObject : QV4::Object +{ + Q_MANAGED; + QQmlDelegateModelItemObject(QV4::ExecutionEngine *engine, QQmlDelegateModelItem *item) + : Object(engine) + , item(item) + { vtbl = &static_vtbl; } + ~QQmlDelegateModelItemObject(); + + static void destroy(Managed *that); + + QQmlDelegateModelItem *item; +}; + + class QQmlDelegateModelPrivate; class QQDMIncubationTask : public QQmlIncubator diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp index bf93c78..96a780f 100644 --- a/src/qml/util/qqmladaptormodel.cpp +++ b/src/qml/util/qqmladaptormodel.cpp @@ -65,11 +65,11 @@ V8_DEFINE_EXTENSION(QQmlAdaptorModelEngineData, engineData) static QV4::Value get_index(QV4::SimpleCallContext *ctx) { - QQmlDelegateModelItem *data = v8_resource_cast(ctx->thisObject); - if (!data) + QQmlDelegateModelItemObject *o = ctx->thisObject.as(); + if (!o) ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); - return QV4::Value::fromInt32(data->index); + return QV4::Value::fromInt32(o->item->index); } template static void setModelDataType(QMetaObjectBuilder *builder, M *metaType) @@ -196,14 +196,14 @@ public: static QV4::Value get_hasModelChildren(QV4::SimpleCallContext *ctx) { - QQmlDelegateModelItem *data = v8_resource_cast(ctx->thisObject); - if (!data) + QQmlDelegateModelItemObject *o = ctx->thisObject.as(); + if (!o) ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); - const QQmlAdaptorModel *const model = static_cast(data)->type->model; - if (data->index >= 0 && *model) { + const QQmlAdaptorModel *const model = static_cast(o->item)->type->model; + if (o->item->index >= 0 && *model) { const QAbstractItemModel * const aim = model->aim(); - return QV4::Value::fromBoolean(aim->hasChildren(aim->index(data->index, 0, model->rootIndex))); + return QV4::Value::fromBoolean(aim->hasChildren(aim->index(o->item->index, 0, model->rootIndex))); } else { return QV4::Value::fromBoolean(false); } @@ -343,18 +343,18 @@ bool QQmlDMCachedModelData::resolveIndex(const QQmlAdaptorModel &, int idx) QV4::Value QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint propertyId) { - QQmlDelegateModelItem *data = v8_resource_cast(ctx->thisObject); - if (!data) + QQmlDelegateModelItemObject *o = ctx->thisObject.as(); + if (!o) ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); - QQmlDMCachedModelData *modelData = static_cast(data); - if (data->index == -1) { + QQmlDMCachedModelData *modelData = static_cast(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 QV4::Value::undefinedValue(); @@ -362,22 +362,22 @@ QV4::Value QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint QV4::Value QQmlDMCachedModelData::set_property(QV4::SimpleCallContext *ctx, uint propertyId) { - QQmlDelegateModelItem *data = v8_resource_cast(ctx->thisObject); - if (!data) + QQmlDelegateModelItemObject *o = ctx->thisObject.as(); + if (!o) ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); if (!ctx->argumentCount) ctx->throwTypeError(); - if (data->index == -1) { - QQmlDMCachedModelData *modelData = static_cast(data); + if (o->item->index == -1) { + QQmlDMCachedModelData *modelData = static_cast(o->item); if (!modelData->cachedData.isEmpty()) { if (modelData->cachedData.count() > 1) { - modelData->cachedData[propertyId] = data->engine->toVariant(ctx->arguments[0], 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(ctx->arguments[0], 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); } } } @@ -424,14 +424,13 @@ public: QV4::Value get() { if (type->prototype.isEmpty()) { - QQmlAdaptorModelEngineData * const data = engineData(engine); + QQmlAdaptorModelEngineData * const data = engineData(v4->v8Engine); type->initializeConstructor(data); } QV4::Object *proto = type->prototype.value().asObject(); - QV4::Object *o = proto->engine()->newObject(); + QV4::Object *o = new (proto->engine()->memoryManager) QQmlDelegateModelItemObject(proto->engine(), this); o->prototype = proto; QV4::Value data = QV4::Value::fromObject(o); - v8::Handle(data)->SetExternalResource(this); ++scriptRef; return data; } @@ -581,32 +580,30 @@ public: static QV4::Value get_modelData(QV4::SimpleCallContext *ctx) { - QQmlDelegateModelItem *data = v8_resource_cast(ctx->thisObject); - if (!data) + QQmlDelegateModelItemObject *o = ctx->thisObject.as(); + if (!o) ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); - return data->engine->fromVariant(static_cast(data)->cachedData); + return ctx->engine->v8Engine->fromVariant(static_cast(o->item)->cachedData); } static QV4::Value set_modelData(QV4::SimpleCallContext *ctx) { - QQmlDelegateModelItem *data = v8_resource_cast(ctx->thisObject); - if (!data) + QQmlDelegateModelItemObject *o = ctx->thisObject.as(); + if (!o) ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); if (!ctx->argumentCount) ctx->throwTypeError(); - - static_cast(data)->setModelData(data->engine->toVariant(ctx->arguments[0], QVariant::Invalid)); + static_cast(o->item)->setModelData(ctx->engine->v8Engine->toVariant(ctx->arguments[0], QVariant::Invalid)); } QV4::Value get() { - QQmlAdaptorModelEngineData *data = engineData(engine); - QV4::Object *o = data->v4->newObject(); + 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); - v8::Handle(val)->SetExternalResource(this); ++scriptRef; return val; } -- 2.7.4