// TimerDelegate.hpp #pragma once #include #include "C11DelegateHandler.hpp" #include "C11UnsafeDelegate.hpp" //----------------------------------------------------------------------------- // TimerDelegate //----------------------------------------------------------------------------- class TimerDelegate { public: typedef DelegateArgs BASE_TA; typedef C11DelegateHandler TimerHandler; protected: typedef std::tuple tPairHandler; std::vector m_handlers; UINT32 TimerInterval; public: TimerDelegate () = default; TimerDelegate (UINT32 Interval) { TimerInterval = Interval; } TimerDelegate (TimerDelegate && from) { swap (from); } TimerDelegate (const TimerDelegate &) = delete; TimerDelegate & operator = (const TimerDelegate &) = delete; TimerDelegate & operator = (TimerDelegate && from) { swap (from); return (*this); } void swap (TimerDelegate & from) { TimerInterval = from.TimerInterval; m_handlers.swap (from.m_handlers); } void SetInterval (UINT32 Interval) { TimerInterval = Interval; } virtual ~TimerDelegate () { } public: bool IsEmpty () const { return m_handlers.empty (); } public: // 按 Key 来查找 inline bool IsExist (const UINT32 mmElapse, const TimerHandler::tKey key) const { for (auto & h : m_handlers) { if (std::get <1> (h) == mmElapse && std::get <2> (h) == key) return true; }; return false; } // 按 Key + 类实例指针 来查找 inline bool IsExist (const UINT32 mmElapse, const TimerHandler::tKey key, const void * pThis) const { for (auto & h : m_handlers) { if (std::get <1> (h) == mmElapse && std::get <2> (h).IsEqual (key, pThis)) return true; }; return false; } public: inline virtual void RemoveAll () { m_handlers.clear (); } public: // lambda 表达式会到这里 // Binder (bind 结果) 会到这里 template inline void Push (const UINT32 mmElapse, const T & handler) { if (IsExist (mmElapse, & handler)) return; TimerHandler h (& handler, handler); ForcePush (std::make_tuple (0, mmElapse, h)); } // 静态函数会到这里 inline void Push (const UINT32 mmElapse, void (*fn) (const void *, DelegateArgs *)) { if (IsExist (mmElapse, fn)) return; TimerHandler h (fn, fn); ForcePush (std::make_tuple (0, mmElapse, h)); } // 此函数用于静态函数函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) template inline void Push (const UINT32 mmElapse, void (*fn) (const void *, TA *)) { if (IsExist (mmElapse, 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); TimerHandler h (tfn, tfn); ForcePush (std::make_tuple (0, mmElapse, 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 mmElapse, T * inst, void (T::*mfn) (const void *, BASE_TA *)) { C11ClassDelegateHandler ::tMemFunToVoid un (mfn); if (IsExist (mmElapse, un.pFunc, inst)) return; C11ClassDelegateHandler h (un.pFunc, inst, mfn); ForcePush (std::make_tuple (0, mmElapse, h)); } #endif // 此函数用于成员函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) //#if (_MSC_VER > 1800) #if 1 template inline void Push (const UINT32 mmElapse, 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 *, BASE_TA *); tRightMemFunc tfn = reinterpret_cast (mfn); C11ClassDelegateHandler ::tMemFunToVoid un (tfn); if (IsExist (mmElapse, un.pFunc, inst)) return; C11ClassDelegateHandler h (un.pFunc, inst, tfn); ForcePush (std::make_tuple (0, mmElapse, h)); } #endif public: template inline void Pop (const UINT32 mmElapse, const T & handler) { DoPop (mmElapse, & handler); } inline void Pop (const UINT32 mmElapse, void (*fn) (const void *, DelegateArgs *)) { DoPop (mmElapse, fn); } /// 此函数用于静态函数函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) template inline void Pop (const UINT32 mmElapse, 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 (mmElapse, 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 mmElapse, T * inst, void (T::*mfn) (const void *, BASE_TA *)) { C11ClassDelegateHandler ::tMemFunToVoid un (mfn); DoPop (mmElapse, un.pFunc, inst); } #endif /// 此函数用于成员函数的参数是 DelegateArgs 的继承类的情形. 例如 // void OnCallback1 (const void * sender, EventArgs_Error * arg) template inline void Pop (const UINT32 mmElapse, 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 *, TA *); tRightMemFunc tfn = reinterpret_cast (mfn); C11ClassDelegateHandler ::tMemFunToVoid un (tfn); DoPop (mmElapse, un.pFunc, inst); } public: inline void operator () (const void * sender, BASE_TA * arg) { Invoke (sender, arg); } inline virtual void Invoke (const void * sender, BASE_TA * arg) { #if 0 //#ifdef _DEBUG static int iEnter = 0; iEnter++; printf ("\r\n\r\n[%d] TimerDelegate.Invoke\r\n\r\n", iEnter); #endif for (auto & h : m_handlers) { std::get <0> (h) += TimerInterval; if (std::get <0> (h) < std::get <1> (h)) // No, not your turn return; std::get <0> (h) = 0; std::get <2> (h) (sender, arg); } } protected: inline virtual void ForcePush (tPairHandler && handler) { m_handlers.push_back (handler); } protected: // 按 Key 来删除 inline virtual bool DoPop (UINT32 mmElapse, const C11DelegateHandler ::tKey key) { for (auto it = m_handlers.begin (); it != m_handlers.end (); it++) { auto & h = (*it); if ((std::get <1> (h)== mmElapse) && (std::get <2> (h) == key)) { m_handlers.erase (it); return true; } }; return false; } // 按 Key + 类实例指针 来删除 inline virtual bool DoPop (UINT32 mmElapse, const C11DelegateHandler ::tKey key, const void * pThis) { for (auto it = m_handlers.begin (); it != m_handlers.end (); it++) { auto & h = (*it); if ((std::get <1> (h) == mmElapse) && (std::get <2> (h) .IsEqual (key, pThis))) { m_handlers.erase (it); return true; } }; return false; } };