From 8a37893db7e340eb1dc3076496aef448c81fd4e7 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Wed, 3 Feb 2010 12:00:06 +1000 Subject: Construct the meta-object directly instead of using QMetaObjectBuilder. Removes the dependency on QtDeclarative for this class. --- src/multimedia/qml/qmetadatacontrolmetaobject.cpp | 214 +++++++++++++++++----- src/multimedia/qml/qmetadatacontrolmetaobject_p.h | 10 +- 2 files changed, 175 insertions(+), 49 deletions(-) diff --git a/src/multimedia/qml/qmetadatacontrolmetaobject.cpp b/src/multimedia/qml/qmetadatacontrolmetaobject.cpp index c2b5e78..6b0164b 100644 --- a/src/multimedia/qml/qmetadatacontrolmetaobject.cpp +++ b/src/multimedia/qml/qmetadatacontrolmetaobject.cpp @@ -40,12 +40,68 @@ ****************************************************************************/ #include - -#include /qmetadatacontrol.h> +#include QT_BEGIN_NAMESPACE +// copied from qmetaobject.cpp +// do not touch without touching the moc as well +enum PropertyFlags { + Invalid = 0x00000000, + Readable = 0x00000001, + Writable = 0x00000002, + Resettable = 0x00000004, + EnumOrFlag = 0x00000008, + StdCppSet = 0x00000100, +// Override = 0x00000200, + Designable = 0x00001000, + ResolveDesignable = 0x00002000, + Scriptable = 0x00004000, + ResolveScriptable = 0x00008000, + Stored = 0x00010000, + ResolveStored = 0x00020000, + Editable = 0x00040000, + ResolveEditable = 0x00080000, + User = 0x00100000, + ResolveUser = 0x00200000, + Notify = 0x00400000, + Dynamic = 0x00800000 +}; + +enum MethodFlags { + AccessPrivate = 0x00, + AccessProtected = 0x01, + AccessPublic = 0x02, + AccessMask = 0x03, //mask + + MethodMethod = 0x00, + MethodSignal = 0x04, + MethodSlot = 0x08, + MethodConstructor = 0x0c, + MethodTypeMask = 0x0c, + + MethodCompatibility = 0x10, + MethodCloned = 0x20, + MethodScriptable = 0x40 +}; + +struct QMetaObjectPrivate +{ + int revision; + int className; + int classInfoCount, classInfoData; + int methodCount, methodData; + int propertyCount, propertyData; + int enumeratorCount, enumeratorData; + int constructorCount, constructorData; + int flags; +}; + +static inline const QMetaObjectPrivate *priv(const uint* m_data) +{ return reinterpret_cast(m_data); } +// end of copied lines from qmetaobject.cpp + namespace { struct MetaDataKey @@ -76,7 +132,7 @@ namespace // Media { QtMedia::Size, "size" }, { QtMedia::MediaType, "mediaType" }, - { QtMedia::Duration, "duration" }, +// { QtMedia::Duration, "duration" }, // Audio { QtMedia::AudioBitRate, "audioBitRate" }, @@ -146,37 +202,132 @@ namespace { QtMedia::Sharpness, "sharpness" }, { QtMedia::DeviceSettingDescription, "deviceSettingDescription" } }; + + class QMetaDataControlObject : public QObject + { + public: + inline QObjectData *data() { return d_ptr.data(); } + }; } QMetaDataControlMetaObject::QMetaDataControlMetaObject(QMetaDataControl *control, QObject *object) : m_control(control) , m_object(object) - , m_mem(0) + , m_data(0) + , m_string(0) , m_propertyOffset(0) , m_signalOffset(0) { - m_builder.setSuperClass(m_object->metaObject()); - m_builder.setClassName(m_object->metaObject()->className()); - m_builder.setFlags(QMetaObjectBuilder::DynamicMetaObject); + const QMetaObject *superClass = m_object->metaObject(); + + const int propertyCount = sizeof(qt_metaDataKeys) / sizeof(MetaDataKey); + const int dataSize = sizeof(uint) + * (13 // QMetaObjectPrivate members. + + 5 // 5 members per signal. + + 4 * propertyCount // 3 members per property + 1 notify signal per property. + + 1); // Terminating value. + + m_data = reinterpret_cast(qMalloc(dataSize)); + + QMetaObjectPrivate *pMeta = reinterpret_cast(m_data); + + pMeta->revision = 3; + pMeta->className = 0; + pMeta->classInfoCount = 0; + pMeta->classInfoData = 0; + pMeta->methodCount = 1; + pMeta->methodData = 13; + pMeta->propertyCount = propertyCount; + pMeta->propertyData = 18; + pMeta->enumeratorCount = 0; + pMeta->enumeratorData = 0; + pMeta->constructorCount = 0; + pMeta->constructorData = 0; + pMeta->flags = 0x01; // Dynamic meta object flag. + + const int classNameSize = qstrlen(superClass->className()) + 1; + + int stringIndex = classNameSize + 1; + + // __metaDataChanged() signal. + static const char *changeSignal = "__metaDataChanged()"; + const int changeSignalSize = qstrlen(changeSignal) + 1; + + m_data[13] = stringIndex; // Signature. + m_data[14] = classNameSize; // Parameters. + m_data[15] = classNameSize; // Type. + m_data[16] = classNameSize; // Tag. + m_data[17] = MethodSignal | AccessProtected; // Flags. + + stringIndex += changeSignalSize; + + const char *qvariantName = "QVariant"; + const int qvariantSize = qstrlen(qvariantName) + 1; + const int qvariantIndex = stringIndex; + + stringIndex += qvariantSize; + + // Properties. + for (int i = 0; i < propertyCount; ++i) { + m_data[18 + 3 * i] = stringIndex; // Name. + m_data[19 + 3 * i] = qvariantIndex; // Type. + m_data[20 + 3 * i] + = Readable | Writable | Notify | Dynamic | (0xffffffff << 24); // Flags. + m_data[18 + propertyCount * 3 + i] = 0; // Notify signal. + + stringIndex += qstrlen(qt_metaDataKeys[i].name) + 1; + } + + // Terminating value. + m_data[18 + propertyCount * 4] = 0; + + // Build string. + m_string = reinterpret_cast(qMalloc(stringIndex + 1)); + + // Class name. + qMemCopy(m_string, superClass->className(), classNameSize); + + stringIndex = classNameSize; + + // Null m_string. + m_string[stringIndex] = '\0'; + stringIndex += 1; + + // __metaDataChanged() signal. + qMemCopy(m_string + stringIndex, changeSignal, changeSignalSize); + stringIndex += changeSignalSize; - QObjectPrivate *op = QObjectPrivate::get(m_object); - if (op->metaObject) - m_builder.setSuperClass(op->metaObject); + qMemCopy(m_string + stringIndex, qvariantName, qvariantSize); + stringIndex += qvariantSize; - m_mem = m_builder.toMetaObject(); - *static_cast(this) = *m_mem; + // Properties. + for (int i = 0; i < propertyCount; ++i) { + const int propertyNameSize = qstrlen(qt_metaDataKeys[i].name) + 1; + + qMemCopy(m_string + stringIndex, qt_metaDataKeys[i].name, propertyNameSize); + stringIndex += propertyNameSize; + } + + // Terminating character. + m_string[stringIndex] = '\0'; + + d.superdata = superClass; + d.stringdata = m_string; + d.data = m_data; + d.extradata = 0; + + static_cast(m_object)->data()->metaObject = this; - op->metaObject = this; m_propertyOffset = propertyOffset(); m_signalOffset = methodOffset(); } QMetaDataControlMetaObject::~QMetaDataControlMetaObject() { - qFree(m_mem); + static_cast(m_object)->data()->metaObject = 0; - QObjectPrivate *op = QObjectPrivate::get(m_object); - op->metaObject = 0; + qFree(m_data); + qFree(m_string); } int QMetaDataControlMetaObject::metaCall(QMetaObject::Call c, int id, void **a) @@ -184,15 +335,15 @@ int QMetaDataControlMetaObject::metaCall(QMetaObject::Call c, int id, void **a) if (c == QMetaObject::ReadProperty && id >= m_propertyOffset) { int propId = id - m_propertyOffset; - *reinterpret_cast(a[0]) = m_control->metaData(m_keys.at(propId)); + *reinterpret_cast(a[0]) = m_control->metaData(qt_metaDataKeys[propId].key); return -1; } else if (c == QMetaObject::WriteProperty && id >= m_propertyOffset) { int propId = id - m_propertyOffset; - m_control->setMetaData(m_keys.at(propId), *reinterpret_cast(a[0])); + m_control->setMetaData(qt_metaDataKeys[propId].key, *reinterpret_cast(a[0])); - activate(m_object, m_signalOffset + propId, 0); + activate(m_object, m_signalOffset, 0); return -1; } else { @@ -200,35 +351,14 @@ int QMetaDataControlMetaObject::metaCall(QMetaObject::Call c, int id, void **a) } } -int QMetaDataControlMetaObject::createProperty(const char *name, const char *) +int QMetaDataControlMetaObject::createProperty(const char *, const char *) { - const int count = sizeof(qt_metaDataKeys) / sizeof(MetaDataKey); - - for (int i = 0; i < count; ++i) { - if (qstrcmp(name, qt_metaDataKeys[i].name) == 0) { - int id = m_keys.count(); - m_keys.append(qt_metaDataKeys[i].key); - - m_builder.addSignal("__" + QByteArray::number(id) + "()"); - - QMetaPropertyBuilder build = m_builder.addProperty(name, "QVariant", id); - build.setDynamic(true); - - qFree(m_mem); - m_mem = m_builder.toMetaObject(); - *static_cast(this) = *m_mem; - - return m_propertyOffset + id; - } - } - return -1; } void QMetaDataControlMetaObject::metaDataChanged() { - for (int i = 0; i < m_keys.count(); ++i) - activate(m_object, m_signalOffset + i, 0); + activate(m_object, m_signalOffset, 0); } QT_END_NAMESPACE diff --git a/src/multimedia/qml/qmetadatacontrolmetaobject_p.h b/src/multimedia/qml/qmetadatacontrolmetaobject_p.h index b7f88fe..c0fd4e8 100644 --- a/src/multimedia/qml/qmetadatacontrolmetaobject_p.h +++ b/src/multimedia/qml/qmetadatacontrolmetaobject_p.h @@ -42,12 +42,10 @@ #ifndef QMETADATACONTROLMETAOBJECT_P_H #define QMETADATACONTROLMETAOJBECT_P_H +#include #include -#include #include -#include - QT_BEGIN_HEADER @@ -69,13 +67,11 @@ public: private: QMetaDataControl *m_control; QObject *m_object; - QMetaObject *m_mem; + char *m_string; + uint *m_data; int m_propertyOffset; int m_signalOffset; - - QVector m_keys; - QMetaObjectBuilder m_builder; }; QT_END_NAMESPACE -- cgit v0.12