From e5457adc859c00d2edf8a5c53f1886c573c2f87f Mon Sep 17 00:00:00 2001 From: Filippo Cucchetto Date: Thu, 7 Jan 2016 13:24:52 +0100 Subject: [PATCH] Bug fixing --- lib/include/DOtherSide/DOtherSide.h | 6 ++-- lib/include/DOtherSide/DosQMetaObject.h | 8 ++++-- lib/src/DOtherSide.cpp | 6 +++- lib/src/DosQMetaObject.cpp | 38 +++++++++++++++++-------- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/lib/include/DOtherSide/DOtherSide.h b/lib/include/DOtherSide/DOtherSide.h index e72fb0c..6e6298c 100644 --- a/lib/include/DOtherSide/DOtherSide.h +++ b/lib/include/DOtherSide/DOtherSide.h @@ -86,8 +86,10 @@ DOS_API void dos_qvariant_isnull(void* vptr, bool* result); DOS_API void dos_qvariant_delete(void* vptr); DOS_API void dos_qvariant_assign(void* vptr, void* other); -// QObjectFactory -DOS_API void dos_qmetaobject_create(void** vptr, void *superClassMetaObject, const char *className, +// QMetaObject +DOS_API void dos_qmetaobject_create(void** vptr, + void *superClassMetaObject, + const char *className, SignalDefinitions signalDefinitions, SlotDefinitions slotDefinitions, PropertyDefinitions propertyDefinitions); diff --git a/lib/include/DOtherSide/DosQMetaObject.h b/lib/include/DOtherSide/DosQMetaObject.h index 4392626..e4848b7 100644 --- a/lib/include/DOtherSide/DosQMetaObject.h +++ b/lib/include/DOtherSide/DosQMetaObject.h @@ -56,7 +56,7 @@ public: }; /// This the generic version used by subclasses of QObject or QAbstractListModels -class DosQMetaObject : public BaseDosQMetaObject +class DosQMetaObject : public IDosQMetaObject { public: DosQMetaObject(const IDosQMetaObject& superClassMetaObject, @@ -68,6 +68,7 @@ public: int signalSlotIndex(const QString& signalName) const override; int readSlotIndex(const char* propertyName) const override; int writeSlotIndex(const char* propertyName) const override; + const QMetaObject *metaObject() const override; private: QMetaObject *createMetaObject(const IDosQMetaObject &superClassMetaObject, @@ -76,8 +77,9 @@ private: const SlotDefinitions &slotDefinitions, const PropertyDefinitions &propertyDefinitions); - QHash m_signalIndexByName; - QHash> m_propertySlots; + SafeQMetaObjectPtr m_metaObject; + std::unordered_map m_signalIndexByName; + std::unordered_map> m_propertySlots; }; /// This class simply holds a ptr to a IDosQMetaObject diff --git a/lib/src/DOtherSide.cpp b/lib/src/DOtherSide.cpp index 38804d4..9ac5662 100644 --- a/lib/src/DOtherSide.cpp +++ b/lib/src/DOtherSide.cpp @@ -536,9 +536,13 @@ void dos_qmetaobject_create(void **vptr, ::SlotDefinitions slotDefinitions, ::PropertyDefinitions propertyDefinitions) { + Q_ASSERT(superClassVPtr); auto superClassHolder = static_cast(superClassVPtr); + Q_ASSERT(superClassHolder); + auto data = superClassHolder->data(); + Q_ASSERT(data); - auto metaObject = std::make_shared(*superClassHolder->data(), + auto metaObject = std::make_shared(*data, QString::fromUtf8(className), toVector(signalDefinitions), toVector(slotDefinitions), diff --git a/lib/src/DosQMetaObject.cpp b/lib/src/DosQMetaObject.cpp index 0651681..d46c3fc 100644 --- a/lib/src/DosQMetaObject.cpp +++ b/lib/src/DosQMetaObject.cpp @@ -23,10 +23,18 @@ QByteArray createSignature(const T& functionDefinition) return signature.arg(functionDefinition.name, arguments).toUtf8(); } +template +Value valueOrDefault(std::unordered_map const& map, const Key& k, Value value) +{ + auto it = map.find(k); + return it != std::end(map) ? it->second : std::move(value); +} + QMetaObject* createDynamicQObjectMetaObject() { QMetaObjectBuilder builder; builder.setClassName("DynamicQObject"); + builder.setFlags(QMetaObjectBuilder::DynamicMetaObject); builder.setSuperClass(&QObject::staticMetaObject); return builder.toMetaObject(); } @@ -34,6 +42,7 @@ QMetaObject* createDynamicQObjectMetaObject() QMetaObject* createDynamicQAbstractListModelMetaObject() { QMetaObjectBuilder builder; + builder.setFlags(QMetaObjectBuilder::DynamicMetaObject); builder.setClassName("DynamicQAbstractListModel"); builder.setSuperClass(&QAbstractListModel::staticMetaObject); return builder.toMetaObject(); @@ -57,8 +66,9 @@ DosQMetaObject::DosQMetaObject(const IDosQMetaObject &superClassMetaObject, const SignalDefinitions& signalDefinitions, const SlotDefinitions& slotDefinitions, const PropertyDefinitions& propertyDefinitions) - : BaseDosQMetaObject(createMetaObject(superClassMetaObject, className, signalDefinitions, slotDefinitions, propertyDefinitions)) + : m_metaObject(nullptr) { + m_metaObject.reset(createMetaObject(superClassMetaObject, className, signalDefinitions, slotDefinitions, propertyDefinitions)); } QMetaObject *DosQMetaObject::createMetaObject(const IDosQMetaObject &superClassMetaObject, @@ -69,37 +79,36 @@ QMetaObject *DosQMetaObject::createMetaObject(const IDosQMetaObject &superClassM { QMetaObjectBuilder builder; builder.setClassName(className.toUtf8()); + builder.setFlags(QMetaObjectBuilder::DynamicMetaObject); builder.setSuperClass(superClassMetaObject.metaObject()); - m_signalIndexByName.reserve(signalDefinitions.size()); - for (const SignalDefinition& signal : signalDefinitions) { QMetaMethodBuilder signalBuilder = builder.addSignal(::createSignature(signal)); signalBuilder.setReturnType(QMetaType::typeName(QMetaType::Void)); signalBuilder.setAccess(QMetaMethod::Public); - m_signalIndexByName[signal.name.toUtf8()] = signalBuilder.index(); + m_signalIndexByName[signal.name.toStdString()] = signalBuilder.index(); } - QHash methodIndexByName; + std::unordered_map methodIndexByName; for (const SlotDefinition& slot : slotDefinitions) { QMetaMethodBuilder methodBuilder = builder.addSlot(::createSignature(slot)); methodBuilder.setReturnType(QMetaType::typeName(slot.returnType)); methodBuilder.setAttributes(QMetaMethod::Scriptable); - methodIndexByName[slot.name] = methodBuilder.index(); + methodIndexByName[slot.name.toStdString()] = methodBuilder.index(); } for (const PropertyDefinition& property : propertyDefinitions) { - const int notifier = m_signalIndexByName.value(property.notifySignal.toUtf8(), -1); + const int notifier = ::valueOrDefault(m_signalIndexByName, property.notifySignal.toStdString(), -1); const QByteArray name = property.name.toUtf8(); const QByteArray typeName = QMetaObject::normalizedType(QMetaType::typeName(property.type)); QMetaPropertyBuilder propertyBuilder = builder.addProperty(name, typeName, notifier); if (notifier == -1) propertyBuilder.setConstant(true); - m_propertySlots[propertyBuilder.name()] = { methodIndexByName.value(property.readSlot, -1) - , methodIndexByName.value(property.writeSlot, -1)}; + m_propertySlots[propertyBuilder.name().toStdString()] = std::make_pair(::valueOrDefault(methodIndexByName, property.readSlot.toStdString(), -1), + ::valueOrDefault(methodIndexByName, property.writeSlot.toStdString(), -1)); } return builder.toMetaObject(); @@ -107,17 +116,22 @@ QMetaObject *DosQMetaObject::createMetaObject(const IDosQMetaObject &superClassM int DosQMetaObject::signalSlotIndex(const QString &signalName) const { - return metaObject()->methodOffset() + m_signalIndexByName.value(signalName.toUtf8(), -1); + return metaObject()->methodOffset() + ::valueOrDefault(m_signalIndexByName, signalName.toStdString(), -1); } int DosQMetaObject::readSlotIndex(const char *propertyName) const { - return metaObject()->methodOffset() + m_propertySlots.value(propertyName, {-1,-1}).first; + return metaObject()->methodOffset() + ::valueOrDefault(m_propertySlots, std::string(propertyName), std::make_pair(-1,-1)).first; } int DosQMetaObject::writeSlotIndex(const char *propertyName) const { - return metaObject()->methodOffset() + m_propertySlots.value(propertyName, {-1,-1}).second; + return metaObject()->methodOffset() + valueOrDefault(m_propertySlots, std::string(propertyName), std::make_pair(-1,-1)).second; +} + +const QMetaObject *DosQMetaObject::metaObject() const +{ + return m_metaObject; } } // namespace DOS