// C11SafeDelegate.hpp #pragma once #include #include "C11DelegateHandler.hpp" #include "ExclusiveArray.tlh" //----------------------------------------------------------------------------- // SafeDelegate //----------------------------------------------------------------------------- class SafeDelegate { protected: typedef DelegateArgs BASE_TA; typedef C11DelegateHandler C11EventHandler; public: SafeDelegate () { } SafeDelegate (SafeDelegate && from) { auto lock_this = m_handlers.Lock (); auto lock_from = from.m_handlers.Lock (); lock_this.As ()->swap (*lock_from.As ()); } SafeDelegate (const SafeDelegate &) = delete; SafeDelegate & operator = (const SafeDelegate &) = delete; SafeDelegate & operator = (SafeDelegate && from) { swap (from); return (*this); } void swap (SafeDelegate & from) { auto lock_this = m_handlers.Lock (); auto lock_from = from.m_handlers.Lock (); lock_this.As ()->swap (*lock_from.As ()); } void CopyTo (SafeDelegate & from) { auto lock_this = m_handlers.Lock (); auto lock_from = from.m_handlers.Lock (); *lock_from.As () = *lock_this.As (); } void Release () { m_handlers.Lock ()->clear (); } virtual ~SafeDelegate () { } protected: // std::vector m_handlers; ExclusiveVector m_handlers; protected: #if 1 // 按完整的 handler 来查找 inline bool IsExist (const C11EventHandler & handler) const { auto lock = m_handlers.Lock (); auto Iter = Iterator::From (lock.As ()) .Find (handler); return Iter; } // 按 Key 来查找 inline bool IsExist (const C11EventHandler::tKey key) const { auto lock = m_handlers.Lock (); auto Iter = Iterator::From (lock.As ()) .First ([&] (C11EventHandler & v) { return v.IsEqual (key); }); return Iter; } // 按 Key + 类实例指针 来查找 inline bool IsExist (const C11EventHandler::tKey key, const void * pThis) const { auto lock = m_handlers.Lock (); auto Iter = Iterator::From (lock.As ()) .First ([&] (C11EventHandler & v) { return v.IsEqual (key, pThis); }); return Iter; } #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.Lock ()->empty (); } inline int GetSize () const { return (int) (m_handlers.Lock ()->size ()); } public: // lambda 表达式会到这里 // Binder (bind 结果) 会到这里 template inline void Push (const T & handler) { if (IsExist (& handler)) return; C11EventHandler h (& handler, handler); ForcePush (std::move (h)); } // 静态函数会到这里 inline void Push (void (*fn) (const void *, DelegateArgs *)) { 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 DelegateArgs"); 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 (T * inst, void (T::*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 (T::*tRightMemFunc) (const void *, DelegateArgs *); 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 (T * 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 (T::*tRightMemFunc) (const void *, DelegateArgs *); 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: template inline void Pop (const T & handler) { DoPop (& handler); } inline void Pop (void (*fn) (const void *, DelegateArgs *)) { 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 (T * inst, void (T::*mfn) (const void *, DelegateArgs *)) { C11ClassDelegateHandler ::tMemFunToVoid un (mfn); DoPop (un.pFunc, inst); } #endif /// 此函数用于成员函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) #if 1 template inline void Pop (T * inst, void (T::*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 (T::*tRightMemFunc) (const void *, DelegateArgs *); 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 (T * 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 (T::*tRightMemFunc) (const void *, DelegateArgs *); tRightMemFunc tfn = reinterpret_cast (mfn); C11ClassDelegateHandler ::tMemFunToVoid un (tfn); DoPop (un.pFunc, inst); } #endif public: inline void operator () (const void * sender, DelegateArgs * arg) { Invoke (sender, arg); } inline virtual void Invoke (const void * sender, DelegateArgs * arg) { #if 1 auto temp = Iterator::From (m_handlers.Lock ().As ()).CopyToVector (); for (auto & h : temp) h (sender, arg); #else for (auto & h : m_handlers) h (sender, arg); #endif } protected: inline virtual void ForcePush (C11EventHandler && handler) { m_handlers.Lock ().As ()->push_back (handler); } protected: // 按 Key 来删除 inline virtual bool DoPop (const C11EventHandler::tKey key) { auto lock = m_handlers.Lock (); auto ar = lock.As (); for (auto it = ar->cbegin (); it != ar->cend (); it++) { auto & h = (*it); if (h == key) { ar->erase (it); return true; } }; return false; } // 按 Key + 类实例指针 来删除 inline virtual bool DoPop (const C11EventHandler::tKey key, const void * pThis) { auto lock = m_handlers.Lock (); auto ar = lock.As (); for (auto it = ar->cbegin (); it != ar->cend (); it++) { auto & h = (*it); if (h.IsEqual (key, pThis)) { ar->erase (it); return true; } }; return false; } };