From b43803703dae91408b58793b9e84470e65388e2f Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Thu, 25 Feb 2021 22:01:47 +0100 Subject: [PATCH] Move Callback implementation to separate header file --- include/wx/msw/wrl/event.h | 104 +++++++++++++++++++++++++++++++++++++ src/msw/webview_edge.cpp | 93 +-------------------------------- 2 files changed, 105 insertions(+), 92 deletions(-) create mode 100644 include/wx/msw/wrl/event.h diff --git a/include/wx/msw/wrl/event.h b/include/wx/msw/wrl/event.h new file mode 100644 index 0000000000..71a2d86770 --- /dev/null +++ b/include/wx/msw/wrl/event.h @@ -0,0 +1,104 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/msw/wrl/event.h +// Purpose: WRL event callback implementation +// Author: nns52k +// Created: 2021-02-25 +// Copyright: (c) 2021 wxWidgets team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MSW_PRIVATE_WRL_H_ +#define _WX_MSW_PRIVATE_WRL_H_ + +#include + +template +class CInvokable : public baseT +{ +public: + CInvokable() : m_nRefCount(0) {} + virtual ~CInvokable() {} + // IUnknown methods + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) override + { + if (riid == __uuidof(baseT) || riid == IID_IUnknown) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + + *ppvObj = NULL; + return E_NOINTERFACE; + } + ULONG STDMETHODCALLTYPE AddRef() override + { + return ++m_nRefCount; + } + ULONG STDMETHODCALLTYPE Release() override + { + size_t ret = --m_nRefCount; + if (ret == 0) + delete this; + return ret; + } +private: + std::atomic m_nRefCount; +}; + +template +class CInvokableLambda : public CInvokable +{ +public: + CInvokableLambda(std::function lambda) + : m_lambda(lambda) + {} + // baseT method + HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override + { + return m_lambda(args...); + } +private: + std::function m_lambda; +}; + +template +class CInvokableMethod : public CInvokable +{ +public: + CInvokableMethod(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) + : m_ctx(ctx), m_mthd(mthd) + {} + // baseT method + HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override + { + return (m_ctx->*m_mthd)(args...); + } +private: + contextT* m_ctx; + HRESULT(contextT::* m_mthd)(argTs...); +}; + +// the function templates to generate concrete classes from above class templates +template < + typename baseT, typename lambdaT, // base type & lambda type + typename LT, typename ...argTs // for capturing argument types of lambda +> +wxCOMPtr Callback_impl(lambdaT&& lambda, HRESULT(LT::*)(argTs...) const) +{ + return wxCOMPtr(new CInvokableLambda(lambda)); +} + +template +wxCOMPtr Callback(lambdaT&& lambda) +{ + return Callback_impl(std::move(lambda), &lambdaT::operator()); +} + +template +wxCOMPtr Callback(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) +{ + return wxCOMPtr(new CInvokableMethod(ctx, mthd)); +} + +#endif // _WX_MSW_PRIVATE_WRL_H_ diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index 2aefc038b2..7069536d72 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -26,102 +26,11 @@ #include "wx/msw/private/cotaskmemptr.h" #include "wx/msw/private/webview_edge.h" -#include - #ifdef __VISUALC__ #include using namespace Microsoft::WRL; #else -#include - -template -class CInvokable : public baseT -{ -public: - CInvokable() : m_nRefCount(0) {} - virtual ~CInvokable() {} - // IUnknown methods - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) override - { - if (riid == __uuidof(baseT) || riid == IID_IUnknown) - { - *ppvObj = this; - AddRef(); - return S_OK; - } - - *ppvObj = NULL; - return E_NOINTERFACE; - } - ULONG STDMETHODCALLTYPE AddRef() override - { - return ++m_nRefCount; - } - ULONG STDMETHODCALLTYPE Release() override - { - size_t ret = --m_nRefCount; - if (ret == 0) - delete this; - return ret; - } -private: - std::atomic m_nRefCount; -}; - -template -class CInvokableLambda : public CInvokable -{ -public: - CInvokableLambda(std::function lambda) - : m_lambda(lambda) - {} - // baseT method - HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override - { - return m_lambda(args...); - } -private: - std::function m_lambda; -}; - -template -class CInvokableMethod : public CInvokable -{ -public: - CInvokableMethod(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) - : m_ctx(ctx), m_mthd(mthd) - {} - // baseT method - HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override - { - return (m_ctx->*m_mthd)(args...); - } -private: - contextT* m_ctx; - HRESULT(contextT::* m_mthd)(argTs...); -}; - -// the function templates to generate concrete classes from above class templates -template < - typename baseT, typename lambdaT, // base type & lambda type - typename LT, typename ...argTs // for capturing argument types of lambda -> -wxCOMPtr Callback_impl(lambdaT&& lambda, HRESULT(LT::*)(argTs...) const) -{ - return wxCOMPtr(new CInvokableLambda(lambda)); -} - -template -wxCOMPtr Callback(lambdaT&& lambda) -{ - return Callback_impl(std::move(lambda), &lambdaT::operator()); -} - -template -wxCOMPtr Callback(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) -{ - return wxCOMPtr(new CInvokableMethod(ctx, mthd)); -} +#include #endif // !__VISUALC__ wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewEdge, wxWebView);