// C11UnsafeDelegate.hpp #pragma once #include #include "C11DelegateHandler.hpp" //----------------------------------------------------------------------------- // _tUnsafeDelegate_Base //----------------------------------------------------------------------------- template class _tUnsafeDelegate_Base { protected: typedef T BASE_TA; typedef C11DelegateHandler C11EventHandler; public: _tUnsafeDelegate_Base () { } _tUnsafeDelegate_Base (_tUnsafeDelegate_Base && from) { m_handlers.swap (from.m_handlers); } _tUnsafeDelegate_Base (const _tUnsafeDelegate_Base &) = delete; _tUnsafeDelegate_Base & operator = (const _tUnsafeDelegate_Base &) = delete; _tUnsafeDelegate_Base & operator = (_tUnsafeDelegate_Base && from) { m_handlers.swap (from.m_handlers); return (*this); } void swap (_tUnsafeDelegate_Base & from) { m_handlers.swap (from.m_handlers); } void CopyTo (_tUnsafeDelegate_Base & from) { from.m_handlers = m_handlers; } void Release () { m_handlers.clear (); } virtual ~_tUnsafeDelegate_Base () { } public: inline void operator () (const void * sender, T * arg) { Invoke (sender, arg); } inline virtual void Invoke (const void * sender, T * arg) = 0; protected: std::vector m_handlers; protected: #if 1 // 按完整的 handler 来查找 inline bool IsExist (const C11EventHandler & handler) const { for (auto & h : m_handlers) { if (h == handler) return true; } return false; } // 按 Key 来查找 inline bool IsExist (const typename C11EventHandler::tKey key) const { for (auto & h : m_handlers) { if (h == key) return true; }; return false; } // 按 Key + 类实例指针 来查找 inline bool IsExist (const typename C11EventHandler::tKey key, const void * pThis) const { for (auto & h : m_handlers) { if (h.IsEqual (key, pThis)) return true; }; return false; } #else inline bool IsExist (const C11EventHandler & handler) const { return false; } inline bool IsExist (const C11EventHandler::tKey key) const { return false; } inline bool IsExist (const C11EventHandler::tKey key, const void * pThis) const { return false; } #endif public: inline virtual void RemoveAll () { Release (); } inline bool IsEmpty () const { return m_handlers.empty (); } inline int GetSize () const { return (int) m_handlers.size (); } public: // lambda 表达式会到这里 // Binder (bind 结果) 会到这里 template inline void Push (const T & handler) { C11EventHandler h (& handler, handler); ForcePush (std::move (h)); } // 静态函数会到这里 inline void Push (void (*fn) (const void *, T *)) { if (IsExist (fn)) return; C11EventHandler h (fn, fn); ForcePush (std::move (h)); } // 此函数用于静态函数函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) template inline void Push (void (*fn) (const void *, TA *)) { if (IsExist (fn)) return; // 静态断言, 如果 TA 不是 DelegateArgs 的继承类, 将断言失败 // 需要编译选项 ISO C++ 最新草案标准 (/std:c++latest) static_assert (std::is_base_of ::value, "TA must be derived from BASE_TA"); typedef void (*tRightFunc) (const void *, DelegateArgs *); tRightFunc tfn = reinterpret_cast (fn); C11EventHandler h (tfn, tfn); ForcePush (std::move (h)); } // 类成员函数 // 模板参数可以自动推导, 因此以下 3 种写法都可以 // D.Push <_MyTest> (&test, &_MyTest::OnCallback2); // D.Push <> (&test, &_MyTest::OnCallback2); // D.Push (&test, &_MyTest::OnCallback2); #if (_MSC_VER > 1800) template inline void Push (T * inst, void (T::*mfn) (const void *, BASE_TA *)) { C11ClassDelegateHandler ::tMemFunToVoid un (mfn); if (IsExist (un.pFunc, inst)) return; C11ClassDelegateHandler h (un.pFunc, inst, mfn); ForcePush (std::move (h)); } #endif #if 1 // 此函数用于成员函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) template inline void Push (TC * inst, void (TC::*mfn) (const void *, TA *)) { // 静态断言, 如果 TA 不是 DelegateArgs 的继承类, 将断言失败 // 需要编译选项 ISO C++ 最新草案标准 (/std:c++latest) static_assert (std::is_base_of ::value, "TA must be derived from BASE_TA"); typedef void (TC::*tRightMemFunc) (const void *, T *); tRightMemFunc tfn = reinterpret_cast (mfn); C11ClassDelegateHandler ::tMemFunToVoid un (tfn); if (IsExist (un.pFunc, inst)) return; C11ClassDelegateHandler h (un.pFunc, inst, tfn); ForcePush (std::move (h)); } #endif #if (_MSC_VER <= 1800) template inline void Push (TC * inst, void (TB::*mfn) (const void *, TA *)) { // 静态断言, 如果 TA 不是 DelegateArgs 的继承类, 将断言失败 // 需要编译选项 ISO C++ 最新草案标准 (/std:c++latest) static_assert (std::is_base_of ::value, "TA must be derived from DelegateArgs"); static_assert (std::is_base_of ::value, "TC must be derived from TB"); typedef void (TC::*tRightMemFunc) (const void *, TA *); tRightMemFunc tfn = reinterpret_cast (mfn); C11ClassDelegateHandler ::tMemFunToVoid un (tfn); if (IsExist (un.pFunc, inst)) return; C11ClassDelegateHandler h (un.pFunc, inst, tfn); ForcePush (std::move (h)); } #endif // 判重 public: // lambda 表达式会到这里 // Binder (bind 结果) 会到这里 template inline void PushOnce (const T & handler) { if (IsExist (& handler)) return; C11EventHandler h (& handler, handler); ForcePush (std::move (h)); } // 静态函数会到这里 inline void PushOnce (void (*fn) (const void *, T *)) { if (IsExist (fn)) return; C11EventHandler h (fn, fn); ForcePush (std::move (h)); } // 此函数用于静态函数函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) template inline void PushOnce (void (*fn) (const void *, TA *)) { if (IsExist (fn)) return; // 静态断言, 如果 TA 不是 DelegateArgs 的继承类, 将断言失败 // 需要编译选项 ISO C++ 最新草案标准 (/std:c++latest) static_assert (std::is_base_of ::value, "TA must be derived from DelegateArgs"); typedef void (TC::*tRightMemFunc) (const void *, T *); tRightFunc tfn = reinterpret_cast (fn); C11EventHandler h (tfn, tfn); ForcePush (std::move (h)); } // 类成员函数 // 模板参数可以自动推导, 因此以下 3 种写法都可以 // D.Push <_MyTest> (&test, &_MyTest::OnCallback2); // D.Push <> (&test, &_MyTest::OnCallback2); // D.Push (&test, &_MyTest::OnCallback2); #if (_MSC_VER > 1800) template inline void PushOnce (TC * inst, void (TC::*mfn) (const void *, BASE_TA *)) { C11ClassDelegateHandler ::tMemFunToVoid un (mfn); if (IsExist (un.pFunc, inst)) return; C11ClassDelegateHandler h (un.pFunc, inst, mfn); ForcePush (std::move (h)); } #endif #if 1 // 此函数用于成员函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) template inline void PushOnce (TC * inst, void (TC::*mfn) (const void *, TA *)) { // 静态断言, 如果 TA 不是 DelegateArgs 的继承类, 将断言失败 // 需要编译选项 ISO C++ 最新草案标准 (/std:c++latest) static_assert (std::is_base_of ::value, "TA must be derived from DelegateArgs"); typedef void (TC::*tRightMemFunc) (const void *, T *); tRightMemFunc tfn = reinterpret_cast (mfn); C11ClassDelegateHandler ::tMemFunToVoid un (tfn); if (IsExist (un.pFunc, inst)) return; C11ClassDelegateHandler h (un.pFunc, inst, tfn); ForcePush (std::move (h)); } #endif #if (_MSC_VER <= 1800) template inline void PushOnce (TC* inst, void (TB::*mfn) (const void *, TA *)) { // 静态断言, 如果 TA 不是 DelegateArgs 的继承类, 将断言失败 // 需要编译选项 ISO C++ 最新草案标准 (/std:c++latest) static_assert (std::is_base_of ::value, "TA must be derived from DelegateArgs"); static_assert (std::is_base_of ::value, "TC must be derived from TB"); typedef void (TC::*tRightMemFunc) (const void *, T *); tRightMemFunc tfn = reinterpret_cast (mfn); C11ClassDelegateHandler ::tMemFunToVoid un (tfn); if (IsExist (un.pFunc, inst)) return; C11ClassDelegateHandler h (un.pFunc, inst, tfn); ForcePush (std::move (h)); } #endif protected: inline virtual void ForcePush (C11EventHandler && handler) { m_handlers.push_back (handler); } }; //----------------------------------------------------------------------------- // _tUnsafeDelegate, 支持 Pop //----------------------------------------------------------------------------- template class _tUnsafeDelegate : public _tUnsafeDelegate_Base { public: // lambda 表达式会到这里 // Binder (bind 结果) 会到这里 template inline void Pop (const T & handler) { DoPop (& handler); } // 静态函数会到这里 inline void Pop (void (*fn) (const void *, T *)) { DoPop (fn); } /// 此函数用于静态函数函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) template inline void Pop (void (*fn) (const void *, TA *)) { // 静态断言, 如果 TA 不是 DelegateArgs 的继承类, 将断言失败 // 需要编译选项 ISO C++ 最新草案标准 (/std:c++latest) static_assert (std::is_base_of ::value, "TA must be derived from DelegateArgs"); DoPop (fn); } /// 模板参数可以自动推导, 因此以下 3 种写法都可以 // D.Pop <_MyTest> (&test, &_MyTest::OnCallback2); // D.Pop <> (&test, &_MyTest::OnCallback2); // D.Pop (&test, &_MyTest::OnCallback2); //#if 0 #if (_MSC_VER > 1800) template inline void Pop (TC * inst, void (TC::*mfn) (const void *, T *)) { C11ClassDelegateHandler ::tMemFunToVoid un (mfn); DoPop (un.pFunc, inst); } #endif /// 此函数用于成员函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) #if 1 template inline void Pop (TC * inst, void (TC::*mfn) (const void *, TA *)) { // 静态断言, 如果 TA 不是 DelegateArgs 的继承类, 将断言失败 // 需要编译选项 ISO C++ 最新草案标准 (/std:c++latest) static_assert (std::is_base_of ::value, "TA must be derived from DelegateArgs"); typedef void (TC::*tRightMemFunc) (const void *, T *); tRightMemFunc tfn = reinterpret_cast (mfn); C11ClassDelegateHandler ::tMemFunToVoid un (tfn); DoPop (un.pFunc, inst); } #endif #if (_MSC_VER <= 1800) // 避免如下警告 // OnMouseWheelNormal .Pop (this, &BlowUpImageView::OnEventMouseWheel); template inline void Pop (TC * inst, void (TB::*mfn) (const void *, TA *)) { // 静态断言, 如果 TA 不是 DelegateArgs 的继承类, 将断言失败 // 需要编译选项 ISO C++ 最新草案标准 (/std:c++latest) static_assert (std::is_base_of ::value, "TA must be derived from DelegateArgs"); static_assert (std::is_base_of ::value, "T must be derived from TB"); typedef void (TC::*tRightMemFunc) (const void *, T *); tRightMemFunc tfn = reinterpret_cast (mfn); C11ClassDelegateHandler ::tMemFunToVoid un (tfn); DoPop (un.pFunc, inst); } #endif public: inline virtual void Invoke (const void * sender, T * arg) override { #if 1 std::vector temp = m_handlers; for (auto & h : temp) h (sender, arg); #else for (auto & h : m_handlers) h (sender, arg); #endif } protected: // 按 Key 来删除 inline virtual bool DoPop (const typename C11EventHandler::tKey key) { for (auto it = m_handlers.begin (); it != m_handlers.end (); it++) { auto & h = (*it); if (h == key) { m_handlers.erase (it); return true; } }; return false; } // 按 Key + 类实例指针 来删除 inline virtual bool DoPop (const typename C11EventHandler::tKey key, const void * pThis) { for (auto it = m_handlers.begin (); it != m_handlers.end (); it++) { auto & h = (*it); if (h.IsEqual (key, pThis)) { m_handlers.erase (it); return true; } }; return false; } }; using UnsafeDelegate = _tUnsafeDelegate ; //----------------------------------------------------------------------------- // VC 2013 不支持以下两种自动推断, 因此这里做了版本判断, 如果是 VC 2013, 就禁止以下两个函数 // inline void Push (T * inst, void (T::*mfn) (const void *, TA *)) // inline void Pop (T * inst, void (T::*mfn) (const void *, TA *)) // // Diff\DICOMCMoveSCUEx.cpp(349): error C2668: “UnsafeDelegate::Pop”: 对重载函数的调用不明确 // E:\NMay.2017\Common\C11UnsafeDelegate.hpp(257): 可能是“void UnsafeDelegate::Pop(T *,void (__cdecl // E:\NMay.2017\Common\C11UnsafeDelegate.hpp(246): 或 “void UnsafeDelegate::Pop(T *,void (__cdecl DICOMCMoveSCUEx::* )(const //-----------------------------------------------------------------------------