From 14c7bb72b98ef39a9118ae0a8e48a3ccd58db07d Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 1 Apr 2012 20:31:55 +0200 Subject: Store the QMetaObject with the QMetaType. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will allow conversion between pointers to compatible QObject derived types. Change-Id: I19e08934571fb3f1b91e594892214041fe5f6a11 Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qmetatype.cpp | 65 +++++++++++++++++++++++++++++++++++++++- src/corelib/kernel/qmetatype.h | 27 ++++++++++++++--- src/corelib/kernel/qmetatype_p.h | 13 ++++++-- 3 files changed, 98 insertions(+), 7 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index e1cebc453d..ea079fa712 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -286,6 +286,7 @@ static const struct { const char * typeName; int typeNameLength; int type; } typ Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = 0; Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper = 0; +Q_CORE_EXPORT const QMetaObject *qMetaObjectWidgetsHelper = 0; class QCustomTypeInfo : public QMetaTypeInterface { @@ -496,6 +497,7 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, inf.destructor = destructor; inf.size = size; inf.flags = flags; + inf.metaObject = metaObject; idx = ct->size() + User; ct->append(inf); return idx; @@ -1521,6 +1523,51 @@ QMetaType::TypeFlags QMetaType::typeFlags(int type) return static_cast(QMetaTypeSwitcher::switcher(flags, type, 0)); } +#ifndef QT_BOOTSTRAPPED +namespace { +class MetaObject +{ +public: + MetaObject(const int type) + : m_type(type) + {} + template + const QMetaObject *delegate(const T*) { return QtPrivate::MetaObjectForType::value(); } + const QMetaObject *delegate(const void*) { return 0; } + const QMetaObject *delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; } + const QMetaObject *delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customMetaObject(m_type); } +private: + const int m_type; + static const QMetaObject *customMetaObject(const int type) + { + const QVector * const ct = customTypes(); + if (Q_UNLIKELY(!ct || type < QMetaType::User)) + return 0; + QReadLocker locker(customTypesLock()); + if (Q_UNLIKELY(ct->count() <= type - QMetaType::User)) + return 0; + return ct->at(type - QMetaType::User).metaObject; + } +}; +} // namespace +#endif + +/*! + \since 5.0 + + Returns QMetaObject of a given \a type, if the \a type is a pointer to type derived from QObject. +*/ +const QMetaObject *QMetaType::metaObjectForType(int type) +{ +#ifndef QT_BOOTSTRAPPED + MetaObject mo(type); + return QMetaTypeSwitcher::switcher(mo, type, 0); +#else + Q_UNUSED(type); + return 0; +#endif +} + /*! \fn int qRegisterMetaType(const char *typeName) \relates QMetaType @@ -1710,7 +1757,7 @@ QMetaType QMetaType::typeInfo(const int type) , typeInfo.info.size , typeInfo.info.flags , type - , 0) + , typeInfo.info.metaObject) : QMetaType(UnknownType); } @@ -1809,4 +1856,20 @@ QMetaType::TypeFlags QMetaType::flagsExtended() const return 0; } +const QMetaObject *QMetaType::metaObjectExtended() const +{ + return 0; +} + + +namespace QtPrivate +{ +const QMetaObject *metaObjectForQWidget() +{ + if (!qMetaTypeWidgetsHelper) + return 0; + return qMetaObjectWidgetsHelper; +} +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index fa0726adfa..a42333fbf8 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -196,7 +196,7 @@ class Q_CORE_EXPORT QMetaType { ConstructEx = 0x4, DestructEx = 0x8, NameEx = 0x10, SizeEx = 0x20, CtorEx = 0x40, DtorEx = 0x80, - FlagsEx = 0x100 + FlagsEx = 0x100, MetaObjectEx = 0x200 }; public: #ifndef Q_QDOC @@ -290,6 +290,7 @@ public: static const char *typeName(int type); static int sizeOf(int type); static TypeFlags typeFlags(int type); + static const QMetaObject *metaObjectForType(int type); static bool isRegistered(int type); static void *create(int type, const void *copy = 0); #if QT_DEPRECATED_SINCE(5, 0) @@ -312,6 +313,7 @@ public: inline bool isRegistered() const; inline int sizeOf() const; inline TypeFlags flags() const; + inline const QMetaObject *metaObject() const; inline void *create(const void *copy = 0) const; inline void destroy(void *data) const; @@ -339,6 +341,7 @@ private: void dtor(); uint sizeExtended() const; QMetaType::TypeFlags flagsExtended() const; + const QMetaObject *metaObjectExtended() const; void *createExtended(const void *copy = 0) const; void destroyExtended(void *data) const; void *constructExtended(void *where, const void *copy = 0) const; @@ -355,7 +358,7 @@ private: uint m_typeFlags; uint m_extensionFlags; int m_typeId; - const QMetaObject *m_metaObject; // Placeholder for Qt 5.1 feature. + const QMetaObject *m_metaObject; }; #undef QT_DEFINE_METATYPE_ID @@ -466,12 +469,21 @@ namespace QtPrivate { static inline const QMetaObject *value() { return 0; } }; + template struct MetaObjectForType { static inline const QMetaObject *value() { return &T::staticMetaObject; } }; + Q_CORE_EXPORT const QMetaObject *metaObjectForQWidget(); + + template<> + struct MetaObjectForType + { + static const QMetaObject *value() { return metaObjectForQWidget(); } + }; + template struct IsSharedPointerToTypeDerivedFromQObject { @@ -846,7 +858,7 @@ inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeI uint size, uint theTypeFlags, int typeId, - const QMetaObject *metaObject) + const QMetaObject *_metaObject) : m_creator(creator) , m_deleter(deleter) , m_saveOp(saveOp) @@ -858,7 +870,7 @@ inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeI , m_typeFlags(theTypeFlags) , m_extensionFlags(extensionFlags) , m_typeId(typeId) - , m_metaObject(metaObject) + , m_metaObject(_metaObject) { if (Q_UNLIKELY(isExtended(CtorEx) || typeId == QMetaType::Void)) ctor(info); @@ -924,6 +936,13 @@ inline QMetaType::TypeFlags QMetaType::flags() const return QMetaType::TypeFlags(m_typeFlags); } +inline const QMetaObject *QMetaType::metaObject() const +{ + if (Q_UNLIKELY(isExtended(MetaObjectEx))) + return metaObjectExtended(); + return m_metaObject; +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index cffc45c988..126acde8fa 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -130,6 +130,7 @@ public: QMetaType::Destructor destructor; int size; quint32 flags; // same as QMetaType::TypeFlags + const QMetaObject *metaObject; }; #ifndef QT_NO_DATASTREAM @@ -147,6 +148,12 @@ public: QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) #endif +#ifndef QT_BOOTSTRAPPED +#define METAOBJECT_DELEGATE(Type) (QtPrivate::MetaObjectForType::value()) +#else +#define METAOBJECT_DELEGATE(Type) 0 +#endif + #define QT_METATYPE_INTERFACE_INIT_IMPL(Type, DATASTREAM_DELEGATE) \ { \ /*creator*/(qMetaTypeCreateHelper), \ @@ -155,7 +162,8 @@ public: /*constructor*/(qMetaTypeConstructHelper), \ /*destructor*/(qMetaTypeDestructHelper), \ /*size*/(QTypeInfo::sizeOf), \ - /*flags*/QtPrivate::QMetaTypeTypeFlags::Flags \ + /*flags*/QtPrivate::QMetaTypeTypeFlags::Flags, \ + /*metaObject*/METAOBJECT_DELEGATE(Type) \ } @@ -179,7 +187,8 @@ public: /*constructor*/ 0, \ /*destructor*/ 0, \ /*size*/ 0, \ - /*flags*/ 0 \ + /*flags*/ 0, \ + /*metaObject*/ 0 \ } namespace QtMetaTypePrivate { -- cgit v1.2.3