diff options
Diffstat (limited to 'src/qmlmodels/qqmllistmodel.cpp')
-rw-r--r-- | src/qmlmodels/qqmllistmodel.cpp | 137 |
1 files changed, 46 insertions, 91 deletions
diff --git a/src/qmlmodels/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp index 039098a80e..c060aaec97 100644 --- a/src/qmlmodels/qqmllistmodel.cpp +++ b/src/qmlmodels/qqmllistmodel.cpp @@ -129,8 +129,28 @@ const ListLayout::Role &ListLayout::getRoleOrCreate(QV4::String *key, Role::Data const ListLayout::Role &ListLayout::createRole(const QString &key, ListLayout::Role::DataType type) { - const int dataSizes[] = { sizeof(StringOrTranslation), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(ListElement::GuardedQObjectPointer), sizeof(QVariantMap), sizeof(QDateTime), sizeof(QUrl), sizeof(QJSValue) }; - const int dataAlignments[] = { alignof(StringOrTranslation), alignof(double), alignof(bool), alignof(ListModel *), alignof(QObject *), alignof(QVariantMap), alignof(QDateTime), alignof(QUrl), alignof(QJSValue) }; + const int dataSizes[] = { + sizeof(StringOrTranslation), + sizeof(double), + sizeof(bool), + sizeof(ListModel *), + sizeof(QV4::PersistentValue), + sizeof(QVariantMap), + sizeof(QDateTime), + sizeof(QUrl), + sizeof(QJSValue) + }; + const int dataAlignments[] = { + alignof(StringOrTranslation), + alignof(double), + alignof(bool), + alignof(ListModel *), + alignof(QV4::PersistentValue), + alignof(QVariantMap), + alignof(QDateTime), + alignof(QUrl), + alignof(QJSValue) + }; Role *r = new Role; r->name = key; @@ -634,10 +654,9 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles) roleIndex = e->setFunctionProperty(r, jsv); } else if (QV4::Object *o = propertyValue->as<QV4::Object>()) { if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) { - QObject *o = wrapper->object(); const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject); if (role.type == ListLayout::Role::QObject) - roleIndex = e->setQObjectProperty(role, o); + roleIndex = e->setQObjectProperty(role, wrapper); } else if (QVariant maybeUrl = o->engine()->toVariant(o->asReturnedValue(), QMetaType::fromType<QUrl>(), true); maybeUrl.metaType() == QMetaType::fromType<QUrl>()) { const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Url); @@ -725,10 +744,9 @@ void ListModel::set(int elementIndex, QV4::Object *object, ListModel::SetElement } } else if (QV4::Object *o = propertyValue->as<QV4::Object>()) { if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) { - QObject *o = wrapper->object(); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject); if (r.type == ListLayout::Role::QObject) - e->setQObjectPropertyFast(r, o); + e->setQObjectPropertyFast(r, wrapper); } else { QVariant maybeUrl = o->engine()->toVariant(o->asReturnedValue(), QMetaType::fromType<QUrl>(), true); if (maybeUrl.metaType() == QMetaType::fromType<QUrl>()) { @@ -852,12 +870,11 @@ StringOrTranslation *ListElement::getStringProperty(const ListLayout::Role &role return s; } -QObject *ListElement::getQObjectProperty(const ListLayout::Role &role) +QV4::QObjectWrapper *ListElement::getQObjectProperty(const ListLayout::Role &role) { char *mem = getPropertyMemory(role); - GuardedQObjectPointer *o - = reinterpret_cast<GuardedQObjectPointer *>(mem); - return o->data(); + QV4::PersistentValue *g = reinterpret_cast<QV4::PersistentValue *>(mem); + return g->as<QV4::QObjectWrapper>(); } QVariantMap *ListElement::getVariantMapProperty(const ListLayout::Role &role) @@ -904,13 +921,13 @@ QJSValue *ListElement::getFunctionProperty(const ListLayout::Role &role) return f; } -ListElement::GuardedQObjectPointer * +QV4::PersistentValue * ListElement::getGuardProperty(const ListLayout::Role &role) { char *mem = getPropertyMemory(role); bool existingGuard = false; - for (size_t i = 0; i < sizeof(GuardedQObjectPointer); + for (size_t i = 0; i < sizeof(QV4::PersistentValue); ++i) { if (mem[i] != 0) { existingGuard = true; @@ -918,12 +935,12 @@ ListElement::getGuardProperty(const ListLayout::Role &role) } } - GuardedQObjectPointer *o = nullptr; + QV4::PersistentValue *g = nullptr; if (existingGuard) - o = reinterpret_cast<GuardedQObjectPointer *>(mem); + g = reinterpret_cast<QV4::PersistentValue *>(mem); - return o; + return g; } ListModel *ListElement::getListProperty(const ListLayout::Role &role) @@ -979,12 +996,8 @@ QVariant ListElement::getProperty(const ListLayout::Role &role, const QQmlListMo break; case ListLayout::Role::QObject: { - GuardedQObjectPointer *guard = - reinterpret_cast<GuardedQObjectPointer *>( - mem); - QObject *object = guard->data(); - if (object) - data = QVariant::fromValue(object); + QV4::PersistentValue *guard = reinterpret_cast<QV4::PersistentValue *>(mem); + data = QVariant::fromValue(guard->as<QV4::QObjectWrapper>()->object()); } break; case ListLayout::Role::VariantMap: @@ -1096,67 +1109,17 @@ int ListElement::setListProperty(const ListLayout::Role &role, ListModel *m) return roleIndex; } -static void -restoreQObjectOwnership(ListElement::GuardedQObjectPointer *pointer) -{ - if (QObject *o = pointer->data()) { - QQmlData *data = QQmlData::get(o, false); - Q_ASSERT(data); - - // Only restore the previous state if the object hasn't become explicitly - // owned - if (!data->explicitIndestructibleSet) - data->indestructible = (pointer->tag() & ListElement::Indestructible); - } -} - -static void setQObjectOwnership(char *mem, QObject *o) -{ - QQmlData *ddata = QQmlData::get(o, false); - const int ownership = (!ddata || ddata->indestructible ? ListElement::Indestructible : 0) - | (ddata && ddata->explicitIndestructibleSet ? ListElement::ExplicitlySet : 0); - - // If ddata didn't exist above, force its creation now - if (!ddata) - ddata = QQmlData::get(o, true); - - if (!ddata->explicitIndestructibleSet) - ddata->indestructible = ownership != 0; - - new (mem) ListElement::GuardedQObjectPointer( - o, static_cast<ListElement::ObjectIndestructible>(ownership)); -} - -int ListElement::setQObjectProperty(const ListLayout::Role &role, QObject *o) +int ListElement::setQObjectProperty(const ListLayout::Role &role, QV4::QObjectWrapper *o) { int roleIndex = -1; if (role.type == ListLayout::Role::QObject) { char *mem = getPropertyMemory(role); - GuardedQObjectPointer *g = - reinterpret_cast<GuardedQObjectPointer *>(mem); - bool existingGuard = false; - for (size_t i = 0; i < sizeof(GuardedQObjectPointer); - ++i) { - if (mem[i] != 0) { - existingGuard = true; - break; - } - } - bool changed; - if (existingGuard) { - changed = g->data() != o; - if (changed) - restoreQObjectOwnership(g); - g->~GuardedQObjectPointer(); - } else { - changed = true; - } - - setQObjectOwnership(mem, o); - - if (changed) - roleIndex = role.index; + if (isMemoryUsed<QVariantMap>(mem)) + reinterpret_cast<QV4::PersistentValue *>(mem)->set(o->engine(), *o); + else + new (mem) QV4::PersistentValue(o->engine(), o); + roleIndex = role.index; } return roleIndex; @@ -1289,11 +1252,10 @@ void ListElement::setBoolPropertyFast(const ListLayout::Role &role, bool b) *value = b; } -void ListElement::setQObjectPropertyFast(const ListLayout::Role &role, QObject *o) +void ListElement::setQObjectPropertyFast(const ListLayout::Role &role, QV4::QObjectWrapper *o) { char *mem = getPropertyMemory(role); - - setQObjectOwnership(mem, o); + new (mem) QV4::PersistentValue(o->engine(), o); } void ListElement::setListPropertyFast(const ListLayout::Role &role, ListModel *m) @@ -1410,7 +1372,7 @@ QVector<int> ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElem break; case ListLayout::Role::QObject: { - QObject *object = src->getQObjectProperty(srcRole); + QV4::QObjectWrapper *object = src->getQObjectProperty(srcRole); roleIndex = target->setQObjectProperty(targetRole, object); } break; @@ -1465,14 +1427,8 @@ void ListElement::destroy(ListLayout *layout) break; case ListLayout::Role::QObject: { - GuardedQObjectPointer *guard = - getGuardProperty(r); - - if (guard) { - restoreQObjectOwnership(guard); - - guard->~GuardedQObjectPointer(); - } + if (QV4::PersistentValue *guard = getGuardProperty(r)) + guard->~PersistentValue(); } break; case ListLayout::Role::VariantMap: @@ -1609,8 +1565,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d QV4::ScopedObject o(scope, d); QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>(); if (role.type == ListLayout::Role::QObject && wrapper) { - QObject *o = wrapper->object(); - roleIndex = setQObjectProperty(role, o); + roleIndex = setQObjectProperty(role, wrapper); } else if (role.type == ListLayout::Role::VariantMap) { roleIndex = setVariantMapProperty(role, o); } else if (role.type == ListLayout::Role::Url) { |