#pragma once #include "DOtherSide/DosQObject.h" #include "DOtherSide/DosQMetaObject.h" #include namespace DOS { template class DosQObjectWrapper : public QObject, public DosIQObjectImpl { public: static const QMetaObject staticMetaObject; /// Constructor DosQObjectWrapper(QObject *parent = nullptr); /// Destructor ~DosQObjectWrapper(); /// @see DosIQObjectImpl::metaObject const QMetaObject *metaObject() const override; /// @see DosIQObjectImpl::qt_metacall int qt_metacall(QMetaObject::Call, int, void **) override; /// @see DosIQObjectImpl::emitSignal bool emitSignal(QObject* emitter, const QString &name, const std::vector &argumentsValues); static const QmlRegisterType &qmlRegisterType(); static void setQmlRegisterType(QmlRegisterType data); static void setStaticMetaObject(const QMetaObject &metaObject); static void setId(int id); private: void *m_dObject; DosQObject *m_impl; static int m_id; static QmlRegisterType m_data; }; template const QMetaObject DosQObjectWrapper::staticMetaObject = QObject::staticMetaObject; template QmlRegisterType DosQObjectWrapper::m_data; template int DosQObjectWrapper::m_id = -1; template DosQObjectWrapper::DosQObjectWrapper(QObject *parent) : QObject(parent) , m_dObject(nullptr) , m_impl(nullptr) { void *impl = nullptr; m_data.createDObject(m_id, static_cast(this), &m_dObject, &impl); m_impl = dynamic_cast(static_cast(impl)); Q_ASSERT(m_dObject); Q_ASSERT(m_impl); } template DosQObjectWrapper::~DosQObjectWrapper() { m_data.deleteDObject(m_id, m_dObject); m_dObject = nullptr; delete dynamic_cast(m_impl); m_impl = nullptr; } template const QMetaObject *DosQObjectWrapper::metaObject() const { Q_ASSERT(m_impl); return m_impl->metaObject(); } template int DosQObjectWrapper::qt_metacall(QMetaObject::Call call, int index, void **args) { Q_ASSERT(m_impl); return m_impl->qt_metacall(call, index, args); } template bool DosQObjectWrapper::emitSignal(QObject* emitter, const QString &name, const std::vector &argumentsValues) { Q_ASSERT(m_impl); return m_impl->emitSignal(this, name, argumentsValues); } template void DosQObjectWrapper::setQmlRegisterType(QmlRegisterType data) { m_data = std::move(data); } template void DosQObjectWrapper::setStaticMetaObject(const QMetaObject &metaObject) { *(const_cast(&staticMetaObject)) = metaObject; } template void DosQObjectWrapper::setId(int id) { m_id = id; } template const QmlRegisterType &DosQObjectWrapper::qmlRegisterType() { return m_data; } namespace DQOW { template using RegisterTypeQObject = DosQObjectWrapper; template int dosQmlRegisterType(QmlRegisterType args) { RegisterTypeQObject::setQmlRegisterType(std::move(args)); const QmlRegisterType &type = RegisterTypeQObject::qmlRegisterType(); RegisterTypeQObject::setStaticMetaObject(*(type.staticMetaObject->metaObject())); int result = qmlRegisterType>(type.uri.c_str(), type.major, type.minor, type.qml.c_str()); RegisterTypeQObject::setId(result); return result; } template struct DosQmlRegisterHelper { static int Register(int i, QmlRegisterType args) { if (i > N) return -1; else if (i == N) return dosQmlRegisterType(std::move(args)); else return DosQmlRegisterHelper < N - 1 >::Register(i, std::move(args)); } }; template<> struct DosQmlRegisterHelper<0> { static int Register(int i, QmlRegisterType args) { return i == 0 ? dosQmlRegisterType<0>(std::move(args)) : -1; } }; template using RegisterSingletonTypeQObject = DosQObjectWrapper; template QObject *singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine) { return new RegisterSingletonTypeQObject(); } template int dosQmlRegisterSingletonType(QmlRegisterType args) { using Func = QObject * (*)(QQmlEngine *, QJSEngine *); Func f = singletontype_provider; RegisterSingletonTypeQObject::setQmlRegisterType(std::move(args)); const QmlRegisterType &type = RegisterSingletonTypeQObject::qmlRegisterType(); RegisterSingletonTypeQObject::setStaticMetaObject(*(type.staticMetaObject->metaObject())); int result = qmlRegisterSingletonType>(type.uri.c_str(), type.major, type.minor, type.qml.c_str(), f); RegisterSingletonTypeQObject::setId(result); return result; } template struct DosQmlRegisterSingletonHelper { static int Register(int i, QmlRegisterType args) { if (i > N) return -1; else if (i == N) return dosQmlRegisterSingletonType(std::move(args)); else return DosQmlRegisterSingletonHelper < N - 1 >::Register(i, std::move(args)); } }; template<> struct DosQmlRegisterSingletonHelper<0> { static int Register(int i, QmlRegisterType args) { return i == 0 ? dosQmlRegisterSingletonType<0>(std::move(args)) : -1; } }; } }