Remove the last v8 dependency from the delegate model
authorLars Knoll <lars.knoll@digia.com>
Fri, 7 Jun 2013 11:10:29 +0000 (13:10 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Fri, 7 Jun 2013 17:12:39 +0000 (19:12 +0200)
Don't use a qv8objectresource for the items anymore.

Change-Id: I5aadd58bf432e0a8984234c03a369aaea92c5f9e
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/qml/v8/qv8engine.cpp
src/qml/types/qqmldelegatemodel.cpp
src/qml/types/qqmldelegatemodel_p_p.h
src/qml/util/qqmladaptormodel.cpp

index c4e6ee7..cd1d48e 100644 (file)
@@ -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:
index bf4a5f6..7e9585c 100644 (file)
@@ -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<DelegateModelGroupFunction *>(that);
-        QQmlDelegateModelItem *cacheItem = v8_resource_cast<QQmlDelegateModelItem>(v8::Handle<v8::Object>(thisObject));
-        if (!cacheItem)
+        QQmlDelegateModelItemObject *o = thisObject.as<QQmlDelegateModelItemObject>();
+        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<QQmlDelegateModelItem>(v8::Handle<v8::Object>(ctx->thisObject));
-    if (!cacheItem)
+    QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
+    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<QQmlDelegateModelItem>(v8::Handle<v8::Object>(ctx->thisObject));
-    if (!cacheItem)
+    QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
+    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<QQmlDelegateModelItem>(v8::Handle<v8::Object>(ctx->thisObject));
-    if (!cacheItem)
+    QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
+    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<QQmlDelegateModelItemObject *>(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<v8::Object> 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<QQmlDelegateModelItem>(v8::Handle<v8::Object>(value));
-        if (QQmlDelegateModelPrivate *model = cacheItem && cacheItem->metaType->model
+    } else if (QQmlDelegateModelItemObject *object = value.as<QQmlDelegateModelItemObject>()) {
+        QQmlDelegateModelItem * const cacheItem = object->item;
+        if (QQmlDelegateModelPrivate *model = cacheItem->metaType->model
                 ? QQmlDelegateModelPrivate::get(cacheItem->metaType->model)
                 : 0) {
             *index = model->m_cache.indexOf(cacheItem);
index d2ba84c..4e1adf1 100644 (file)
@@ -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
index bf93c78..96a780f 100644 (file)
@@ -65,11 +65,11 @@ V8_DEFINE_EXTENSION(QQmlAdaptorModelEngineData, engineData)
 
 static QV4::Value get_index(QV4::SimpleCallContext *ctx)
 {
-    QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(ctx->thisObject);
-    if (!data)
+    QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
+    if (!o)
         ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
 
-    return QV4::Value::fromInt32(data->index);
+    return QV4::Value::fromInt32(o->item->index);
 }
 
 template <typename T, typename M> 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<QQmlDelegateModelItem>(ctx->thisObject);
-        if (!data)
+        QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
+        if (!o)
             ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
 
-        const QQmlAdaptorModel *const model = static_cast<QQmlDMCachedModelData *>(data)->type->model;
-        if (data->index >= 0 && *model) {
+        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(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<QQmlDelegateModelItem>(ctx->thisObject);
-    if (!data)
+    QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
+    if (!o)
         ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
 
-    QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(data);
-    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 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<QQmlDelegateModelItem>(ctx->thisObject);
-    if (!data)
+    QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
+    if (!o)
         ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
     if (!ctx->argumentCount)
         ctx->throwTypeError();
 
-    if (data->index == -1) {
-        QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(data);
+    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(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<v8::Object>(data)->SetExternalResource(this);
         ++scriptRef;
         return data;
     }
@@ -581,32 +580,30 @@ public:
 
     static QV4::Value get_modelData(QV4::SimpleCallContext *ctx)
     {
-        QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(ctx->thisObject);
-        if (!data)
+        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 QV4::Value set_modelData(QV4::SimpleCallContext *ctx)
     {
-        QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(ctx->thisObject);
-        if (!data)
+        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(ctx->arguments[0], QVariant::Invalid));
+        static_cast<QQmlDMListAccessorData *>(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<v8::Object>(val)->SetExternalResource(this);
         ++scriptRef;
         return val;
     }