aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlmodels/qqmllistmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmlmodels/qqmllistmodel.cpp')
-rw-r--r--src/qmlmodels/qqmllistmodel.cpp137
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) {