diff options
author | Lars Knoll <lars.knoll@qt.io> | 2019-04-02 14:29:39 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-06-08 19:26:40 +0200 |
commit | 6a48a81319b886c8a3f85e1eb024186b05d0f3af (patch) | |
tree | bdc7a28492e24c734f1500d5eab073760655ede4 /src/qml/qml/qqmlpropertycache_p.h | |
parent | a8ef2c12635db3fcd46e600d3a49baa7bcaa6225 (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.h | 60 |
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 |