From 4350877d6deb58f36df24164c6edde3302a3f1a3 Mon Sep 17 00:00:00 2001 From: Matthew Vogt Date: Wed, 1 Aug 2012 10:27:17 +1000 Subject: Permit value types with metatype IDs >= QMetaType::User Remove the assumption that value types must be types defined by Qt, having metatype IDs below QMetaType::User. Task-number: QTBUG-26352 Change-Id: Ib5a56ff2e7892e82adf17a3a1e7517a0c9fe0534 Reviewed-by: Michael Brasser --- src/qml/qml/qqmlvaluetype.cpp | 89 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 13 deletions(-) (limited to 'src/qml/qml/qqmlvaluetype.cpp') diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index 165024adfe..9be48ae9c7 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -47,21 +47,40 @@ QT_BEGIN_NAMESPACE -QQmlValueTypeFactory::QQmlValueTypeFactory() +namespace { + +struct QQmlValueTypeFactoryImpl +{ + QQmlValueTypeFactoryImpl(); + ~QQmlValueTypeFactoryImpl(); + + bool isValueType(int idx); + + QQmlValueType *createValueType(int); + QQmlValueType *valueType(int); + + QQmlValueType *valueTypes[QVariant::UserType]; + QHash userTypes; + QMutex mutex; +}; + +QQmlValueTypeFactoryImpl::QQmlValueTypeFactoryImpl() { for (unsigned int ii = 0; ii < QVariant::UserType; ++ii) valueTypes[ii] = 0; } -QQmlValueTypeFactory::~QQmlValueTypeFactory() +QQmlValueTypeFactoryImpl::~QQmlValueTypeFactoryImpl() { - for (unsigned int ii = 0; ii < QVariant::UserType; ++ii) - delete valueTypes[ii]; + qDeleteAll(valueTypes, valueTypes + QVariant::UserType); + qDeleteAll(userTypes); } -bool QQmlValueTypeFactory::isValueType(int idx) +bool QQmlValueTypeFactoryImpl::isValueType(int idx) { - if ((uint)idx < QVariant::UserType + if (idx >= QVariant::UserType) { + return (valueType(idx) != 0); + } else if (idx >= 0 && idx != QVariant::StringList && idx != QMetaType::QObjectStar && idx != QMetaType::QWidgetStar @@ -69,15 +88,11 @@ bool QQmlValueTypeFactory::isValueType(int idx) && idx != QMetaType::QVariant) { return true; } - return false; -} -void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor, int versionMinor) -{ - qmlRegisterValueTypeEnums(uri, versionMajor, versionMinor, "Easing"); + return false; } -QQmlValueType *QQmlValueTypeFactory::valueType(int t) +QQmlValueType *QQmlValueTypeFactoryImpl::createValueType(int t) { QQmlValueType *rv = 0; @@ -112,12 +127,60 @@ QQmlValueType *QQmlValueTypeFactory::valueType(int t) return rv; } +QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx) +{ + if (idx >= (int)QVariant::UserType) { + // Protect the hash with a mutex + mutex.lock(); + + QHash::iterator it = userTypes.find(idx); + if (it == userTypes.end()) { + it = userTypes.insert(idx, createValueType(idx)); + } + + mutex.unlock(); + return *it; + } + + QQmlValueType *rv = valueTypes[idx]; + if (!rv) { + // No need for mutex protection - the most we can lose is a valueType instance + + // TODO: Investigate the performance/memory characteristics of + // removing the preallocated array + if ((rv = createValueType(idx))) { + valueTypes[idx] = rv; + } + } + + return rv; +} + +} + +Q_GLOBAL_STATIC(QQmlValueTypeFactoryImpl, factoryImpl); + +bool QQmlValueTypeFactory::isValueType(int idx) +{ + return factoryImpl()->isValueType(idx); +} + +QQmlValueType *QQmlValueTypeFactory::valueType(int idx) +{ + return factoryImpl()->valueType(idx); +} + +void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor, int versionMinor) +{ + qmlRegisterValueTypeEnums(uri, versionMajor, versionMinor, "Easing"); +} + + QQmlValueType::QQmlValueType(int userType, QObject *parent) : QObject(parent), m_userType(userType) { } - QQmlPointFValueType::QQmlPointFValueType(QObject *parent) : QQmlValueTypeBase(QMetaType::QPointF, parent) { -- cgit v1.2.3