Added support for QMetaObject inheritance and lots of renaming

This commit is contained in:
Filippo Cucchetto 2016-01-07 12:04:40 +01:00
parent d0e0079fcf
commit 56306f8403
21 changed files with 370 additions and 260 deletions

View File

@ -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)

View File

@ -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);

View File

@ -1,10 +1,11 @@
#pragma once
// std
#include <memory>
// Qt
#include <QtCore/QString>
#include <QtCore/QMetaType>
// 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<DynamicQObjectFactory*()>;
using OnMetaObject = std::function<DosIQMetaObjectHolder*()>;
using OnSlotExecuted = std::function<QVariant(const QString&, const std::vector<QVariant>&)>;
class SafeQMetaObjectPtr

View File

@ -4,16 +4,16 @@
#include <QAbstractListModel>
// 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<int>& roles = QVector<int>());
/// Set the implementation
void setImpl(std::unique_ptr<IDynamicQObject> impl);
void setImpl(std::unique_ptr<IDosQObject> impl);
private:
std::unique_ptr<IDynamicQObject> m_impl;
std::unique_ptr<IDosQObject> m_impl;
void* m_modelObject;
RowCountCallback m_rowCountCallback;
ColumnCountCallback m_columnCountCallback;
@ -93,4 +93,4 @@ private:
HeaderDataCallback m_headerDataCallback;
};
}
} // namespace DOS

View File

@ -0,0 +1,97 @@
#pragma once
// std
#include <memory>
#include <unordered_map>
#include <tuple>
// Qt
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QHash>
// 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<QByteArray, int> m_signalIndexByName;
QHash<QByteArray, QPair<int,int>> m_propertySlots;
};
/// This class simply holds a ptr to a IDosQMetaObject
class DosIQMetaObjectHolder
{
public:
DosIQMetaObjectHolder(std::shared_ptr<IDosQMetaObject> ptr)
: m_data(std::move(ptr))
{}
const std::shared_ptr<const IDosQMetaObject>& data() const { return m_data; }
private:
std::shared_ptr<const IDosQMetaObject> m_data;
};
} // namespace DOS

View File

@ -1,20 +1,21 @@
#pragma once
// Qt
#include <QObject>
#include <functional>
// 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<QVariant>& 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<IDynamicQObject> impl);
void setImpl(std::unique_ptr<IDosQObject> impl);
private:
std::unique_ptr<IDynamicQObject> m_impl;
std::unique_ptr<IDosQObject> m_impl;
};
} // namespace DOS

View File

@ -1,15 +1,18 @@
#pragma once
// std
#include <vector>
// Qt
#include <QtCore/QString>
#include <QtCore/QVariant>
#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<const DynamicQObjectFactoryData> factory() const;
std::shared_ptr<const DOS::IDosQMetaObject> factory() const;
bool executeSlot(int index, void** args);
bool readProperty(int index, void** args);
bool writeProperty(int index, void** args);

View File

@ -1,71 +0,0 @@
#pragma once
#include <memory>
#include <unordered_map>
#include <tuple>
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QHash>
#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<QByteArray, int> m_signalIndexByName;
QHash<QByteArray, QPair<int,int>> 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<DynamicQObjectFactoryData>(signalDefinitions,
slotDefinitions,
propertyDefinitions))
{}
std::shared_ptr<const DynamicQObjectFactoryData> data() const { return m_data; }
private:
std::shared_ptr<const DynamicQObjectFactoryData> m_data;
};
} // namespace DOS

View File

@ -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<QVariant>& argumentsValues) = 0;

View File

@ -6,7 +6,7 @@
#include <QVariant>
// 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;

View File

@ -1,5 +1,6 @@
#pragma once
// std
#include <algorithm>
#include <functional>
#include <type_traits>

View File

