diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index c4cbe16427..74baf46e1c 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -36,7 +36,7 @@ public: CInvokable() : m_nRefCount(0) {} virtual ~CInvokable() {} // IUnknown methods - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID WXUNUSED(riid), void **ppvObj) override + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID WXUNUSED(riid), void** ppvObj) override { /** * WebView2 Runtime apparently doesn't use this method, so it doesn't @@ -47,10 +47,12 @@ public: *ppvObj = NULL; return E_NOINTERFACE; } - ULONG STDMETHODCALLTYPE AddRef(void) override { + ULONG STDMETHODCALLTYPE AddRef() override + { return ++m_nRefCount; } - ULONG STDMETHODCALLTYPE Release(void) override { + ULONG STDMETHODCALLTYPE Release() override + { size_t ret = --m_nRefCount; if (ret == 0) delete this; @@ -59,51 +61,58 @@ public: private: std::atomic m_nRefCount; }; + template class CInvokableLambda : public CInvokable { public: CInvokableLambda(std::function lambda) - : m_lambda(lambda) { - } + : m_lambda(lambda) + {} // baseT method - HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override { + 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) { - } + CInvokableMethod(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) + : m_ctx(ctx), m_mthd(mthd) + {} // baseT method - HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override { + HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override + { return (m_ctx->*m_mthd)(args...); } private: - contextT *m_ctx; - HRESULT (contextT::*m_mthd)(argTs...); + 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) +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...)) +wxCOMPtr Callback(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) { return wxCOMPtr(new CInvokableMethod(ctx, mthd)); }