aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlpropertycache_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2019-04-02 14:29:39 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2020-06-08 19:26:40 +0200
commit6a48a81319b886c8a3f85e1eb024186b05d0f3af (patch)
treebdc7a28492e24c734f1500d5eab073760655ede4 /src/qml/qml/qqmlpropertycache_p.h
parenta8ef2c12635db3fcd46e600d3a49baa7bcaa6225 (diff)
Add a wrapper class for the meta object in the property cache
Change-Id: Ie324f0bd29ff3df5528682d3bc135a28ca1b597f Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlpropertycache_p.h')
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h60
1 files changed, 55 insertions, 5 deletions
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 86435656db..a6517cc3ff 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -77,6 +77,55 @@ class QMetaObjectBuilder;
class QQmlVMEMetaObject;
class QQmlPropertyCacheMethodArguments;
+class RefCountedMetaObject {
+public:
+ enum OwnershipMode {
+ StaticMetaObject,
+ SharedMetaObject
+ };
+
+ struct Data {
+ ~Data() { if (mode == SharedMetaObject) ::free(const_cast<QMetaObject *>(mo)); }
+ const QMetaObject *mo = nullptr;
+ int ref = 1;
+ OwnershipMode mode;
+ } *d;
+
+ RefCountedMetaObject()
+ : d(nullptr)
+ {}
+
+ RefCountedMetaObject(const QMetaObject *mo, OwnershipMode mode)
+ : d(new Data) {
+ d->mo = mo;
+ d->mode = mode;
+ }
+ ~RefCountedMetaObject() {
+ if (d && !--d->ref)
+ delete d;
+ }
+ RefCountedMetaObject(const RefCountedMetaObject &other)
+ : d(other.d)
+ {
+ if (d && d->ref > 0)
+ ++d->ref;
+ }
+ RefCountedMetaObject &operator =(const RefCountedMetaObject &other)
+ {
+ if (d == other.d)
+ return *this;
+ if (d && !--d->ref)
+ delete d;
+ d = other.d;
+ if (d && d->ref > 0)
+ ++d->ref;
+ return *this;
+ }
+ operator const QMetaObject *() const { return d ? d->mo : nullptr; }
+ const QMetaObject * operator ->() const { return d ? d->mo : nullptr; }
+ bool isShared() const { return d && d->mode == SharedMetaObject; }
+};
+
class Q_QML_PRIVATE_EXPORT QQmlPropertyCache : public QQmlRefCount
{
public:
@@ -129,7 +178,7 @@ public:
QString defaultPropertyName() const;
QQmlPropertyData *defaultProperty() const;
- QQmlPropertyCache *parent() const;
+ inline QQmlPropertyCache *parent() const;
// is used by the Qml Designer
void setParent(QQmlPropertyCache *newParent);
@@ -241,7 +290,7 @@ private:
bool _hasPropertyOverrides : 1;
bool _ownMetaObject : 1;
- const QMetaObject *_metaObject;
+ RefCountedMetaObject _metaObject;
QByteArray _dynamicClassName;
QByteArray _dynamicStringData;
QString _defaultPropertyName;
@@ -268,9 +317,10 @@ inline const QMetaObject *QQmlPropertyCache::metaObject() const
// QML
inline const QMetaObject *QQmlPropertyCache::firstCppMetaObject() const
{
- while (_parent && (_metaObject == nullptr || _ownMetaObject))
- return _parent->firstCppMetaObject();
- return _metaObject;
+ const QQmlPropertyCache *p = this;
+ while (!p->_metaObject || p->_metaObject.isShared())
+ p = p->parent();
+ return p->_metaObject;
}
inline QQmlPropertyData *QQmlPropertyCache::property(int index) const