// C11UnsafeDelegate.hpp #pragma once #include #include "C11DelegateHandler.hpp" #include "EventArgs.BUS.hpp" //----------------------------------------------------------------------------- // BUSDelegate //----------------------------------------------------------------------------- class BUSDelegate { public: typedef EventArgs_BUSMessage BASE_TA; typedef C11DelegateHandler BUSHandler; protected: typedef std::pair tPairHandler; std::vector m_handlers; public: BUSDelegate () = default; BUSDelegate (BUSDelegate && from) { swap (from); } BUSDelegate (const BUSDelegate &) = delete; BUSDelegate & operator = (const BUSDelegate &) = delete; BUSDelegate & operator = (BUSDelegate && from) { swap (from); return (*this); } void swap (BUSDelegate & from) { m_handlers.swap (from.m_handlers); OnNoResponse.swap (from.OnNoResponse); } virtual ~BUSDelegate () { } protected: #if 0 // 按 Key 来查找 inline bool IsExist (const UINT32 Command, const BUSHandler::tKey key) const { for (auto & h : m_handlers) { if (h.first == Command && h.second == key) return true; }; return false; } // 按 Key + 类实例指针 来查找 inline bool IsExist (const UINT32 Command, const BUSHandler::tKey key, const void * pThis) const { for (auto & h : m_handlers) { if (h.first == Command && h.second.IsEqual (key, pThis)) return true; }; return false; } #else inline bool IsExist (const UINT32 Command, const BUSHandler::tKey key) const { return false; } inline bool IsExist (const UINT32 Command, const BUSHandler::tKey key, const void * pThis) const { return false; } #endif public: inline void RemoveAll () { m_handlers.clear (); } public: // lambda 表达式会到这里 // Binder (bind 结果) 会到这里 template inline void Push (const UINT32 Command, const T & handler) { // printf ("\nEnter Push, Command : %d, handler : 0x%0llx", Command, & handler); // if (IsExist (Command, & handler)) return m_handlers.size (); BUSHandler h (& handler, handler); ForcePush (std::make_pair (Command, h)); // return m_handlers.size (); } // 静态函数会到这里 inline void Push (const UINT32 Command, void (*fn) (const void *, BASE_TA *)) { if (IsExist (Command, fn)) return; BUSHandler h (fn, fn); ForcePush (std::make_pair (Command, h)); } // 此函数用于静态函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) template inline void Push (const UINT32 Command, void (*fn) (const void *, TA *)) { if (IsExist (Command, fn)) return; // 静态断言, 如果 TA 不是 DelegateArgs 的继承类, 将断言失败 // 需要编译选项 ISO C++ 最新草案标准 (/std:c++latest) static_assert (std::is_base_of ::value, "TA must be derived from EventArgs_BUSMessage"); typedef void (*tRightFunc) (const void *, DelegateArgs *); tRightFunc tfn = reinterpret_cast (fn); BUSHandler h (tfn, tfn); ForcePush (std::make_pair (Command, h)); } // 类成员函数 // 模板参数可以自动推导, 因此以下 3 种写法都可以 // D.Push <_MyTest> (&test, &_MyTest::OnCallback2); // D.Push <> (&test, &_MyTest::OnCallback2); // D.Push (&test, &_MyTest::OnCallback2); #if 0 template inline void Push (const UINT32 Command, T * inst, void (T::*mfn) (const void *, BASE_TA *)) { C11ClassDelegateHandler ::tMemFunToVoid un (mfn); if (IsExist (Command, un.pFunc, inst)) return; C11ClassDelegateHandler h (un.pFunc, inst, mfn); ForcePush (std::make_pair (Command, h)); } #endif // 此函数用于成员函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) //#if (_MSC_VER > 1800) #if 1 template inline void Push (const UINT32 Command, 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 EventArgs_BUSMessage"); typedef void (TC::*tRightMemFunc) (const void *, BASE_TA *); tRightMemFunc tfn = reinterpret_cast (mfn); C11ClassDelegateHandler ::tMemFunToVoid un (tfn); if (IsExist (Command, un.pFunc, inst)) return; C11ClassDelegateHandler h (un.pFunc, inst, tfn); ForcePush (std::make_pair (Command, h)); } #endif public: template inline void Pop (const UINT32 Command, const T & handler) { DoPop (Command, & handler); } inline void Pop (const UINT32 Command, void (*fn) (const void *, BASE_TA *)) { DoPop (Command, fn); } /// 此函数用于静态函数函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) template inline void Pop (const UINT32 Command, void (*fn) (const void *, TA *)) { // 静态断言, 如果 TA 不是 DelegateArgs 的继承类, 将断言失败 // 需要编译选项 ISO C++ 最新草案标准 (/std:c++latest) static_assert (std::is_base_of ::value, "TA must be derived from EventArgs_BUSMessage"); DoPop (Command, fn); } /// 模板参数可以自动推导, 因此以下 3 种写法都可以 // D.Pop <_MyTest> (&test, &_MyTest::OnCallback2); // D.Pop <> (&test, &_MyTest::OnCallback2); // D.Pop (&test, &_MyTest::OnCallback2); #if 0 template inline void Pop (const UINT32 Command, T * inst, void (T::*mfn) (const void *, BASE_TA *)) { C11ClassDelegateHandler ::tMemFunToVoid un (mfn); DoPop (Command, un.pFunc, inst); } #endif /// 此函数用于成员函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) template inline void Pop (const UINT32 Command, 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 EventArgs_BUSMessage"); typedef void (T::*tRightMemFunc) (const void *, BASE_TA *); tRightMemFunc tfn = reinterpret_cast (mfn); C11ClassDelegateHandler ::tMemFunToVoid un (tfn); DoPop (Command, un.pFunc, inst); } public: inline void operator () (UINT32 Command, const void * sender, BASE_TA * arg) { Invoke (Command, sender, arg); } inline virtual void Invoke (UINT32 Command, const void * sender, BASE_TA * arg) { #if 0 //#ifdef _DEBUG static int iEnter = 0; iEnter++; printf ("\r\n\r\n[%d] BUSDelegate.Invoke\r\n\r\n", iEnter); #endif for (auto & h : m_handlers) { if (h.first == Command) h.second (sender, arg); } } protected: inline void ForcePush (tPairHandler && handler) { m_handlers.push_back (handler); } protected: // 按 Key 来删除 inline bool DoPop (UINT32 Command, const C11DelegateHandler ::tKey key) { for (auto it = m_handlers.begin (); it != m_handlers.end (); it++) { auto & h = (*it); if ( (h.first == Command) && (h.second == key) ) { m_handlers.erase (it); return true; } }; return false; } // 按 Key + 类实例指针 来删除 inline bool DoPop (UINT32 Command, const C11DelegateHandler ::tKey key, const void * pThis) { for (auto it = m_handlers.begin (); it != m_handlers.end (); it++) { auto & h = (*it); if ( (h.first == Command) && h.second.IsEqual (key, pThis)) { m_handlers.erase (it); return true; } }; return false; } public: _tUnsafeDelegate OnNoResponse; };