From c018df5b4075ae962966d4df7653d476dab02840 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 17 Apr 2019 08:38:20 +0200 Subject: QML: Remove static attchedPropertyIds map If the same object is available under two different names it should still have the same attached properties no matter which name you use. This was achieved by having a static map of metaobjects to attached property IDs that would always hold the first attached property ID registered for a given metaobject. This attached property ID was then used as key in the map of attached properties for the actual objects. The obvious downside to that is that we need a global static which gives us thread safety and static initialization (and destruction) problems. It turns out, all the attached properties are created by attached properties functions, registered by the user. Those functions only get the object to be amended as parameter. Therefore, no attached properties function can be registered for multiple attached properties on the same object as it wouldn't know which one to create for a given call. Thus, the whole ID dance is unnecessary as we can as well index the attached property objects by the function that created them. This nicely avoids creating two attached property objects for the same object and function and still makes the global static unnecessary. Fixes: QTBUG-75176 Change-Id: Ie8d53ef0a6f41c9b3d6b9d611cde1603a557901c Reviewed-by: Erik Verbruggen --- src/qml/qml/qqmlmetatype.cpp | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) (limited to 'src/qml/qml/qqmlmetatype.cpp') diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index f801e9aeba..1873a99a71 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -224,7 +224,6 @@ public: QQmlCustomParser *customParser; QQmlAttachedPropertiesFunc attachedPropertiesFunc; const QMetaObject *attachedPropertiesType; - int attachedPropertiesId; int propertyValueSourceCast; int propertyValueInterceptorCast; bool registerEnumClassesUnscoped; @@ -269,8 +268,6 @@ public: mutable QStringHash scopedEnumIndex; // maps from enum name to index in scopedEnums mutable QList*> scopedEnums; - static QHash attachedPropertyIds; - struct PropertyCacheByMinorVersion { PropertyCacheByMinorVersion() : cache(nullptr), minorVersion(-1) {} @@ -363,8 +360,6 @@ QJSValue QQmlType::SingletonInstanceInfo::scriptApi(QQmlEngine *e) const return scriptApis.value(e); } -QHash QQmlTypePrivate::attachedPropertyIds; - QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type) : refCount(1), regType(type), iid(nullptr), typeId(0), listId(0), revision(0), containsRevisionedAttributes(false), baseMetaObject(nullptr), @@ -498,14 +493,6 @@ QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQm d->baseMetaObject = type.metaObject; d->extraData.cd->attachedPropertiesFunc = type.attachedPropertiesFunction; d->extraData.cd->attachedPropertiesType = type.attachedPropertiesMetaObject; - if (d->extraData.cd->attachedPropertiesType) { - auto iter = QQmlTypePrivate::attachedPropertyIds.find(d->baseMetaObject); - if (iter == QQmlTypePrivate::attachedPropertyIds.end()) - iter = QQmlTypePrivate::attachedPropertyIds.insert(d->baseMetaObject, d->index); - d->extraData.cd->attachedPropertiesId = *iter; - } else { - d->extraData.cd->attachedPropertiesId = -1; - } d->extraData.cd->parserStatusCast = type.parserStatusCast; d->extraData.cd->propertyValueSourceCast = type.valueSourceCast; d->extraData.cd->propertyValueInterceptorCast = type.valueInterceptorCast; @@ -571,16 +558,8 @@ QQmlType::QQmlType(QQmlTypePrivate *priv) QQmlType::~QQmlType() { - if (d && !d->refCount.deref()) { - // If attached properties were successfully registered, deregister them. - // (They may not have been registered if some other type used the same baseMetaObject) - if (d->regType == CppType && d->extraData.cd->attachedPropertiesType) { - auto it = QQmlTypePrivate::attachedPropertyIds.find(d->baseMetaObject); - if (it != QQmlTypePrivate::attachedPropertyIds.end() && *it == d->index) - QQmlTypePrivate::attachedPropertyIds.erase(it); - } + if (d && !d->refCount.deref()) delete d; - } } QHashedString QQmlType::module() const @@ -1228,7 +1207,7 @@ int QQmlType::attachedPropertiesId(QQmlEnginePrivate *engine) const if (!d) return -1; if (d->regType == CppType) - return d->extraData.cd->attachedPropertiesId; + return d->extraData.cd->attachedPropertiesType ? d->index : -1; QQmlType base; if (d->regType == CompositeType) @@ -2188,6 +2167,16 @@ QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFuncById(QQmlEnginePr return data->types.at(id).attachedPropertiesFunction(engine); } +QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFunc(QQmlEnginePrivate *engine, + const QMetaObject *mo) +{ + QMutexLocker lock(metaTypeDataLock()); + QQmlMetaTypeData *data = metaTypeData(); + + QQmlType type(data->metaObjectToType.value(mo)); + return type.attachedPropertiesFunction(engine); +} + QMetaProperty QQmlMetaType::defaultProperty(const QMetaObject *metaObject) { int idx = metaObject->indexOfClassInfo("DefaultProperty"); -- cgit v1.2.3