diff options
author | Matthew Vogt <matthew.vogt@nokia.com> | 2012-08-01 10:27:17 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-08-10 05:40:49 +0200 |
commit | 4350877d6deb58f36df24164c6edde3302a3f1a3 (patch) | |
tree | 5b1b121c1ce21aff1717de500282a5951f4e1267 /src/qml/qml/qqmlvaluetype.cpp | |
parent | 34ae6deb78c30a80570e0c0dda7b2f071abdbf68 (diff) |
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 <michael.brasser@nokia.com>
Diffstat (limited to 'src/qml/qml/qqmlvaluetype.cpp')
-rw-r--r-- | src/qml/qml/qqmlvaluetype.cpp | 89 |
1 files changed, 76 insertions, 13 deletions
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<int, QQmlValueType *> 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<QQmlEasingValueType>(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<int, QQmlValueType *>::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<QQmlEasingValueType>(uri, versionMajor, versionMinor, "Easing"); +} + + QQmlValueType::QQmlValueType(int userType, QObject *parent) : QObject(parent), m_userType(userType) { } - QQmlPointFValueType::QQmlPointFValueType(QObject *parent) : QQmlValueTypeBase<QPointF>(QMetaType::QPointF, parent) { |