diff options
-rw-r--r-- | src/qml/qml/qqml.h | 90 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 33 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetype_p.h | 2 | ||||
-rw-r--r-- | tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp | 2 |
4 files changed, 70 insertions, 57 deletions
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index b7f5cb714d..9c01ee4bd6 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -89,19 +89,30 @@ QT_BEGIN_NAMESPACE class QQmlPropertyValueInterceptor; +#define QML_GETTYPENAMES \ + const char *className = T::staticMetaObject.className(); \ + int nameLen = strlen(className); \ + QVarLengthArray<char,48> pointerName(nameLen+2); \ + memcpy(pointerName.data(), className, nameLen); \ + pointerName[nameLen] = '*'; \ + pointerName[nameLen+1] = '\0'; \ + int listLen = strlen("QQmlListProperty<"); \ + QVarLengthArray<char,64> listName(listLen + nameLen + 2); \ + memcpy(listName.data(), "QQmlListProperty<", listLen); \ + memcpy(listName.data()+listLen, className, nameLen); \ + listName[listLen+nameLen] = '>'; \ + listName[listLen+nameLen+1] = '\0'; + template<typename T> int qmlRegisterType() { - QByteArray name(T::staticMetaObject.className()); - - QByteArray pointerName(name + '*'); - QByteArray listName("QQmlListProperty<" + name + '>'); + QML_GETTYPENAMES QQmlPrivate::RegisterType type = { 0, - qRegisterMetaType<T *>(pointerName.constData()), - qRegisterMetaType<QQmlListProperty<T> >(listName.constData()), + qRegisterNormalizedMetaType<T *>(pointerName.constData()), + qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), 0, 0, QString(), @@ -128,16 +139,13 @@ int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, template<typename T> int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason) { - QByteArray name(T::staticMetaObject.className()); - - QByteArray pointerName(name + '*'); - QByteArray listName("QQmlListProperty<" + name + '>'); + QML_GETTYPENAMES QQmlPrivate::RegisterType type = { 0, - qRegisterMetaType<T *>(pointerName.constData()), - qRegisterMetaType<QQmlListProperty<T> >(listName.constData()), + qRegisterNormalizedMetaType<T *>(pointerName.constData()), + qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), 0, 0, reason, @@ -162,16 +170,13 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin template<typename T> int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) { - QByteArray name(T::staticMetaObject.className()); - - QByteArray pointerName(name + '*'); - QByteArray listName("QQmlListProperty<" + name + '>'); + QML_GETTYPENAMES QQmlPrivate::RegisterType type = { 0, - qRegisterMetaType<T *>(pointerName.constData()), - qRegisterMetaType<QQmlListProperty<T> >(listName.constData()), + qRegisterNormalizedMetaType<T *>(pointerName.constData()), + qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), sizeof(T), QQmlPrivate::createInto<T>, QString(), @@ -196,16 +201,13 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c template<typename T, int metaObjectRevision> int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) { - QByteArray name(T::staticMetaObject.className()); - - QByteArray pointerName(name + '*'); - QByteArray listName("QQmlListProperty<" + name + '>'); + QML_GETTYPENAMES QQmlPrivate::RegisterType type = { 1, - qRegisterMetaType<T *>(pointerName.constData()), - qRegisterMetaType<QQmlListProperty<T> >(listName.constData()), + qRegisterNormalizedMetaType<T *>(pointerName.constData()), + qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), sizeof(T), QQmlPrivate::createInto<T>, QString(), @@ -230,16 +232,13 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c template<typename T, int metaObjectRevision> int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) { - QByteArray name(T::staticMetaObject.className()); - - QByteArray pointerName(name + '*'); - QByteArray listName("QQmlListProperty<" + name + '>'); + QML_GETTYPENAMES QQmlPrivate::RegisterType type = { 1, - qRegisterMetaType<T *>(pointerName.constData()), - qRegisterMetaType<QQmlListProperty<T> >(listName.constData()), + qRegisterNormalizedMetaType<T *>(pointerName.constData()), + qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), sizeof(T), QQmlPrivate::createInto<T>, QString(), @@ -265,16 +264,13 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) template<typename T, typename E> int qmlRegisterExtendedType() { - QByteArray name(T::staticMetaObject.className()); - - QByteArray pointerName(name + '*'); - QByteArray listName("QQmlListProperty<" + name + '>'); + QML_GETTYPENAMES QQmlPrivate::RegisterType type = { 0, - qRegisterMetaType<T *>(pointerName.constData()), - qRegisterMetaType<QQmlListProperty<T> >(listName.constData()), + qRegisterNormalizedMetaType<T *>(pointerName.constData()), + qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), 0, 0, QString(), @@ -300,10 +296,7 @@ template<typename T, typename E> int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) { - QByteArray name(T::staticMetaObject.className()); - - QByteArray pointerName(name + '*'); - QByteArray listName("QQmlListProperty<" + name + '>'); + QML_GETTYPENAMES QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>(); const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>(); @@ -315,8 +308,8 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, QQmlPrivate::RegisterType type = { 0, - qRegisterMetaType<T *>(pointerName.constData()), - qRegisterMetaType<QQmlListProperty<T> >(listName.constData()), + qRegisterNormalizedMetaType<T *>(pointerName.constData()), + qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), sizeof(T), QQmlPrivate::createInto<T>, QString(), @@ -349,8 +342,8 @@ int qmlRegisterInterface(const char *typeName) QQmlPrivate::RegisterInterface qmlInterface = { 0, - qRegisterMetaType<T *>(pointerName.constData()), - qRegisterMetaType<QQmlListProperty<T> >(listName.constData()), + qRegisterNormalizedMetaType<T *>(pointerName.constData()), + qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), qobject_interface_iid<T *>() }; @@ -362,16 +355,13 @@ template<typename T> int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, QQmlCustomParser *parser) { - QByteArray name(T::staticMetaObject.className()); - - QByteArray pointerName(name + '*'); - QByteArray listName("QQmlListProperty<" + name + '>'); + QML_GETTYPENAMES QQmlPrivate::RegisterType type = { 0, - qRegisterMetaType<T *>(pointerName.constData()), - qRegisterMetaType<QQmlListProperty<T> >(listName.constData()), + qRegisterNormalizedMetaType<T *>(pointerName.constData()), + qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), sizeof(T), QQmlPrivate::createInto<T>, QString(), diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 1566d83a22..87c39b1859 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -190,6 +190,25 @@ public: static QHash<const QMetaObject *, int> m_attachedPropertyIds; }; +// Avoid multiple fromUtf8(), copies and hashing of the module name. +// This is only called when metaTypeDataLock is locked. +static QHashedString moduletoUtf8(const char *module) +{ + if (!module) + return QHashedString(); + + static const char *lastModule = 0; + static QHashedString lastModuleStr; + + if (lastModule != module) { + lastModuleStr = QString::fromUtf8(module); + lastModuleStr.hash(); + lastModule = module; + } + + return lastModuleStr; +} + QHash<const QMetaObject *, int> QQmlTypePrivate::m_attachedPropertyIds; QQmlTypePrivate::QQmlTypePrivate() @@ -219,14 +238,9 @@ QQmlType::QQmlType(int index, const QQmlPrivate::RegisterInterface &interface) QQmlType::QQmlType(int index, const QQmlPrivate::RegisterType &type) : d(new QQmlTypePrivate) { - d->m_module = QString::fromUtf8(type.uri); + d->m_module = moduletoUtf8(type.uri); d->m_elementName = QString::fromUtf8(type.elementName); - if (!d->m_module.isEmpty()) - d->m_name = static_cast<QString>(d->m_module) + QLatin1Char('/') + d->m_elementName; - else - d->m_name = d->m_elementName; - d->m_version_maj = type.versionMajor; d->m_version_min = type.versionMinor; if (type.version >= 1) // revisions added in version 1 @@ -498,6 +512,13 @@ const QString &QQmlType::elementName() const const QString &QQmlType::qmlTypeName() const { + if (d->m_name.isEmpty()) { + if (!d->m_module.isEmpty()) + d->m_name = static_cast<QString>(d->m_module) + QLatin1Char('/') + d->m_elementName; + else + d->m_name = d->m_elementName; + } + return d->m_name; } diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index c72d2fc182..6641a40328 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -341,7 +341,7 @@ int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMino QQmlPrivate::RegisterType type = { 0, - qRegisterMetaType<T *>(pointerName.constData()), 0, 0, 0, + qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, 0, 0, QString(), diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index a3f311e248..520697909a 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -179,11 +179,13 @@ void tst_qqmlmetatype::qmlType() QVERIFY(type); QVERIFY(type->module() == QLatin1String("Test")); QVERIFY(type->elementName() == QLatin1String("ParserStatusTestType")); + QCOMPARE(type->qmlTypeName(), QLatin1String("Test/ParserStatusTestType")); type = QQmlMetaType::qmlType("Test/ParserStatusTestType", 1, 0); QVERIFY(type); QVERIFY(type->module() == QLatin1String("Test")); QVERIFY(type->elementName() == QLatin1String("ParserStatusTestType")); + QCOMPARE(type->qmlTypeName(), QLatin1String("Test/ParserStatusTestType")); } void tst_qqmlmetatype::isList() |