Delegate.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // Delegate.h
  2. #pragma once
  3. //-----------------------------------------------------------------------------
  4. // 注: 我把 dynamic_cast 改成了 static_cast, 因为 dynamic_cast 需要RTTI
  5. // 但因为IsEqual是比较成员函数的地址,所以即使用 static_cast 也是正确的.
  6. //-----------------------------------------------------------------------------
  7. #define NewDelegateStatic(staticFunc) \
  8. new StaticDelegateHandler ((StaticDelegateHandler::pStaticFunctor)staticFunc, #staticFunc"")
  9. #define NewDelegate(theClass, instance, memberFunc) \
  10. new ClassDelegateHandler <theClass> (instance, (ClassDelegateHandler<theClass>::classMember) (theClass::memberFunc), #theClass"::"#memberFunc)
  11. #define MAXLEN_DELEGATE_NAME 64
  12. class DelegateArgs;
  13. class DelegateHandler;
  14. void OnDelegateInvokeFailed (const DelegateHandler * h);
  15. //
  16. // Arguments of a Delegate
  17. // You are supposed to derive this class to include
  18. // more informations regarding the delegate
  19. class DelegateArgs
  20. {
  21. public:
  22. DelegateArgs () { }
  23. virtual ~DelegateArgs () { }
  24. };
  25. //
  26. // this the base DelegateHandler which is the static/member function that is called
  27. //
  28. class DelegateHandler
  29. {
  30. public:
  31. inline DelegateHandler ()
  32. {
  33. m_Name[0] = 0;
  34. }
  35. inline DelegateHandler (const char * Name)
  36. {
  37. strncpy (m_Name, Name, sizeof(m_Name)-1);
  38. }
  39. inline void operator () (const void * sender, DelegateArgs * arg)
  40. {
  41. Invoke (sender, arg);
  42. }
  43. virtual void Invoke (const void * sender, DelegateArgs * arg) = 0;
  44. virtual int IsEqual (const DelegateHandler & handler) const = 0;
  45. virtual bool IsEmpty (void) const = 0;
  46. virtual DelegateHandler * Clone (void) const = 0;
  47. public:
  48. char m_Name [MAXLEN_DELEGATE_NAME];
  49. };
  50. //
  51. // static functions as handlers
  52. //
  53. class StaticDelegateHandler : public DelegateHandler
  54. {
  55. public:
  56. typedef void (* pStaticFunctor) (const void *, DelegateArgs *);
  57. inline StaticDelegateHandler (pStaticFunctor functor)
  58. {
  59. m_pStaticFunctor = functor;
  60. }
  61. inline StaticDelegateHandler (pStaticFunctor functor, const char * Name)
  62. : DelegateHandler (Name)
  63. {
  64. m_pStaticFunctor = functor;
  65. }
  66. inline virtual void Invoke (const void * sender, DelegateArgs * arg)
  67. {
  68. #ifndef _DEBUG
  69. try
  70. #endif
  71. {
  72. m_pStaticFunctor (sender, arg);
  73. }
  74. #ifndef _DEBUG
  75. catch (...)
  76. {
  77. Beep (1000, 1000);
  78. OnDelegateInvokeFailed (this);
  79. }
  80. #endif
  81. }
  82. inline virtual int IsEqual (const DelegateHandler & handler) const
  83. {
  84. // const StaticDelegateHandler * staticHandler = dynamic_cast <const StaticDelegateHandler *> (& handler);
  85. const StaticDelegateHandler * staticHandler = static_cast <const StaticDelegateHandler *> (& handler);
  86. if (staticHandler != 0)
  87. {
  88. return (staticHandler->m_pStaticFunctor == m_pStaticFunctor);
  89. }
  90. return false;
  91. }
  92. inline virtual bool IsEmpty (void) const
  93. {
  94. return (m_pStaticFunctor == NULL);
  95. }
  96. inline virtual DelegateHandler * Clone (void) const
  97. {
  98. StaticDelegateHandler * p;
  99. if (m_Name[0])
  100. p = new StaticDelegateHandler (m_pStaticFunctor, m_Name);
  101. else
  102. p = new StaticDelegateHandler (m_pStaticFunctor);
  103. return p;
  104. }
  105. protected:
  106. pStaticFunctor m_pStaticFunctor;
  107. };
  108. //
  109. // member function as handlers
  110. //
  111. template <typename class T>
  112. class ClassDelegateHandler : public DelegateHandler
  113. {
  114. public:
  115. typedef void (T::*classMember) (const void *, DelegateArgs *);
  116. inline ClassDelegateHandler (T * pthis, classMember functor)
  117. {
  118. m_pthis = pthis;
  119. m_classMember = functor;
  120. }
  121. inline ClassDelegateHandler (T * pthis, classMember functor, const char * Name)
  122. : DelegateHandler (Name)
  123. {
  124. m_pthis = pthis;
  125. m_classMember = functor;
  126. }
  127. inline virtual void Invoke (const void * sender, DelegateArgs * arg)
  128. {
  129. #ifndef _DEBUG
  130. try
  131. #endif
  132. {
  133. (* m_pthis.*m_classMember) (sender, arg);
  134. }
  135. #ifndef _DEBUG
  136. catch (...)
  137. {
  138. Beep (1000, 1000);
  139. OnDelegateInvokeFailed (this);
  140. }
  141. #endif
  142. }
  143. inline virtual int IsEqual (const DelegateHandler & handler) const
  144. {
  145. // const ClassDelegateHandler * classHandler = dynamic_cast<const ClassDelegateHandler *> ( &handler);
  146. const ClassDelegateHandler * classHandler = static_cast <const ClassDelegateHandler *> (& handler);
  147. if (classHandler != 0)
  148. {
  149. return (classHandler->m_classMember == m_classMember && m_pthis == classHandler->m_pthis);
  150. }
  151. return false;
  152. }
  153. inline virtual bool IsEmpty (void) const
  154. {
  155. return (m_classMember == NULL);
  156. }
  157. inline virtual DelegateHandler * Clone (void) const
  158. {
  159. class ClassDelegateHandler <T> * p;
  160. if (m_Name[0])
  161. p = new ClassDelegateHandler <T> (m_pthis, m_classMember, m_Name);
  162. else
  163. p = new ClassDelegateHandler <T> (m_pthis, m_classMember);
  164. return p;
  165. }
  166. const T * GetClassInstance (void) const
  167. {
  168. return m_pthis;
  169. }
  170. T * GetClassInstance (void)
  171. {
  172. return m_pthis;
  173. }
  174. protected:
  175. classMember m_classMember;
  176. T * m_pthis;
  177. };