From 56306f8403bd64b57f3da343e8b942ee1a9ea7a5 Mon Sep 17 00:00:00 2001 From: Filippo Cucchetto Date: Thu, 7 Jan 2016 12:04:40 +0100 Subject: [PATCH] Added support for QMetaObject inheritance and lots of renaming --- lib/CMakeLists.txt | 18 +-- lib/include/DOtherSide/DOtherSide.h | 7 +- lib/include/DOtherSide/DOtherSideTypesCpp.h | 12 +- ...actListModel.h => DosQAbstractListModel.h} | 12 +- lib/include/DOtherSide/DosQMetaObject.h | 97 ++++++++++++++ .../{DynamicQObject.h => DosQObject.h} | 13 +- ...{DynamicQObjectImpl.h => DosQObjectImpl.h} | 9 +- .../DOtherSide/DynamicQObjectFactory.h | 71 ---------- .../{IDynamicQObject.h => IDosQObject.h} | 4 +- .../DOtherSide/OnSlotExecutedHandler.h | 4 +- lib/include/DOtherSide/Utils.h | 1 + lib/src/DOtherSide.cpp | 51 +++++--- lib/src/DOtherSideTypesCpp.cpp | 2 + ...istModel.cpp => DosQAbstractListModel.cpp} | 44 +++---- lib/src/DosQMetaObject.cpp | 123 ++++++++++++++++++ lib/src/DosQObject.cpp | 37 ++++++ ...amicQObjectImpl.cpp => DosQObjectImpl.cpp} | 8 +- lib/src/DynamicQObject.cpp | 37 ------ lib/src/DynamicQObjectFactory.cpp | 72 ---------- lib/src/OnSlotExecutedHandler.cpp | 4 +- test/test_dotherside.cpp | 4 +- 21 files changed, 370 insertions(+), 260 deletions(-) rename lib/include/DOtherSide/{DynamicQAbstractListModel.h => DosQAbstractListModel.h} (91%) create mode 100644 lib/include/DOtherSide/DosQMetaObject.h rename lib/include/DOtherSide/{DynamicQObject.h => DosQObject.h} (70%) rename lib/include/DOtherSide/{DynamicQObjectImpl.h => DosQObjectImpl.h} (82%) delete mode 100644 lib/include/DOtherSide/DynamicQObjectFactory.h rename lib/include/DOtherSide/{IDynamicQObject.h => IDosQObject.h} (88%) rename lib/src/{DynamicQAbstractListModel.cpp => DosQAbstractListModel.cpp} (51%) create mode 100644 lib/src/DosQMetaObject.cpp create mode 100644 lib/src/DosQObject.cpp rename lib/src/{DynamicQObjectImpl.cpp => DosQObjectImpl.cpp} (91%) delete mode 100644 lib/src/DynamicQObject.cpp delete mode 100644 lib/src/DynamicQObjectFactory.cpp diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 581260a..6a14653 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -17,23 +17,23 @@ set(HEADERS_LIST include/DOtherSide/DOtherSideTypes.h include/DOtherSide/DOtherSideTypesCpp.h include/DOtherSide/DOtherSide.h - include/DOtherSide/IDynamicQObject.h + include/DOtherSide/IDosQObject.h include/DOtherSide/OnSlotExecutedHandler.h - include/DOtherSide/DynamicQObjectFactory.h - include/DOtherSide/DynamicQObject.h + include/DOtherSide/DosQMetaObject.h + include/DOtherSide/DosQObject.h + include/DOtherSide/DosQObjectImpl.h + include/DOtherSide/DosQAbstractListModel.h include/DOtherSide/Utils.h - include/DOtherSide/DynamicQObjectImpl.h - include/DOtherSide/DynamicQAbstractListModel.h ) set(SRC_LIST src/DOtherSide.cpp src/OnSlotExecutedHandler.cpp - src/DynamicQObjectFactory.cpp - src/DynamicQObject.cpp + src/DosQMetaObject.cpp + src/DosQObject.cpp src/DOtherSideTypesCpp.cpp - src/DynamicQObjectImpl.cpp - src/DynamicQAbstractListModel.cpp + src/DosQObjectImpl.cpp + src/DosQAbstractListModel.cpp ) include_directories(include include/Qt) diff --git a/lib/include/DOtherSide/DOtherSide.h b/lib/include/DOtherSide/DOtherSide.h index f0b9c9a..e72fb0c 100644 --- a/lib/include/DOtherSide/DOtherSide.h +++ b/lib/include/DOtherSide/DOtherSide.h @@ -87,13 +87,18 @@ 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, +DOS_API void dos_qmetaobject_create(void** vptr, void *superClassMetaObject, const char *className, SignalDefinitions signalDefinitions, SlotDefinitions slotDefinitions, PropertyDefinitions propertyDefinitions); DOS_API void dos_qmetaobject_delete(void* vptr); +// QAbstractListModel +DOS_API void dos_qabstractlistmodel_qmetaobject(void** vptr); + // QObject +DOS_API void dos_qobject_qmetaobject(void** vptr); + DOS_API void dos_qobject_create(void** vptr, void* dObjectPointer, MetaObjectCallback metaObjectCallback, DObjectCallback dObjectCallback); diff --git a/lib/include/DOtherSide/DOtherSideTypesCpp.h b/lib/include/DOtherSide/DOtherSideTypesCpp.h index 9af5dc2..efbf610 100644 --- a/lib/include/DOtherSide/DOtherSideTypesCpp.h +++ b/lib/include/DOtherSide/DOtherSideTypesCpp.h @@ -1,10 +1,11 @@ #pragma once +// std #include - +// Qt #include #include - +// DOtherSide #include "DOtherSide/DOtherSideTypes.h" #include "DOtherSide/Utils.h" @@ -90,10 +91,11 @@ SignalDefinitions toVector(const ::SignalDefinitions& cType); SlotDefinitions toVector(const ::SlotDefinitions& cType); PropertyDefinitions toVector(const ::PropertyDefinitions& cType); -class DynamicQObjectFactory; -class DynamicQObjectFactoryData; +class DosIQMetaObjectHolder; +class IDosQMetaObject; +class DosQMetaObject; -using OnMetaObject = std::function; +using OnMetaObject = std::function; using OnSlotExecuted = std::function&)>; class SafeQMetaObjectPtr diff --git a/lib/include/DOtherSide/DynamicQAbstractListModel.h b/lib/include/DOtherSide/DosQAbstractListModel.h similarity index 91% rename from lib/include/DOtherSide/DynamicQAbstractListModel.h rename to lib/include/DOtherSide/DosQAbstractListModel.h index 1863fbb..ddcf0e8 100644 --- a/lib/include/DOtherSide/DynamicQAbstractListModel.h +++ b/lib/include/DOtherSide/DosQAbstractListModel.h @@ -4,16 +4,16 @@ #include // DOtherSide #include "DOtherSide/DOtherSideTypes.h" -#include "DOtherSide/DynamicQObject.h" +#include "DOtherSide/DosQObject.h" namespace DOS { -class DynamicQAbstractListModel : public QAbstractListModel, public IDynamicQObject +class DosQAbstractListModel : public QAbstractListModel, public IDosQObject { public: /// Constructor - DynamicQAbstractListModel(void* modelObject, + DosQAbstractListModel(void* modelObject, RowCountCallback rowCountCallback, ColumnCountCallback columnCountCallback, DataCallback dataCallback, @@ -79,10 +79,10 @@ public: const QVector& roles = QVector()); /// Set the implementation - void setImpl(std::unique_ptr impl); + void setImpl(std::unique_ptr impl); private: - std::unique_ptr m_impl; + std::unique_ptr m_impl; void* m_modelObject; RowCountCallback m_rowCountCallback; ColumnCountCallback m_columnCountCallback; @@ -93,4 +93,4 @@ private: HeaderDataCallback m_headerDataCallback; }; -} +} // namespace DOS diff --git a/lib/include/DOtherSide/DosQMetaObject.h b/lib/include/DOtherSide/DosQMetaObject.h new file mode 100644 index 0000000..4392626 --- /dev/null +++ b/lib/include/DOtherSide/DosQMetaObject.h @@ -0,0 +1,97 @@ +#pragma once + +// std +#include +#include +#include +// Qt +#include +#include +#include +// DOtherSide +#include "DOtherSide/DOtherSideTypesCpp.h" + +namespace DOS +{ + +/// This the QMetaObject wrapper +class IDosQMetaObject +{ +public: + virtual ~IDosQMetaObject() = default; + virtual const QMetaObject* metaObject() const = 0; + virtual int signalSlotIndex(const QString& signalName) const = 0; + virtual int readSlotIndex(const char* propertyName) const = 0; + virtual int writeSlotIndex(const char* propertyName) const = 0; +}; + +/// Base class for any IDosQMetaObject +class BaseDosQMetaObject : public IDosQMetaObject +{ +public: + BaseDosQMetaObject(QMetaObject* metaObject) + : m_metaObject(metaObject) + {} + const QMetaObject *metaObject() const override { return m_metaObject; } + int signalSlotIndex(const QString &signalName) const override { return -1; } + int readSlotIndex(const char *propertyName) const override { return -1; } + int writeSlotIndex(const char *propertyName) const override { return -1; } + +private: + SafeQMetaObjectPtr m_metaObject; +}; + +/// This is the DosQMetaObject for a QObject +class DosQObjectMetaObject : public BaseDosQMetaObject +{ +public: + DosQObjectMetaObject(); +}; + +/// This is the DosQMetaObject for a QAbstractListModel +class DosQAbstractListModelMetaObject : public BaseDosQMetaObject +{ +public: + DosQAbstractListModelMetaObject(); +}; + +/// This the generic version used by subclasses of QObject or QAbstractListModels +class DosQMetaObject : public BaseDosQMetaObject +{ +public: + DosQMetaObject(const IDosQMetaObject& superClassMetaObject, + const QString& className, + const SignalDefinitions &signalDefinitions, + const SlotDefinitions &slotDefinitions, + const PropertyDefinitions &propertyDefinitions); + + int signalSlotIndex(const QString& signalName) const override; + int readSlotIndex(const char* propertyName) const override; + int writeSlotIndex(const char* propertyName) const override; + +private: + QMetaObject *createMetaObject(const IDosQMetaObject &superClassMetaObject, + const QString& className, + const SignalDefinitions &signalDefinitions, + const SlotDefinitions &slotDefinitions, + const PropertyDefinitions &propertyDefinitions); + + QHash m_signalIndexByName; + QHash> m_propertySlots; +}; + +/// This class simply holds a ptr to a IDosQMetaObject +class DosIQMetaObjectHolder +{ +public: + DosIQMetaObjectHolder(std::shared_ptr ptr) + : m_data(std::move(ptr)) + {} + + const std::shared_ptr& data() const { return m_data; } + +private: + std::shared_ptr m_data; +}; + +} // namespace DOS diff --git a/lib/include/DOtherSide/DynamicQObject.h b/lib/include/DOtherSide/DosQObject.h similarity index 70% rename from lib/include/DOtherSide/DynamicQObject.h rename to lib/include/DOtherSide/DosQObject.h index 6f37d58..f274186 100644 --- a/lib/include/DOtherSide/DynamicQObject.h +++ b/lib/include/DOtherSide/DosQObject.h @@ -1,20 +1,21 @@ #pragma once +// Qt #include #include - +// DOtherSide #include "DOtherSideTypesCpp.h" -#include "DOtherSide/IDynamicQObject.h" +#include "DOtherSide/IDosQObject.h" namespace DOS { /// This class model a QObject -class DynamicQObject : public QObject, public IDynamicQObject +class DosQObject : public QObject, public IDosQObject { public: /// Constructor - DynamicQObject(); + DosQObject(); /// Emit a signal bool emitSignal(const QString& name, const std::vector& arguments) override; @@ -26,10 +27,10 @@ public: int qt_metacall(QMetaObject::Call callType, int index, void**args) override; /// Set the implementation - void setImpl(std::unique_ptr impl); + void setImpl(std::unique_ptr impl); private: - std::unique_ptr m_impl; + std::unique_ptr m_impl; }; } // namespace DOS diff --git a/lib/include/DOtherSide/DynamicQObjectImpl.h b/lib/include/DOtherSide/DosQObjectImpl.h similarity index 82% rename from lib/include/DOtherSide/DynamicQObjectImpl.h rename to lib/include/DOtherSide/DosQObjectImpl.h index ec61f17..eea35a9 100644 --- a/lib/include/DOtherSide/DynamicQObjectImpl.h +++ b/lib/include/DOtherSide/DosQObjectImpl.h @@ -1,15 +1,18 @@ #pragma once +// std #include +// Qt #include #include -#include "DOtherSide/IDynamicQObject.h" +// DOtherSide +#include "DOtherSide/DosQObject.h" #include "DOtherSide/DOtherSideTypesCpp.h" namespace DOS { -class DynamicQObjectImpl : public IDynamicQObject +class DynamicQObjectImpl : public IDosQObject { public: DynamicQObjectImpl(QObject* parent, @@ -21,7 +24,7 @@ public: int qt_metacall(QMetaObject::Call callType, int index, void**args) override; private: - std::shared_ptr factory() const; + std::shared_ptr factory() const; bool executeSlot(int index, void** args); bool readProperty(int index, void** args); bool writeProperty(int index, void** args); diff --git a/lib/include/DOtherSide/DynamicQObjectFactory.h b/lib/include/DOtherSide/DynamicQObjectFactory.h deleted file mode 100644 index 6810f00..0000000 --- a/lib/include/DOtherSide/DynamicQObjectFactory.h +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include - -#include "DOtherSide/DOtherSideTypesCpp.h" - -namespace DOS -{ - -class DynamicQObjectFactoryData -{ -public: - DynamicQObjectFactoryData(SignalDefinitions signalDefinitions, - SlotDefinitions slotDefinitions, - PropertyDefinitions propertyDefinitions); - - inline const QMetaObject* metaObject() const; - inline int signalSlotIndex(const QString& signalName) const; - inline int readSlotIndex(const char* propertyName) const; - inline int writeSlotIndex(const char* propertyName) const; - -private: - SafeQMetaObjectPtr m_metaObject; - QHash m_signalIndexByName; - QHash> m_propertySlots; -}; - -const QMetaObject *DynamicQObjectFactoryData::metaObject() const -{ - return m_metaObject; -} - -inline int DynamicQObjectFactoryData::signalSlotIndex(const QString &signalName) const -{ - return m_metaObject->methodOffset() + m_signalIndexByName.value(signalName.toUtf8(), -1); -} - -inline int DynamicQObjectFactoryData::readSlotIndex(const char *propertyName) const -{ - return m_metaObject->methodOffset() + m_propertySlots.value(propertyName, {-1,-1}).first; -} - -inline int DynamicQObjectFactoryData::writeSlotIndex(const char *propertyName) const -{ - return m_metaObject->methodOffset() + m_propertySlots.value(propertyName, {-1,-1}).second; -} - -class DynamicQObjectFactory -{ -public: - DynamicQObjectFactory(SignalDefinitions signalDefinitions, - SlotDefinitions slotDefinitions, - PropertyDefinitions propertyDefinitions) - : m_data(std::make_shared(signalDefinitions, - slotDefinitions, - propertyDefinitions)) - {} - - std::shared_ptr data() const { return m_data; } - -private: - std::shared_ptr m_data; -}; - -} // namespace DOS diff --git a/lib/include/DOtherSide/IDynamicQObject.h b/lib/include/DOtherSide/IDosQObject.h similarity index 88% rename from lib/include/DOtherSide/IDynamicQObject.h rename to lib/include/DOtherSide/IDosQObject.h index 5833567..c252de4 100644 --- a/lib/include/DOtherSide/IDynamicQObject.h +++ b/lib/include/DOtherSide/IDosQObject.h @@ -5,11 +5,11 @@ class QMetaObject; namespace DOS { -class IDynamicQObject +class IDosQObject { public: /// Destructor - virtual ~IDynamicQObject() = default; + virtual ~IDosQObject() = default; /// Emit the signal with the given name and arguments virtual bool emitSignal(const QString& name, const std::vector& argumentsValues) = 0; diff --git a/lib/include/DOtherSide/OnSlotExecutedHandler.h b/lib/include/DOtherSide/OnSlotExecutedHandler.h index db95685..455455d 100644 --- a/lib/include/DOtherSide/OnSlotExecutedHandler.h +++ b/lib/include/DOtherSide/OnSlotExecutedHandler.h @@ -6,7 +6,7 @@ #include // DOtherSide #include "DOtherSide/DOtherSideTypesCpp.h" -#include "DOtherSide/IDynamicQObject.h" +#include "DOtherSide/DosQObject.h" namespace DOS { @@ -16,7 +16,7 @@ class OnMetaObjectHandler public: OnMetaObjectHandler(void* dObjectPointer, MetaObjectCallback dMetaObjectCallback); - DynamicQObjectFactory* operator()(); + DosIQMetaObjectHolder* operator()(); private: void* m_dObjectPointer; diff --git a/lib/include/DOtherSide/Utils.h b/lib/include/DOtherSide/Utils.h index 0e77e18..80c54e4 100644 --- a/lib/include/DOtherSide/Utils.h +++ b/lib/include/DOtherSide/Utils.h @@ -1,5 +1,6 @@ #pragma once +// std #include #include #include diff --git a/lib/src/DOtherSide.cpp b/lib/src/DOtherSide.cpp index 7eb144d..38804d4 100644 --- a/lib/src/DOtherSide.cpp +++ b/lib/src/DOtherSide.cpp @@ -15,9 +15,11 @@ #include "DOtherSide/DOtherSideTypesCpp.h" #include "DOtherSide/OnSlotExecutedHandler.h" -#include "DOtherSide/DynamicQObjectFactory.h" -#include "DOtherSide/DynamicQObject.h" -#include "DOtherSide/DynamicQObjectImpl.h" +#include "DOtherSide/DosQMetaObject.h" +#include "DOtherSide/DosQObject.h" +#include "DOtherSide/DosQObjectImpl.h" + +using namespace DOS; void convert_to_cstring(const QString& source, char** destination) @@ -362,10 +364,10 @@ void dos_qobject_create(void** vptr, void* dObjectPointer, DObjectCallback dObjectCallback) { - auto dynamicQObject = new DOS::DynamicQObject(); - auto impl = std::make_unique(dynamicQObject, - DOS::OnMetaObjectHandler(dObjectPointer, dMetaObjectCallback), - DOS::OnSlotExecutedHandler(dObjectPointer, dObjectCallback)); + auto dynamicQObject = new DosQObject(); + auto impl = std::make_unique(dynamicQObject, + OnMetaObjectHandler(dObjectPointer, dMetaObjectCallback), + OnSlotExecutedHandler(dObjectPointer, dObjectCallback)); dynamicQObject->setImpl(std::move(impl)); QQmlEngine::setObjectOwnership(dynamicQObject, QQmlEngine::CppOwnership); *vptr = dynamicQObject; @@ -381,10 +383,10 @@ void dos_qobject_delete(void* vptr) void dos_qobject_signal_emit(void* vptr, const char* name, int parametersCount, void** parameters) { auto qobject = reinterpret_cast(vptr); - auto dynamicQObject = dynamic_cast(qobject); + auto dynamicQObject = dynamic_cast(qobject); auto transformation = [](void* vptr)->QVariant{return *(reinterpret_cast(vptr));}; - const std::vector variants = DOS::toVector(parameters, parametersCount, transformation); + const std::vector variants = toVector(parameters, parametersCount, transformation); dynamicQObject->emitSignal(QString::fromStdString(name), variants); } @@ -528,17 +530,34 @@ void dos_qurl_to_string(void* vptr, char** result) } void dos_qmetaobject_create(void **vptr, - SignalDefinitions signalDefinitions, - SlotDefinitions slotDefinitions, - PropertyDefinitions propertyDefinitions) + void* superClassVPtr, + const char* className, + ::SignalDefinitions signalDefinitions, + ::SlotDefinitions slotDefinitions, + ::PropertyDefinitions propertyDefinitions) { - *vptr = new DOS::DynamicQObjectFactory(DOS::toVector(signalDefinitions), - DOS::toVector(slotDefinitions), - DOS::toVector(propertyDefinitions)); + auto superClassHolder = static_cast(superClassVPtr); + + auto metaObject = std::make_shared(*superClassHolder->data(), + QString::fromUtf8(className), + toVector(signalDefinitions), + toVector(slotDefinitions), + toVector(propertyDefinitions)); + *vptr = new DosIQMetaObjectHolder(std::move(metaObject)); } void dos_qmetaobject_delete(void *vptr) { - auto factory = reinterpret_cast(vptr); + auto factory = reinterpret_cast(vptr); delete factory; } + +void dos_qobject_qmetaobject(void **vptr) +{ + *vptr = new DosIQMetaObjectHolder(std::make_shared()); +} + +void dos_qabstractlistmodel_qmetaobject(void **vptr) +{ + *vptr = new DosIQMetaObjectHolder(std::make_shared()); +} diff --git a/lib/src/DOtherSideTypesCpp.cpp b/lib/src/DOtherSideTypesCpp.cpp index b595ddb..7b1fbe3 100644 --- a/lib/src/DOtherSideTypesCpp.cpp +++ b/lib/src/DOtherSideTypesCpp.cpp @@ -2,6 +2,7 @@ namespace DOS { + SignalDefinitions toVector(const ::SignalDefinitions& cType) { return toVector(cType.definitions, cType.count); @@ -16,4 +17,5 @@ PropertyDefinitions toVector(const ::PropertyDefinitions& cType) { return toVector(cType.definitions, cType.count); } + } // namespace DOS diff --git a/lib/src/DynamicQAbstractListModel.cpp b/lib/src/DosQAbstractListModel.cpp similarity index 51% rename from lib/src/DynamicQAbstractListModel.cpp rename to lib/src/DosQAbstractListModel.cpp index ba27ad9..d101aa6 100644 --- a/lib/src/DynamicQAbstractListModel.cpp +++ b/lib/src/DosQAbstractListModel.cpp @@ -1,9 +1,9 @@ -#include "DOtherSide/DynamicQAbstractListModel.h" +#include "DOtherSide/DosQAbstractListModel.h" namespace DOS { -DynamicQAbstractListModel::DynamicQAbstractListModel(void *modelObject, RowCountCallback rowCountCallback, ColumnCountCallback columnCountCallback, DataCallback dataCallback, SetDataCallback setDataCallback, RoleNamesCallback roleNamesCallback, FlagsCallback flagsCallback, HeaderDataCallback headerDataCallback) +DosQAbstractListModel::DosQAbstractListModel(void *modelObject, RowCountCallback rowCountCallback, ColumnCountCallback columnCountCallback, DataCallback dataCallback, SetDataCallback setDataCallback, RoleNamesCallback roleNamesCallback, FlagsCallback flagsCallback, HeaderDataCallback headerDataCallback) : m_impl(nullptr) , m_modelObject(modelObject) , m_rowCountCallback(rowCountCallback) @@ -16,22 +16,22 @@ DynamicQAbstractListModel::DynamicQAbstractListModel(void *modelObject, RowCount { } -bool DynamicQAbstractListModel::emitSignal(const QString &name, const std::vector &argumentsValues) +bool DosQAbstractListModel::emitSignal(const QString &name, const std::vector &argumentsValues) { return m_impl->emitSignal(name, argumentsValues); } -const QMetaObject *DynamicQAbstractListModel::metaObject() const +const QMetaObject *DosQAbstractListModel::metaObject() const { return m_impl->metaObject(); } -int DynamicQAbstractListModel::qt_metacall(QMetaObject::Call callType, int index, void **args) +int DosQAbstractListModel::qt_metacall(QMetaObject::Call callType, int index, void **args) { return m_impl->qt_metacall(callType, index, args); } -int DynamicQAbstractListModel::rowCount(const QModelIndex &parent) const +int DosQAbstractListModel::rowCount(const QModelIndex &parent) const { auto parentIndex = new QModelIndex(); *parentIndex = parent; @@ -40,7 +40,7 @@ int DynamicQAbstractListModel::rowCount(const QModelIndex &parent) const return result; } -int DynamicQAbstractListModel::columnCount(const QModelIndex &parent) const +int DosQAbstractListModel::columnCount(const QModelIndex &parent) const { auto parentIndex = new QModelIndex(); *parentIndex = parent; @@ -49,7 +49,7 @@ int DynamicQAbstractListModel::columnCount(const QModelIndex &parent) const return result; } -QVariant DynamicQAbstractListModel::data(const QModelIndex &index, int role) const +QVariant DosQAbstractListModel::data(const QModelIndex &index, int role) const { auto newIndex = new QModelIndex(); *newIndex = index; @@ -58,7 +58,7 @@ QVariant DynamicQAbstractListModel::data(const QModelIndex &index, int role) con return result; } -bool DynamicQAbstractListModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool DosQAbstractListModel::setData(const QModelIndex &index, const QVariant &value, int role) { auto newIndex = new QModelIndex(index); *newIndex = index; @@ -69,7 +69,7 @@ bool DynamicQAbstractListModel::setData(const QModelIndex &index, const QVariant return result; } -Qt::ItemFlags DynamicQAbstractListModel::flags(const QModelIndex &index) const +Qt::ItemFlags DosQAbstractListModel::flags(const QModelIndex &index) const { auto newIndex = new QModelIndex(index); *newIndex = index; @@ -78,63 +78,63 @@ Qt::ItemFlags DynamicQAbstractListModel::flags(const QModelIndex &index) const return Qt::ItemFlags(result); } -QVariant DynamicQAbstractListModel::headerData(int section, Qt::Orientation orientation, int role) const +QVariant DosQAbstractListModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant result; m_headerDataCallback(m_modelObject, section, orientation, role, &result); return result; } -void *DynamicQAbstractListModel::modelObject() +void *DosQAbstractListModel::modelObject() { return m_modelObject; } -QHash DynamicQAbstractListModel::roleNames() const +QHash DosQAbstractListModel::roleNames() const { QHash result; m_roleNamesCallback(m_modelObject, &result); return result; } -void DynamicQAbstractListModel::publicBeginInsertRows(const QModelIndex &index, int first, int last) +void DosQAbstractListModel::publicBeginInsertRows(const QModelIndex &index, int first, int last) { beginInsertRows(index, first, last); } -void DynamicQAbstractListModel::publicEndInsertRows() +void DosQAbstractListModel::publicEndInsertRows() { return endInsertRows(); } -void DynamicQAbstractListModel::publicBeginRemoveRows(const QModelIndex &index, int first, int last) +void DosQAbstractListModel::publicBeginRemoveRows(const QModelIndex &index, int first, int last) { beginRemoveRows(index, first, last); } -void DynamicQAbstractListModel::publicEndRemoveRows() +void DosQAbstractListModel::publicEndRemoveRows() { return endRemoveRows(); } -void DynamicQAbstractListModel::publicBeginResetModel() +void DosQAbstractListModel::publicBeginResetModel() { beginResetModel(); } -void DynamicQAbstractListModel::publicEndResetModel() +void DosQAbstractListModel::publicEndResetModel() { endResetModel(); } -void DynamicQAbstractListModel::publicDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) +void DosQAbstractListModel::publicDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) { emit dataChanged(topLeft, bottomRight, roles); } -void DynamicQAbstractListModel::setImpl(std::unique_ptr impl) +void DosQAbstractListModel::setImpl(std::unique_ptr impl) { m_impl = std::move(impl); } -} +} // namespace DOS diff --git a/lib/src/DosQMetaObject.cpp b/lib/src/DosQMetaObject.cpp new file mode 100644 index 0000000..0651681 --- /dev/null +++ b/lib/src/DosQMetaObject.cpp @@ -0,0 +1,123 @@ +#include "DOtherSide/DosQMetaObject.h" +#include "DOtherSide/DosQObject.h" +#include "private/qmetaobjectbuilder_p.h" +#include "private/qmetaobject_p.h" +#include "private/qobject_p.h" +#include + +namespace +{ + +template +QByteArray createSignature(const T& functionDefinition) +{ + QString signature("%1(%2)"); + QString arguments; + + for (int type : functionDefinition.parameterTypes) { + if (type != functionDefinition.parameterTypes.front()) + arguments += QLatin1Char(','); + arguments += QMetaType::typeName(type); + } + + return signature.arg(functionDefinition.name, arguments).toUtf8(); +} + +QMetaObject* createDynamicQObjectMetaObject() +{ + QMetaObjectBuilder builder; + builder.setClassName("DynamicQObject"); + builder.setSuperClass(&QObject::staticMetaObject); + return builder.toMetaObject(); +} + +QMetaObject* createDynamicQAbstractListModelMetaObject() +{ + QMetaObjectBuilder builder; + builder.setClassName("DynamicQAbstractListModel"); + builder.setSuperClass(&QAbstractListModel::staticMetaObject); + return builder.toMetaObject(); +} + +} + +namespace DOS +{ + +DosQObjectMetaObject::DosQObjectMetaObject() + : BaseDosQMetaObject(::createDynamicQObjectMetaObject()) +{} + +DosQAbstractListModelMetaObject::DosQAbstractListModelMetaObject() + : BaseDosQMetaObject(::createDynamicQAbstractListModelMetaObject()) +{} + +DosQMetaObject::DosQMetaObject(const IDosQMetaObject &superClassMetaObject, + const QString &className, + const SignalDefinitions& signalDefinitions, + const SlotDefinitions& slotDefinitions, + const PropertyDefinitions& propertyDefinitions) + : BaseDosQMetaObject(createMetaObject(superClassMetaObject, className, signalDefinitions, slotDefinitions, propertyDefinitions)) +{ +} + +QMetaObject *DosQMetaObject::createMetaObject(const IDosQMetaObject &superClassMetaObject, + const QString &className, + const SignalDefinitions& signalDefinitions, + const SlotDefinitions& slotDefinitions, + const PropertyDefinitions& propertyDefinitions) +{ + QMetaObjectBuilder builder; + builder.setClassName(className.toUtf8()); + 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(); + } + + QHash 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(); + } + + for (const PropertyDefinition& property : propertyDefinitions) + { + const int notifier = m_signalIndexByName.value(property.notifySignal.toUtf8(), -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)}; + } + + return builder.toMetaObject(); +} + +int DosQMetaObject::signalSlotIndex(const QString &signalName) const +{ + return metaObject()->methodOffset() + m_signalIndexByName.value(signalName.toUtf8(), -1); +} + +int DosQMetaObject::readSlotIndex(const char *propertyName) const +{ + return metaObject()->methodOffset() + m_propertySlots.value(propertyName, {-1,-1}).first; +} + +int DosQMetaObject::writeSlotIndex(const char *propertyName) const +{ + return metaObject()->methodOffset() + m_propertySlots.value(propertyName, {-1,-1}).second; +} + +} // namespace DOS diff --git a/lib/src/DosQObject.cpp b/lib/src/DosQObject.cpp new file mode 100644 index 0000000..2118431 --- /dev/null +++ b/lib/src/DosQObject.cpp @@ -0,0 +1,37 @@ +#include "DOtherSide/DosQObject.h" +#include "DOtherSide/DosQMetaObject.h" +#include +#include + +namespace DOS +{ + +DosQObject::DosQObject() + : m_impl(nullptr) +{ +} + +bool DosQObject::emitSignal(const QString &name, const std::vector &args) +{ + Q_ASSERT(m_impl); + return m_impl->emitSignal(name, args); +} + +const QMetaObject *DosQObject::metaObject() const +{ + Q_ASSERT(m_impl); + return m_impl->metaObject(); +} + +int DosQObject::qt_metacall(QMetaObject::Call callType, int index, void** args) +{ + Q_ASSERT(m_impl); + return m_impl->qt_metacall(callType, index, args); +} + +void DosQObject::setImpl(std::unique_ptr impl) +{ + m_impl = std::move(impl); +} + +} // namespace DOS diff --git a/lib/src/DynamicQObjectImpl.cpp b/lib/src/DosQObjectImpl.cpp similarity index 91% rename from lib/src/DynamicQObjectImpl.cpp rename to lib/src/DosQObjectImpl.cpp index 62a09d9..a471cf0 100644 --- a/lib/src/DynamicQObjectImpl.cpp +++ b/lib/src/DosQObjectImpl.cpp @@ -1,5 +1,5 @@ -#include "DOtherSide/DynamicQObjectImpl.h" -#include "DOtherSide/DynamicQObjectFactory.h" +#include "DOtherSide/DosQObjectImpl.h" +#include "DOtherSide/DosQMetaObject.h" #include #include @@ -55,9 +55,9 @@ int DynamicQObjectImpl::qt_metacall(QMetaObject::Call callType, int index, void return -1; } -std::shared_ptr DynamicQObjectImpl::factory() const +std::shared_ptr DynamicQObjectImpl::factory() const { - static std::shared_ptr result = m_onMetaObject()->data(); + static std::shared_ptr result = m_onMetaObject()->data(); return result; } diff --git a/lib/src/DynamicQObject.cpp b/lib/src/DynamicQObject.cpp deleted file mode 100644 index 9d96223..0000000 --- a/lib/src/DynamicQObject.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "DOtherSide/DynamicQObject.h" -#include "DOtherSide/DynamicQObjectFactory.h" -#include -#include - -namespace DOS -{ - -DynamicQObject::DynamicQObject() - : m_impl(nullptr) -{ -} - -bool DynamicQObject::emitSignal(const QString &name, const std::vector &args) -{ - Q_ASSERT(m_impl); - return m_impl->emitSignal(name, args); -} - -const QMetaObject *DynamicQObject::metaObject() const -{ - Q_ASSERT(m_impl); - return m_impl->metaObject(); -} - -int DynamicQObject::qt_metacall(QMetaObject::Call callType, int index, void** args) -{ - Q_ASSERT(m_impl); - return m_impl->qt_metacall(callType, index, args); -} - -void DynamicQObject::setImpl(std::unique_ptr impl) -{ - m_impl = std::move(impl); -} - -} // namespace DOS diff --git a/lib/src/DynamicQObjectFactory.cpp b/lib/src/DynamicQObjectFactory.cpp deleted file mode 100644 index 1405615..0000000 --- a/lib/src/DynamicQObjectFactory.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "DOtherSide/DynamicQObjectFactory.h" -#include "DOtherSide/DynamicQObject.h" -#include "private/qmetaobjectbuilder_p.h" -#include "private/qmetaobject_p.h" -#include "private/qobject_p.h" - -namespace -{ -template -QByteArray createSignature(const T& functionDefinition) -{ - QString signature("%1(%2)"); - QString arguments; - - for (int type : functionDefinition.parameterTypes) { - if (type != functionDefinition.parameterTypes.front()) - arguments += QLatin1Char(','); - arguments += QMetaType::typeName(type); - } - - return signature.arg(functionDefinition.name, arguments).toUtf8(); -} -} - -namespace DOS -{ - -DynamicQObjectFactoryData::DynamicQObjectFactoryData(SignalDefinitions signalDefinitions, - SlotDefinitions slotDefinitions, - PropertyDefinitions propertyDefinitions) - : m_metaObject(nullptr) -{ - QMetaObjectBuilder builder; - builder.setFlags(QMetaObjectBuilder::DynamicMetaObject); - builder.setClassName("DynamicQObject"); - builder.setSuperClass(&QObject::staticMetaObject); - - 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(); - } - - QHash 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(); - } - - for (const PropertyDefinition& property : propertyDefinitions) - { - const int notifier = m_signalIndexByName.value(property.notifySignal.toUtf8(), -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_metaObject.reset(builder.toMetaObject()); -} - -} // namespace DOS diff --git a/lib/src/OnSlotExecutedHandler.cpp b/lib/src/OnSlotExecutedHandler.cpp index 4721130..34175f8 100644 --- a/lib/src/OnSlotExecutedHandler.cpp +++ b/lib/src/OnSlotExecutedHandler.cpp @@ -37,9 +37,9 @@ OnMetaObjectHandler::OnMetaObjectHandler(void *dObjectPointer, MetaObjectCallbac , m_dMetaObjectCallback(dMetaObjectCallback) {} -DynamicQObjectFactory* OnMetaObjectHandler::operator()() +DosIQMetaObjectHolder* OnMetaObjectHandler::operator()() { - DynamicQObjectFactory* result = nullptr; + DosIQMetaObjectHolder* result = nullptr; m_dMetaObjectCallback(m_dObjectPointer, reinterpret_cast(&result)); return result; } diff --git a/test/test_dotherside.cpp b/test/test_dotherside.cpp index 4580743..4191fcd 100644 --- a/test/test_dotherside.cpp +++ b/test/test_dotherside.cpp @@ -13,8 +13,8 @@ // DOtherSide #include "DOtherSide/DOtherSide.h" -#include "DOtherSide/DynamicQObject.h" -#include "DOtherSide/DynamicQObjectFactory.h" +#include "DOtherSide/DosQObject.h" +#include "DOtherSide/DosQMetaObject.h" template bool ExecuteTest(int argc, char* argv[]) {