// C11SafeDelegate.hpp #pragma once #include #include "C11DelegateHandler.hpp" #include "FastExclusive.tlh" namespace UCT = ::Utility::Concurrent; //----------------------------------------------------------------------------- // SafeDelegate //----------------------------------------------------------------------------- class SafeDelegate { protected: typedef DelegateArgs BASE_TA; typedef C11DelegateHandler C11EventHandler; protected: UCT::ExclusiveVector m_handlers; public: SafeDelegate () = default; SafeDelegate (SafeDelegate && from) = delete; /* { 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) = delete; /* { 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.clear (); } virtual ~SafeDelegate () { } protected: #if 1 // 按完整的 handler 来查找 inline bool IsExist (const C11EventHandler & handler) const { return m_handlers.find (handler); } // 按 Key 来查找 inline bool IsExist (const C11EventHandler::tKey key) const { return m_handlers.find_if ([& key] (const auto & Item) { return Item.IsEqual (key); }); } // 按 Key + 类实例指针 来查找 inline bool IsExist (const C11EventHandler::tKey key, const void * pThis) const { return m_handlers.find_if ([& key, pThis] (const auto & Item) { return Item.IsEqual (key, pThis); }); } #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) { 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 *)) { typename C11ClassDelegateHandler ::template 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); typename C11ClassDelegateHandler ::template 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 *)) { typename C11ClassDelegateHandler ::template 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); typename C11ClassDelegateHandler ::template 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 = m_handlers.clone (); 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.push (std::move (handler)); } protected: // 按 Key 来删除 inline virtual bool DoPop (const C11EventHandler::tKey key) { return m_handlers.erase_if ([& key] (const auto & Item) { return Item == key; }); } // 按 Key + 类实例指针 来删除 inline virtual bool DoPop (const C11EventHandler::tKey key, const void * pThis) { return m_handlers.erase_if ([& key, pThis] (const auto & Item) { return Item.IsEqual (key, pThis); }); } };