diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/labs/stylekit/qqstylekitcontrolproperties.cpp | 50 | ||||
| -rw-r--r-- | src/labs/stylekit/qqstylekitcontrolproperties_p.h | 3 | ||||
| -rw-r--r-- | src/labs/stylekit/qqstylekitdebug.cpp | 37 | ||||
| -rw-r--r-- | src/labs/stylekit/qqstylekitglobal_p.h | 1 | ||||
| -rw-r--r-- | src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp | 4 | ||||
| -rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 30 | ||||
| -rw-r--r-- | src/qml/qml/qqmlmetatypedata.cpp | 23 | ||||
| -rw-r--r-- | src/qml/qml/qqmlmetatypedata_p.h | 12 | ||||
| -rw-r--r-- | src/qml/qml/qqmltypedata.cpp | 30 |
9 files changed, 108 insertions, 82 deletions
diff --git a/src/labs/stylekit/qqstylekitcontrolproperties.cpp b/src/labs/stylekit/qqstylekitcontrolproperties.cpp index d44bf6050d..d35935860f 100644 --- a/src/labs/stylekit/qqstylekitcontrolproperties.cpp +++ b/src/labs/stylekit/qqstylekitcontrolproperties.cpp @@ -11,6 +11,8 @@ QT_BEGIN_NAMESPACE // ************* QQStyleKitPropertyGroup **************** +QHash<PropertyPathId_t, QString> QQStyleKitPropertyGroup::s_pathStrings; + QQStyleKitPropertyGroup::QQStyleKitPropertyGroup(QQSK::PropertyGroup, QObject *parent) : QObject(parent) { @@ -27,6 +29,51 @@ PropertyPathId QQStyleKitPropertyGroup::propertyPathId(QQSK::Property property, return PropertyPathId(property, m_groupSpace.start, QQSK::PropertyGroup::DelegateSubtype0); } +QString QQStyleKitPropertyGroup::pathToString() const +{ + /* Start from the root of the path and build the path down to this group. This + * mirrors how the groups were originally created and avoids rounding issues + * that can arise if attempting to reconstruct the path “backwards”. + * Note: For each group, m_groupSpace.start is stored relative to the root, + * while m_groupSpace.size is relative to the parent group. However, when + * calculating the group index, the group-space start must be computed + * relative to the parent group. + * We cache the requested paths, as the same paths are typically requested + * repeatedly. The number of possible paths (and thus leaf groups) is well below + * 100, and in practice the cache usually ends up with fewer than 20 entries. */ + if (s_pathStrings.contains(m_groupSpace.start)) + return s_pathStrings[m_groupSpace.start]; + + constexpr PropertyPathId_t rootGroupsSize = nestedGroupsStartSize / nestedGroupCount; + const auto metaEnum = QMetaEnum::fromType<QQSK::PropertyGroup>(); + + PropertyPathId_t nestedGroupStart = m_groupSpace.start; + PropertyPathId_t nestedGroupSize = rootGroupsSize; + PropertyPathId_t nestedGroupIndex = nestedGroupStart / nestedGroupSize; + auto groupType = QQSK::PropertyGroup(nestedGroupIndex); + if (groupType == QQSK::PropertyGroup::Control) + return {}; + + QString groupName = QString::fromLatin1(metaEnum.valueToKey(static_cast<int>(groupType))); + groupName[0] = groupName[0].toLower(); + QString pathString = groupName; + + while (true) { + nestedGroupStart -= nestedGroupIndex * nestedGroupSize; + nestedGroupSize /= nestedGroupCount; + nestedGroupIndex = nestedGroupStart / nestedGroupSize; + groupType = QQSK::PropertyGroup(nestedGroupIndex); + if (groupType == QQSK::PropertyGroup::Control) + break; + + QString groupName = QString::fromLatin1(metaEnum.valueToKey(static_cast<int>(groupType))); + groupName[0] = groupName[0].toLower(); + pathString += '.'_L1 + groupName; + } + + return pathString; +} + QQStyleKitControlProperties *QQStyleKitPropertyGroup::controlProperties() const { if (isControlProperties()) { @@ -63,9 +110,8 @@ T *QQStyleKitPropertyGroup::lazyCreateGroup(T * const &ptr, QQSK::PropertyGroup /* Calculate the available property ID space for the nested group. This is done by * dividing the available space inside _this_ group on the number of potential groups * that _this_ group can potentially contain. */ - constexpr PropertyPathId_t groupCount = PropertyPathId_t(QQSK::PropertyGroup::PATH_ID_GROUP_COUNT); const PropertyPathId_t nestedGroupIndex = PropertyPathId_t(group); - const PropertyPathId_t nestedGroupSize = m_groupSpace.size / groupCount; + const PropertyPathId_t nestedGroupSize = m_groupSpace.size / nestedGroupCount; nestedGroup->m_groupSpace.size = nestedGroupSize; nestedGroup->m_groupSpace.start = m_groupSpace.start + (nestedGroupIndex * nestedGroupSize); /* Ensure that we haven’t exhausted the available PropertyPathId space. There must be diff --git a/src/labs/stylekit/qqstylekitcontrolproperties_p.h b/src/labs/stylekit/qqstylekitcontrolproperties_p.h index f2c7f35216..fb6df9fb81 100644 --- a/src/labs/stylekit/qqstylekitcontrolproperties_p.h +++ b/src/labs/stylekit/qqstylekitcontrolproperties_p.h @@ -45,6 +45,7 @@ public: QQStyleKitPropertyGroup(QQSK::PropertyGroup group, QObject *parent); PropertyPathId propertyPathId(QQSK::Property property, PropertyPathId::Flag flag) const; + QString pathToString() const; template<typename T> inline T styleProperty( @@ -101,6 +102,8 @@ protected: private: bool shouldEmitLocally(); bool shouldEmitGlobally(); + + static QHash<PropertyPathId_t, QString> s_pathStrings; }; // ************* QQStyleKitImageProperties **************** diff --git a/src/labs/stylekit/qqstylekitdebug.cpp b/src/labs/stylekit/qqstylekitdebug.cpp index dcd191959d..4f6cd78b61 100644 --- a/src/labs/stylekit/qqstylekitdebug.cpp +++ b/src/labs/stylekit/qqstylekitdebug.cpp @@ -52,37 +52,12 @@ QString QQStyleKitDebug::styleReaderToString(const QQStyleKitReader *reader) QString QQStyleKitDebug::propertyPath(const QQStyleKitPropertyGroup *group, const PropertyPathId property) { - QString path = enumToString(property.property()); - path[0] = path[0].toLower(); - const QQStyleKitPropertyGroup *childGroup = group; - const int startIndex = QQStyleKitPropertyGroup::staticMetaObject.propertyOffset(); - - while (childGroup) { - if (childGroup->isControlProperties()) - break; - const QQStyleKitPropertyGroup *parentGroup = - qobject_cast<const QQStyleKitPropertyGroup *>(childGroup->parent()); - if (!parentGroup) - break; - - // Resolve group name by inspecting which property in the parent group it belongs to - const QMetaObject* parentMeta = parentGroup->metaObject(); - for (int i = startIndex; i < parentMeta->propertyCount(); ++i) { - const QMetaProperty prop = parentMeta->property(i); - const QMetaObject* typeMeta = QMetaType::fromName(prop.typeName()).metaObject(); - if (!typeMeta || !typeMeta->inherits(&QQStyleKitPropertyGroup::staticMetaObject)) - continue; - QObject *propGroup = prop.read(parentGroup).value<QQStyleKitPropertyGroup *>(); - if (propGroup == childGroup) { - path.prepend(QString::fromUtf8(prop.name()) + kDot); - break; - } - } - - childGroup = parentGroup; - } - - return path; + const QString path = group->pathToString(); + QString propertyName = enumToString(property.property()); + propertyName[0] = propertyName[0].toLower(); + if (path.isEmpty()) + return propertyName; + return path + kDot + propertyName; } QString QQStyleKitDebug::controlToString(const QQStyleKitControlProperties *control) diff --git a/src/labs/stylekit/qqstylekitglobal_p.h b/src/labs/stylekit/qqstylekitglobal_p.h index 3808def107..e4d6a151dc 100644 --- a/src/labs/stylekit/qqstylekitglobal_p.h +++ b/src/labs/stylekit/qqstylekitglobal_p.h @@ -171,6 +171,7 @@ using QQStyleKitExtendableControlType = quint32; using QQStyleKitPropertyStorage = QHash<PropertyStorageId, QVariant>; constexpr PropertyPathId_t maxPropertyStorageSpaceSize = std::numeric_limits<PropertyPathId_t>::max(); +constexpr PropertyPathId_t nestedGroupCount = PropertyPathId_t(QQSK::PropertyGroup::PATH_ID_GROUP_COUNT); constexpr PropertyPathId_t maxStateCombinationCount = PropertyPathId_t(QQSK::StateFlag::MAX_STATE); constexpr PropertyPathId_t stateStorageSpaceSize = maxPropertyStorageSpaceSize / maxStateCombinationCount; constexpr PropertyPathId_t subtypeCount = PropertyPathId_t(QQSK::PropertyPathFlag::DelegateSubtype2) - PropertyPathId_t(QQSK::PropertyPathFlag::DelegateSubtype0) + 1; diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp index 14eabef68a..b9f13f52a7 100644 --- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp +++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp @@ -162,8 +162,6 @@ void QQmlPreviewPosition::readLastPositionFromByteArray(const QByteArray &array) QPoint nativePosition; stream >> nativePosition; - if (nativePosition.isNull()) - return; QSize size; stream >> size; @@ -174,8 +172,6 @@ void QQmlPreviewPosition::readLastPositionFromByteArray(const QByteArray &array) void QQmlPreviewPosition::setPosition(const QQmlPreviewPosition::Position &position, QWindow *window) { - if (position.nativePosition.isNull()) - return; if (QScreen *screen = findScreen(position.screenName)) { window->setScreen(screen); const auto point = QHighDpiScaling::mapPositionFromNative(position.nativePosition, diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 5e2e5eb488..01da4ef485 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -329,7 +329,6 @@ void QQmlMetaType::clearTypeRegistrations() data->idToType.clear(); data->nameToType.clear(); data->urlToType.clear(); - data->typePropertyCaches.clear(); data->metaObjectToType.clear(); data->undeletableTypes.clear(); data->propertyCaches.clear(); @@ -350,7 +349,7 @@ void QQmlMetaType::clearTypeRegistrations() void QQmlMetaType::registerTypeAlias(int typeIndex, const QString &name) { QQmlMetaTypeDataPtr data; - const QQmlType type = data->types.value(typeIndex); + const QQmlType type = data->types.value(typeIndex).type; const QQmlTypePrivate *priv = type.priv(); data->nameToType.insert(name, priv); } @@ -928,7 +927,8 @@ static bool namespaceContainsRegistrations(const QQmlMetaTypeData *data, const Q { // Has any type previously been installed to this namespace? QHashedString nameSpace(uri); - for (const QQmlType &type : data->types) { + for (const auto &typeAndCaches : std::as_const(data->types)) { + const QQmlType &type = typeAndCaches.type; if (type.module() == nameSpace && type.version().majorVersion() == version.majorVersion()) return true; } @@ -1328,10 +1328,7 @@ QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStrin QQmlType QQmlMetaType::qmlTypeById(int qmlTypeId) { const QQmlMetaTypeDataPtr data; - QQmlType type = data->types.value(qmlTypeId); - if (type.isValid()) - return type; - return QQmlType(); + return data->types.value(qmlTypeId).type; } /*! @@ -1519,7 +1516,7 @@ QQmlPropertyCache::ConstPtr QQmlMetaType::rawPropertyCacheForType( void QQmlMetaType::unregisterType(int typeIndex) { QQmlMetaTypeDataPtr data; - const QQmlType type = data->types.value(typeIndex); + const QQmlType type = data->types.value(typeIndex).type; if (const QQmlTypePrivate *d = type.priv()) { if (d->regType == QQmlType::CompositeType || d->regType == QQmlType::CompositeSingletonType) removeFromInlineComponents(data->urlToType, d); @@ -1529,8 +1526,7 @@ void QQmlMetaType::unregisterType(int typeIndex) removeQQmlTypePrivate(data->metaObjectToType, d); for (auto & module : data->uriToModule) module->remove(d); - data->clearPropertyCachesForVersion(typeIndex); - data->types[typeIndex] = QQmlType(); + data->types[typeIndex] = QQmlMetaTypeData::Type(); data->undeletableTypes.remove(type); } } @@ -1607,9 +1603,9 @@ void QQmlMetaType::freeUnusedTypesAndCaches() bool deletedAtLeastOneType; do { deletedAtLeastOneType = false; - QList<QQmlType>::Iterator it = data->types.begin(); + auto it = data->types.begin(); while (it != data->types.end()) { - const QQmlTypePrivate *d = (*it).priv(); + const QQmlTypePrivate *d = it->type.priv(); if (d && d->count() == 1 && !hasActiveInlineComponents(data, d)) { deletedAtLeastOneType = true; @@ -1625,8 +1621,7 @@ void QQmlMetaType::freeUnusedTypesAndCaches() for (auto &module : data->uriToModule) module->remove(d); - data->clearPropertyCachesForVersion(d->index); - *it = QQmlType(); + *it = QQmlMetaTypeData::Type(); } else { ++it; } @@ -1687,7 +1682,12 @@ QList<QQmlType> QQmlMetaType::qmlTypes() QList<QQmlType> QQmlMetaType::qmlAllTypes() { const QQmlMetaTypeDataPtr data; - return data->types; + QList<QQmlType> types; + types.reserve(data->types.size()); + std::transform( + data->types.constBegin(), data->types.constEnd(), + std::back_inserter(types), [](const auto &type) { return type.type; }); + return types; } /*! diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp index 30838c73a0..13170a47e1 100644 --- a/src/qml/qml/qqmlmetatypedata.cpp +++ b/src/qml/qml/qqmlmetatypedata.cpp @@ -28,14 +28,15 @@ QQmlMetaTypeData::~QQmlMetaTypeData() void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv) { for (int i = 0; i < types.size(); ++i) { - if (!types.at(i).isValid()) { - types[i] = QQmlType(priv); + Type &type = types[i]; + if (!type.type.isValid()) { + type.type = QQmlType(priv); priv->index = i; priv->release(); return; } } - types.append(QQmlType(priv)); + types.append({QQmlType(priv), {}}); priv->index = types.size() - 1; priv->release(); } @@ -85,23 +86,17 @@ bool QQmlMetaTypeData::registerModuleTypes(const QString &uri) QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCacheForVersion( int index, QTypeRevision version) const { - return (index < typePropertyCaches.size()) - ? typePropertyCaches.at(index).value(version) + return (index < types.size()) + ? types[index].propertyCaches.value(version) : QQmlPropertyCache::ConstPtr(); } void QQmlMetaTypeData::setPropertyCacheForVersion(int index, QTypeRevision version, const QQmlPropertyCache::ConstPtr &cache) { - if (index >= typePropertyCaches.size()) - typePropertyCaches.resize(index + 1); - typePropertyCaches[index][version] = cache; -} - -void QQmlMetaTypeData::clearPropertyCachesForVersion(int index) -{ - if (index < typePropertyCaches.size()) - typePropertyCaches[index].clear(); + if (index >= types.size()) + types.resize(index + 1); + types[index].propertyCaches[version] = cache; } QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCache( diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h index 6b6bae64f2..44eebb93fe 100644 --- a/src/qml/qml/qqmlmetatypedata_p.h +++ b/src/qml/qml/qqmlmetatypedata_p.h @@ -32,8 +32,16 @@ struct QQmlMetaTypeData QQmlMetaTypeData(); ~QQmlMetaTypeData(); void registerType(QQmlTypePrivate *priv); - QList<QQmlType> types; + + struct Type + { + QQmlType type; + QHash<QTypeRevision, QQmlPropertyCache::ConstPtr> propertyCaches; + }; + + QList<Type> types; QSet<QQmlType> undeletableTypes; + typedef QHash<int, QQmlTypePrivate *> Ids; Ids idToType; @@ -45,7 +53,6 @@ struct QQmlMetaTypeData typedef QMultiHash<const QMetaObject *, const QQmlTypePrivate *> MetaObjects; MetaObjects metaObjectToType; - QVector<QHash<QTypeRevision, QQmlPropertyCache::ConstPtr>> typePropertyCaches; QHash<int, QQmlValueType *> metaTypeToValueType; // This has to be a multihash because a user can create a compilation unit using arbitrary @@ -110,7 +117,6 @@ struct QQmlMetaTypeData QQmlPropertyCache::ConstPtr propertyCacheForVersion(int index, QTypeRevision version) const; void setPropertyCacheForVersion( int index, QTypeRevision version, const QQmlPropertyCache::ConstPtr &cache); - void clearPropertyCachesForVersion(int index); QQmlPropertyCache::ConstPtr propertyCache(const QMetaObject *metaObject, QTypeRevision version); QQmlPropertyCache::ConstPtr propertyCache(const QQmlType &type, QTypeRevision version); diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index 44e1635afc..e3947d15df 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -418,24 +418,28 @@ bool QQmlTypeData::checkDependencies() || type.typeData->isCompleteOrError() || type.type.isInlineComponentType()); - if (type.type.isInlineComponentType()) { - const QUrl url = type.type.sourceUrl(); - if (!QQmlMetaType::equalBaseUrls(url, finalUrl()) - && !QQmlMetaType::obtainCompilationUnit(type.type.typeId())) { - const QString &typeName = stringAt(it.key()); - int lastDot = typeName.lastIndexOf(u'.'); - createError( - type, - QQmlTypeLoader::tr("Type %1 has no inline component type called %2") - .arg(QStringView{typeName}.left(lastDot), type.type.elementName())); - return false; - } - } if (type.typeData && type.typeData->isError()) { const QString &typeName = stringAt(it.key()); createError(type, QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName)); return false; } + + if (!type.selfReference && type.type.isInlineComponentType()) { + const QString icName = type.type.elementName(); + Q_ASSERT(!icName.isEmpty()); + + // We have a CU here. Check if the inline component exists. + if (type.typeData && type.typeData->compilationUnit()->inlineComponentId(icName) >= 0) + return true; + + const QString typeName = stringAt(it.key()); + const qsizetype lastDot = typeName.lastIndexOf(u'.'); + createError( + type, + QQmlTypeLoader::tr("Type %1 has no inline component type called %2") + .arg(QStringView{typeName}.left(lastDot), icName)); + return false; + } } return true; |
