/*************************************************************************************************** Copyright (C) 2023 The Qt Company Ltd. SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only ***************************************************************************************************/ #pragma once #include "qdotnetref.h" #include "qdotnetcallback.h" #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wconversion" #endif #include #include #ifdef __GNUC__ # pragma GCC diagnostic pop #endif class QDotNetInterface : public QDotNetRef { public: QDotNetInterface(const QString &interfaceName, void *data = nullptr, void *cleanUp = nullptr) : QDotNetRef(adapter().addInterfaceProxy(interfaceName, data, cleanUp)) {} QDotNetInterface(const void *objectRef = nullptr) : QDotNetRef(objectRef) {} QDotNetInterface(const QDotNetInterface &cpySrc) : QDotNetRef(cpySrc) {} QDotNetInterface &operator =(const QDotNetInterface &cpySrc) { QDotNetRef::operator=(cpySrc); return *this; } QDotNetInterface(QDotNetInterface &&movSrc) noexcept : QDotNetRef(std::move(movSrc)) {} QDotNetInterface &operator=(QDotNetInterface &&movSrc) noexcept { QDotNetRef::operator=(std::move(movSrc)); return *this; } template T *dataAs() { if (!fnDataPtr.isValid()) { const QList parameters { QDotNetInbound::Parameter }; fnDataPtr = adapter().resolveInstanceMethod(*this, "get_Data", parameters); } return reinterpret_cast(fnDataPtr()); } virtual ~QDotNetInterface() override { if (!isValid()) return; for (const QDotNetCallbackBase *callback : callbacks) delete callback; callbacks.clear(); } template void setCallback(const QString &methodName, typename QDotNetCallback::FunctionType function, typename QDotNetCallback::CleanUpType cleanUp = nullptr) { auto *callback = new QDotNetCallback(function, cleanUp); callbacks.append(callback); const QList parameters { QDotNetCallbackReturn::Parameter, UnmanagedType::SysInt, UnmanagedType::U8, UnmanagedType::SysInt, QDotNetCallbackArg::Parameter... }; adapter().setInterfaceMethod( *this, methodName, parameters, callback->delegate(), callback->cleanUp(), callback); } private: QList callbacks; QDotNetFunction fnDataPtr = nullptr; }; template struct QDotNetTypeOf>> { static inline const QString TypeName = T::AssemblyQualifiedName; static inline UnmanagedType MarshalAs = UnmanagedType::ObjectRef; }; template struct QDotNetNativeInterface : public QDotNetInterface { QDotNetNativeInterface(const void *objectRef = nullptr) : QDotNetInterface(objectRef) { } QDotNetNativeInterface(const QString &interfaceName, T *data, bool doCleanUp = true) : QDotNetInterface(interfaceName, data, doCleanUp ? cleanUp : nullptr) { } T *data() { return dataAs(); } operator T&() { return *data(); } static void QDOTNETFUNCTION_CALLTYPE cleanUp(void *data) { if (data) delete reinterpret_cast(data); } };