signalslot.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #pragma once
  2. #include<iostream>
  3. #include<map>
  4. #include <functional>
  5. #include<string>
  6. #include<type_traits>
  7. #include<tuple>
  8. #if 1
  9. using namespace std;
  10. class Object;
  11. using omfptr = void(Object::*)();
  12. class MPointer
  13. {
  14. public:
  15. virtual void sendback(Object* optr) = 0;
  16. virtual omfptr get_mfptr() = 0;
  17. bool operator< (const MPointer& rhs) const
  18. {
  19. return true;
  20. }
  21. };
  22. class DPointer :public MPointer
  23. {
  24. public:
  25. DPointer(void(Object::* mfptr)()) :_mfptr(mfptr) {}
  26. void(Object::* _mfptr)();
  27. virtual void sendback(Object* optr)override
  28. {
  29. (optr->*_mfptr)();
  30. }
  31. virtual omfptr get_mfptr() override
  32. {
  33. return omfptr(_mfptr);
  34. }
  35. };
  36. template<int ...>
  37. struct seq {};
  38. template<int N, int ...S>
  39. struct gens : gens<N - 1, N - 1, S...> {};
  40. template<int ...S>
  41. struct gens<0, S...> {
  42. typedef seq<S...> type;
  43. };
  44. template<int ...S, typename T, typename... Types>
  45. void callFunc(seq<S...>, const T& tuple, MPointer* mptr, Object* optr, std::tuple<Types...>& ty) {
  46. auto mfptr = mptr->get_mfptr();
  47. auto cast_omfptr = (void (Object::*)(Types...))mfptr;
  48. (optr->*cast_omfptr)(std::get<S>(tuple) ...);
  49. }
  50. template<typename T, typename... Types>
  51. void delayed_dispatch(const T& tup, MPointer* mptr, Object* optr, std::tuple<Types...>& ty) {
  52. callFunc(typename gens<std::tuple_size<T>::value >::type(), tup, mptr, optr, ty);
  53. }
  54. std::map<std::pair<std::pair<std::string, MPointer*>, Object*>, std::pair<std::pair<std::string, MPointer*>, Object*>> _map;
  55. #if 0
  56. #define connect(obj_ptr1,omfunc1,obj_ptr2,omfunc2)\
  57. do{\
  58. auto mfptr1=omfunc1;\
  59. auto mfptr2=omfunc2;\
  60. auto cast_mid_mfptr1=(void (std::remove_reference<decltype(*obj_ptr2)>::type ::*)())(mfptr1);\
  61. auto cast_mfptr1=omfptr(cast_mid_mfptr1);\
  62. auto cast_mid_mfptr2=(void (std::remove_reference<decltype(*obj_ptr2)>::type ::*)())(mfptr2);\
  63. auto cast_mfptr2=omfptr(cast_mid_mfptr2);\
  64. auto m1=new DPointer(cast_mfptr1);\
  65. auto m2=new DPointer(cast_mfptr2);\
  66. _map.insert(make_pair(std::make_pair(std::make_pair(#omfunc1,m1),obj_ptr1),std::make_pair(std::make_pair(#omfunc2,m2),obj_ptr2)));}\
  67. while(0);
  68. #else
  69. #define connect(obj_ptr1,omfunc1,obj_ptr2,omfunc2)\
  70. do{\
  71. auto mfptr1=omfunc1;\
  72. auto mfptr2=omfunc2;\
  73. auto cast_mid_mfptr1=(void (std::remove_reference<decltype(*obj_ptr1)>::type ::*)())(mfptr1);\
  74. auto cast_mfptr1=omfptr(cast_mid_mfptr1);\
  75. auto cast_mid_mfptr2=(void (std::remove_reference<decltype(*obj_ptr2)>::type ::*)())(mfptr2);\
  76. auto cast_mfptr2=omfptr(cast_mid_mfptr2);\
  77. auto m1=new DPointer(cast_mfptr1);\
  78. auto m2=new DPointer(cast_mfptr2);\
  79. _map.insert(make_pair(std::make_pair(std::make_pair(#omfunc1,m1),obj_ptr1),std::make_pair(std::make_pair(#omfunc2,m2),obj_ptr2)));}\
  80. while(0);
  81. #endif
  82. #define emit(func)\
  83. do{\
  84. func();\
  85. for(auto _outPair:_map){\
  86. std::size_t pos=_outPair.first.first.first.rfind("::");\
  87. std::string funcName=_outPair.first.first.first.substr(pos+2);\
  88. if((funcName==#func)&&(_outPair.first.second==this)){\
  89. _outPair.second.first.second->sendback(_outPair.second.second);}}}\
  90. while(0);
  91. auto t = std::make_tuple(10, 20);
  92. #define emitWithParam(func,signalArgs,slotsArgs)\
  93. do{\
  94. func signalArgs ;\
  95. auto tuple = std::make_tuple slotsArgs ;\
  96. for(auto _outPair:_map){\
  97. std::size_t pos=_outPair.first.first.first.rfind("::");\
  98. std::string funcName=_outPair.first.first.first.substr(pos+2);\
  99. if((funcName==#func)&&(_outPair.first.second==this)){\
  100. delayed_dispatch(tuple,_outPair.second.first.second,_outPair.second.second,tuple);\
  101. }}}\
  102. while(0);
  103. #else
  104. // https://github.com/HeranGa0/Signals-and-Slots-in-100-lines-Cpp-code/tree/master
  105. using namespace std;
  106. class cBaseGraphics;
  107. using omfptr = void (cBaseGraphics::*)();
  108. class MPointer
  109. {
  110. public:
  111. virtual void sendback(cBaseGraphics* optr) = 0;
  112. virtual omfptr get_mfptr() = 0;
  113. bool operator<(const MPointer& rhs) const
  114. {
  115. return true;
  116. }
  117. };
  118. class DPointer : public MPointer
  119. {
  120. public:
  121. DPointer(void (cBaseGraphics::* mfptr)()) : _mfptr(mfptr) {}
  122. void (cBaseGraphics::* _mfptr)();
  123. virtual void sendback(cBaseGraphics* optr) override
  124. {
  125. (optr->*_mfptr)();
  126. }
  127. virtual omfptr get_mfptr() override
  128. {
  129. return omfptr(_mfptr);
  130. }
  131. };
  132. template <int...>
  133. struct seq
  134. {
  135. };
  136. template <int N, int... S>
  137. struct gens : gens<N - 1, N - 1, S...>
  138. {
  139. };
  140. template <int... S>
  141. struct gens<0, S...>
  142. {
  143. typedef seq<S...> type;
  144. };
  145. template <int... S, typename T, typename... Types>
  146. void callFunc(seq<S...>, const T& tuple, MPointer* mptr, cBaseGraphics* optr, std::tuple<Types...>& ty)
  147. {
  148. auto mfptr = mptr->get_mfptr();
  149. auto cast_omfptr = (void (cBaseGraphics::*)(Types...))mfptr;
  150. (optr->*cast_omfptr)(std::get<S>(tuple)...);
  151. }
  152. template <typename T, typename... Types>
  153. void delayed_dispatch(const T& tup, MPointer* mptr, cBaseGraphics* optr, std::tuple<Types...>& ty)
  154. {
  155. callFunc(typename gens<std::tuple_size<T>::value>::type(), tup, mptr, optr, ty);
  156. }
  157. std::map<std::pair<std::pair<std::string, MPointer*>, cBaseGraphics*>, std::pair<std::pair<std::string, MPointer*>, cBaseGraphics*>> _map;
  158. #define connect(obj_ptr1, omfunc1, obj_ptr2, omfunc2) \
  159. do \
  160. { \
  161. auto mfptr1 = omfunc1; \
  162. auto mfptr2 = omfunc2; \
  163. auto cast_mid_mfptr1 = (void (std::remove_reference<decltype(*obj_ptr1)>::type ::*)())(mfptr1); \
  164. auto cast_mfptr1 = omfptr(cast_mid_mfptr1); \
  165. auto cast_mid_mfptr2 = (void (std::remove_reference<decltype(*obj_ptr2)>::type ::*)())(mfptr2); \
  166. auto cast_mfptr2 = omfptr(cast_mid_mfptr2); \
  167. auto m1 = new DPointer(cast_mfptr1); \
  168. auto m2 = new DPointer(cast_mfptr2); \
  169. _map.insert(make_pair(std::make_pair(std::make_pair(#omfunc1, m1), obj_ptr1), std::make_pair(std::make_pair(#omfunc2, m2), obj_ptr2))); \
  170. } while (0);
  171. #define emit(func) \
  172. do \
  173. { \
  174. func(); \
  175. for (auto _outPair : _map) \
  176. { \
  177. std::size_t pos = _outPair.first.first.first.rfind("::"); \
  178. std::string funcName = _outPair.first.first.first.substr(pos + 2); \
  179. if ((funcName == #func) && (_outPair.first.second == this)) \
  180. { \
  181. _outPair.second.first.second->sendback(_outPair.second.second); \
  182. } \
  183. } \
  184. } while (0);
  185. auto t = std::make_tuple(10, 20);
  186. #define emitWithParam(func, signalArgs, slotsArgs) \
  187. do \
  188. { \
  189. func signalArgs; \
  190. auto tuple = std::make_tuple slotsArgs; \
  191. for (auto _outPair : _map) \
  192. { \
  193. std::size_t pos = _outPair.first.first.first.rfind("::"); \
  194. std::string funcName = _outPair.first.first.first.substr(pos + 2); \
  195. if ((funcName == #func) && (_outPair.first.second == this)) \
  196. { \
  197. delayed_dispatch(tuple, _outPair.second.first.second, _outPair.second.second, tuple); \
  198. } \
  199. } \
  200. } while (0);
  201. #endif