@ -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<DOS::DynamicQObjectImpl>(dynamicQObject,
DOS::OnMetaObjectHandler(dObjectPointer, dMetaObjectCallback),
DOS::OnSlotExecutedHandler(dObjectPointer, dObjectCallback));
auto dynamicQObject = new DosQObject();
auto impl = std::make_unique<DynamicQObjectImpl>(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<QObject*>(vptr);
auto dynamicQObject = dynamic_cast<DOS::IDynamicQObject*>(qobject);
auto dynamicQObject = dynamic_cast<IDosQObject*>(qobject);
auto transformation = [](void* vptr)->QVariant{return *(reinterpret_cast<QVariant*>(vptr));};
const std::vector<QVariant> variants = DOS::toVector(parameters, parametersCount, transformation);
const std::vector<QVariant> 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<DosIQMetaObjectHolder*>(superClassVPtr);
auto metaObject = std::make_shared<DosQMetaObject>(*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<DOS::DynamicQObjectFactory*>(vptr);
auto factory = reinterpret_cast<DosIQMetaObjectHolder*>(vptr);
delete factory;
}
void dos_qobject_qmetaobject(void **vptr)
{
*vptr = new DosIQMetaObjectHolder(std::make_shared<DosQObjectMetaObject>());
}
void dos_qabstractlistmodel_qmetaobject(void **vptr)
{
*vptr = new DosIQMetaObjectHolder(std::make_shared<DosQAbstractListModelMetaObject>());
}

View File

@ -2,6 +2,7 @@
namespace DOS
{
SignalDefinitions toVector(const ::SignalDefinitions& cType)
{
return toVector<SignalDefinition>(cType.definitions, cType.count);
@ -16,4 +17,5 @@ PropertyDefinitions toVector(const ::PropertyDefinitions& cType)
{
return toVector<PropertyDefinition>(cType.definitions, cType.count);
}
} // namespace DOS

View File

@ -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<QVariant> &argumentsValues)
bool DosQAbstractListModel::emitSignal(const QString &name, const std::vector<QVariant> &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<int, QByteArray> DynamicQAbstractListModel::roleNames() const
QHash<int, QByteArray> DosQAbstractListModel::roleNames() const
{
QHash<int, QByteArray> 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<int> &roles)
void DosQAbstractListModel::publicDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
emit dataChanged(topLeft, bottomRight, roles);
}
void DynamicQAbstractListModel::setImpl(std::unique_ptr<IDynamicQObject> impl)
void DosQAbstractListModel::setImpl(std::unique_ptr<IDosQObject> impl)
{
m_impl = std::move(impl);
}
}
} // namespace DOS

123
lib/src/DosQMetaObject.cpp Normal file
View File

@ -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 <QtCore/QAbstractListModel>
namespace
{
template<class T>
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<QString, int> 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

37
lib/src/DosQObject.cpp Normal file
View File

@ -0,0 +1,37 @@
#include "DOtherSide/DosQObject.h"
#include "DOtherSide/DosQMetaObject.h"
#include <QtCore/QMetaMethod>
#include <QtCore/QDebug>
namespace DOS
{
DosQObject::DosQObject()
: m_impl(nullptr)
{
}
bool DosQObject::emitSignal(const QString &name, const std::vector<QVariant> &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<IDosQObject> impl)
{
m_impl = std::move(impl);
}
} // namespace DOS

View File

@ -1,5 +1,5 @@
#include "DOtherSide/DynamicQObjectImpl.h"
#include "DOtherSide/DynamicQObjectFactory.h"
#include "DOtherSide/DosQObjectImpl.h"
#include "DOtherSide/DosQMetaObject.h"
#include <QtCore/QMetaObject>
#include <QtCore/QMetaMethod>
@ -55,9 +55,9 @@ int DynamicQObjectImpl::qt_metacall(QMetaObject::Call callType, int index, void
return -1;
}
std::shared_ptr<const DynamicQObjectFactoryData> DynamicQObjectImpl::factory() const
std::shared_ptr<const IDosQMetaObject> DynamicQObjectImpl::factory() const
{
static std::shared_ptr<const DynamicQObjectFactoryData> result = m_onMetaObject()->data();
static std::shared_ptr<const IDosQMetaObject> result = m_onMetaObject()->data();
return result;
}

View File

@ -1,37 +0,0 @@
#include "DOtherSide/DynamicQObject.h"
#include "DOtherSide/DynamicQObjectFactory.h"
#include <QtCore/QMetaMethod>
#include <QtCore/QDebug>
namespace DOS
{
DynamicQObject::DynamicQObject()
: m_impl(nullptr)
{
}
bool DynamicQObject::emitSignal(const QString &name, const std::vector<QVariant> &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<IDynamicQObject> impl)
{
m_impl = std::move(impl);
}
} // namespace DOS

View File

@ -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<class T>
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<QString, int> 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

View File

@ -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<void**>(&result));
return result;
}

View File

@ -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<typename Test>
bool ExecuteTest(int argc, char* argv[]) {