sigslot.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * File : sigslot.h
  3. * COPYRIGHT (C) 2012-2017, Shanghai Real-Thread Technology Co., Ltd
  4. *
  5. * Change Logs:
  6. * Date Author Notes
  7. * 2017-11-05 realthread the first version
  8. */
  9. #pragma once
  10. namespace Persimmon
  11. {
  12. namespace sigslot_detail
  13. {
  14. class _not_a_param_type;
  15. /* Slots with no parameters. */
  16. class SlotBase0
  17. {
  18. public:
  19. virtual void exec(void) = 0;
  20. virtual ~SlotBase0() {};
  21. };
  22. template<typename T>
  23. class SlotImpl0 : public SlotBase0
  24. {
  25. public:
  26. SlotImpl0(T* pObj, void (T::*func)(void))
  27. {
  28. m_obj = pObj;
  29. m_func = func;
  30. }
  31. virtual void exec(void)
  32. {
  33. (m_obj->*m_func)();
  34. }
  35. private:
  36. T* m_obj;
  37. void (T::*m_func)(void);
  38. };
  39. class Slot0
  40. {
  41. public:
  42. template<typename T>
  43. void set(T* pObj, void (T::*func)(void))
  44. {
  45. if (m_slotBase)
  46. delete m_slotBase;
  47. m_slotBase = new SlotImpl0<T>(pObj, func);
  48. }
  49. Slot0() : m_slotBase(0) {}
  50. ~Slot0()
  51. {
  52. delete m_slotBase;
  53. }
  54. void exec(void)
  55. {
  56. if (m_slotBase)
  57. m_slotBase->exec();
  58. }
  59. private:
  60. SlotBase0* m_slotBase;
  61. Slot0(const Slot0& slt) : m_slotBase(slt.m_slotBase)
  62. {}
  63. void operator=(const Slot0& slt) {}
  64. };
  65. /* Slots with 1 parameter. */
  66. template<typename Tp1>
  67. class SlotBase1
  68. {
  69. public:
  70. virtual void exec(Tp1 p1) = 0;
  71. virtual ~SlotBase1() {};
  72. };
  73. template<typename T, typename Tp1>
  74. class SlotImpl1 : public SlotBase1<Tp1>
  75. {
  76. public:
  77. SlotImpl1(T* pObj, void (T::*func)(Tp1))
  78. {
  79. m_obj = pObj;
  80. m_func = func;
  81. }
  82. virtual void exec(Tp1 p1)
  83. {
  84. (m_obj->*m_func)(p1);
  85. }
  86. private:
  87. T* m_obj;
  88. void (T::*m_func)(Tp1);
  89. };
  90. template<typename Tp1>
  91. class Slot1
  92. {
  93. public:
  94. template<typename T>
  95. void set(T* pObj, void (T::*func)(Tp1))
  96. {
  97. if (m_slotBase)
  98. delete m_slotBase;
  99. m_slotBase = new SlotImpl1<T, Tp1>(pObj, func);
  100. }
  101. Slot1() : m_slotBase(0) {}
  102. ~Slot1()
  103. {
  104. delete m_slotBase;
  105. }
  106. void exec(Tp1 p1)
  107. {
  108. if (m_slotBase)
  109. m_slotBase->exec(p1);
  110. }
  111. private:
  112. SlotBase1<Tp1>* m_slotBase;
  113. Slot1(const Slot1<Tp1>& slt) : m_slotBase(slt.m_slotBase)
  114. {}
  115. void operator=(const Slot1<Tp1>& slt)
  116. {}
  117. };
  118. /* Slots with 2 parameters. */
  119. template<typename Tp1, typename Tp2>
  120. class SlotBase2
  121. {
  122. public:
  123. virtual void exec(Tp1, Tp2) = 0;
  124. virtual ~SlotBase2() {};
  125. };
  126. template<typename T, typename Tp1, typename Tp2>
  127. class SlotImpl2 : public SlotBase2<Tp1, Tp2>
  128. {
  129. public:
  130. SlotImpl2(T* pObj, void (T::*func)(Tp1, Tp2))
  131. {
  132. m_obj = pObj;
  133. m_func = func;
  134. }
  135. virtual void exec(Tp1 p1, Tp2 p2)
  136. {
  137. (m_obj->*m_func)(p1, p2);
  138. }
  139. private:
  140. T* m_obj;
  141. void (T::*m_func)(Tp1, Tp2);
  142. };
  143. template<typename Tp1, typename Tp2>
  144. class Slot2
  145. {
  146. public:
  147. template<typename T>
  148. void set(T* pObj, void (T::*func)(Tp1, Tp2))
  149. {
  150. if (m_slotBase)
  151. delete m_slotBase;
  152. m_slotBase = new SlotImpl2<T, Tp1, Tp2>(pObj, func);
  153. }
  154. Slot2() : m_slotBase(0) {}
  155. ~Slot2()
  156. {
  157. delete m_slotBase;
  158. }
  159. void exec(Tp1 p1, Tp2 p2)
  160. {
  161. if (m_slotBase)
  162. m_slotBase->exec(p1, p2);
  163. }
  164. private:
  165. SlotBase2<Tp1, Tp2>* m_slotBase;
  166. Slot2(const Slot2<Tp1, Tp2>& slt) : m_slotBase(slt.m_slotBase)
  167. {}
  168. void operator=(const Slot2<Tp1, Tp2>& slt)
  169. {}
  170. };
  171. }
  172. template<typename Tp1, typename Tp2=sigslot_detail::_not_a_param_type>
  173. class Signal
  174. {
  175. public:
  176. template<typename T>
  177. void connect(T* pObj, void (T::*func)(Tp1, Tp2))
  178. {
  179. m_slot.set(pObj, func);
  180. }
  181. Signal(): m_slot() {}
  182. ~Signal() {}
  183. void operator()(Tp1 p1, Tp2 p2)
  184. {
  185. m_slot.exec(p1, p2);
  186. }
  187. private:
  188. sigslot_detail::Slot2<Tp1, Tp2> m_slot;
  189. };
  190. template<typename Tp1>
  191. class Signal<Tp1, sigslot_detail::_not_a_param_type>
  192. {
  193. public:
  194. template<typename T>
  195. void connect(T* pObj, void (T::*func)(Tp1))
  196. {
  197. m_slot.set(pObj, func);
  198. }
  199. Signal(): m_slot() {}
  200. ~Signal() {}
  201. void operator()(Tp1 p1)
  202. {
  203. m_slot.exec(p1);
  204. }
  205. private:
  206. sigslot_detail::Slot1<Tp1> m_slot;
  207. };
  208. template<>
  209. class Signal<void>
  210. {
  211. public:
  212. template<typename T>
  213. void connect(T* pObj, void (T::*func)(void))
  214. {
  215. m_slot.set(pObj,func);
  216. }
  217. Signal(): m_slot() {}
  218. ~Signal() {}
  219. void operator()(void)
  220. {
  221. m_slot.exec();
  222. }
  223. private:
  224. sigslot_detail::Slot0 m_slot;
  225. };
  226. }