aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-01-13 12:39:44 +0100
committerUlf Hermann <ulf.hermann@qt.io>2021-01-13 14:32:40 +0100
commitf1410debc7905e704b6ed16ae345e43765ef8ef5 (patch)
tree56c0acf733fff7bc08362b753bd7729421169709
parentcfe0b08b5439a27b4fdd14c29620e0492543f506 (diff)
Add a freeze() method to QQmlPropertyMap
After freezing a QQmlPropertyMap you cannot add any more properties, but in turn the property access is cached, and therefore faster. Task-number: QTBUG-57792 Change-Id: I2c6d768039c3b59eb2411194e463ee0de55f8bed Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/qml/qqmlopenmetaobject.cpp24
-rw-r--r--src/qml/qml/qqmlopenmetaobject_p.h7
-rw-r--r--src/qml/util/qqmlpropertymap.cpp16
-rw-r--r--src/qml/util/qqmlpropertymap.h1
-rw-r--r--tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp21
5 files changed, 60 insertions, 9 deletions
diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp
index b5264fcdfc..ec2d57013f 100644
--- a/src/qml/qml/qqmlopenmetaobject.cpp
+++ b/src/qml/qml/qqmlopenmetaobject.cpp
@@ -172,8 +172,8 @@ void QQmlOpenMetaObjectTypePrivate::init(const QMetaObject *metaObj)
class QQmlOpenMetaObjectPrivate
{
public:
- QQmlOpenMetaObjectPrivate(QQmlOpenMetaObject *_q, bool _autoCreate, QObject *obj)
- : q(_q), object(obj), autoCreate(_autoCreate) {}
+ QQmlOpenMetaObjectPrivate(QQmlOpenMetaObject *_q, QObject *obj)
+ : q(_q), object(obj) {}
struct Property {
private:
@@ -243,12 +243,12 @@ public:
QObject *object;
QQmlRefPointer<QQmlOpenMetaObjectType> type;
QVector<QByteArray> *deferredPropertyNames = nullptr;
- bool autoCreate;
+ bool autoCreate = true;
bool cacheProperties = false;
};
-QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj, const QMetaObject *base, bool automatic)
-: d(new QQmlOpenMetaObjectPrivate(this, automatic, obj))
+QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj, const QMetaObject *base)
+: d(new QQmlOpenMetaObjectPrivate(this, obj))
{
d->type.adopt(new QQmlOpenMetaObjectType(base ? base : obj->metaObject()));
d->type->d->referers.insert(this);
@@ -259,8 +259,8 @@ QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj, const QMetaObject *base, bo
op->metaObject = this;
}
-QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj, QQmlOpenMetaObjectType *type, bool automatic)
-: d(new QQmlOpenMetaObjectPrivate(this, automatic, obj))
+QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj, QQmlOpenMetaObjectType *type)
+: d(new QQmlOpenMetaObjectPrivate(this, obj))
{
d->type = type;
d->type->d->referers.insert(this);
@@ -438,6 +438,16 @@ void QQmlOpenMetaObject::setCached(bool c)
}
}
+bool QQmlOpenMetaObject::autoCreatesProperties() const
+{
+ return d->autoCreate;
+}
+
+void QQmlOpenMetaObject::setAutoCreatesProperties(bool autoCreate)
+{
+ d->autoCreate = autoCreate;
+}
+
int QQmlOpenMetaObject::createProperty(const char *name, const char *)
{
diff --git a/src/qml/qml/qqmlopenmetaobject_p.h b/src/qml/qml/qqmlopenmetaobject_p.h
index f6397c8c59..47bba085b5 100644
--- a/src/qml/qml/qqmlopenmetaobject_p.h
+++ b/src/qml/qml/qqmlopenmetaobject_p.h
@@ -93,8 +93,8 @@ class QQmlOpenMetaObjectPrivate;
class Q_QML_PRIVATE_EXPORT QQmlOpenMetaObject : public QAbstractDynamicMetaObject
{
public:
- QQmlOpenMetaObject(QObject *, const QMetaObject * = nullptr, bool = true);
- QQmlOpenMetaObject(QObject *, QQmlOpenMetaObjectType *, bool = true);
+ QQmlOpenMetaObject(QObject *, const QMetaObject * = nullptr);
+ QQmlOpenMetaObject(QObject *, QQmlOpenMetaObjectType *);
~QQmlOpenMetaObject() override;
QVariant value(const QByteArray &) const;
@@ -115,6 +115,9 @@ public:
// longer automatically called for new properties.
void setCached(bool);
+ bool autoCreatesProperties() const;
+ void setAutoCreatesProperties(bool autoCreate);
+
QQmlOpenMetaObjectType *type() const;
void emitPropertyNotification(const QByteArray &propertyName);
diff --git a/src/qml/util/qqmlpropertymap.cpp b/src/qml/util/qqmlpropertymap.cpp
index e38cf3a2a9..2bf8ab0190 100644
--- a/src/qml/util/qqmlpropertymap.cpp
+++ b/src/qml/util/qqmlpropertymap.cpp
@@ -204,6 +204,22 @@ void QQmlPropertyMap::clear(const QString &key)
}
/*!
+ \since 6.1
+
+ Disallows any further properties to be added to this property map.
+ Existing properties can be modified or cleared.
+
+ In turn, an internal cache is turned on for the existing properties, which
+ may result in faster access from QML.
+ */
+void QQmlPropertyMap::freeze()
+{
+ Q_D(QQmlPropertyMap);
+ d->mo->setAutoCreatesProperties(false);
+ d->mo->setCached(true);
+}
+
+/*!
Returns the value associated with \a key.
If no value has been set for this key (or if the value has been cleared),
diff --git a/src/qml/util/qqmlpropertymap.h b/src/qml/util/qqmlpropertymap.h
index 556754c021..de070673d7 100644
--- a/src/qml/util/qqmlpropertymap.h
+++ b/src/qml/util/qqmlpropertymap.h
@@ -62,6 +62,7 @@ public:
void insert(const QString &key, const QVariant &value);
void insert(const QVariantHash &values);
void clear(const QString &key);
+ void freeze();
Q_INVOKABLE QStringList keys() const;
diff --git a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp
index 82930b3f4a..75ef397bba 100644
--- a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp
+++ b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp
@@ -63,6 +63,7 @@ private slots:
void QTBUG_35906();
void QTBUG_48136();
void lookupsInSubTypes();
+ void freeze();
};
class LazyPropertyMap : public QQmlPropertyMap, public QQmlParserStatus
@@ -574,6 +575,26 @@ void tst_QQmlPropertyMap::lookupsInSubTypes()
QCOMPARE(object->property("newProperty").toInt(), 42);
}
+void tst_QQmlPropertyMap::freeze()
+{
+ QQmlPropertyMap map;
+
+ map.insert(QLatin1String("key1"),100);
+ map.insert(QLatin1String("key2"),200);
+ QCOMPARE(map.keys().count(), 2);
+ QVERIFY(map.contains(QLatin1String("key1")));
+ QCOMPARE(map.value(QLatin1String("key1")), QVariant(100));
+ QCOMPARE(map.value(QLatin1String("key2")), QVariant(200));
+
+ map.freeze();
+ map.insert(QLatin1String("key3"), 32);
+ QCOMPARE(map.keys().count(), 2);
+ QVERIFY(!map.contains("key3"));
+
+ map.insert(QLatin1String("key1"), QStringLiteral("Hello World"));
+ QCOMPARE(map.value("key1").toString(), QStringLiteral("Hello World"));
+}
+
QTEST_MAIN(tst_QQmlPropertyMap)
#include "tst_qqmlpropertymap.moc"