| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- #pragma once
- #include<iostream>
- #include<map>
- #include <functional>
- #include<string>
- #include<type_traits>
- #include<tuple>
- #if 1
- using namespace std;
- class Object;
- using omfptr = void(Object::*)();
- class MPointer
- {
- public:
- virtual void sendback(Object* optr) = 0;
- virtual omfptr get_mfptr() = 0;
- bool operator< (const MPointer& rhs) const
- {
- return true;
- }
- };
- class DPointer :public MPointer
- {
- public:
- DPointer(void(Object::* mfptr)()) :_mfptr(mfptr) {}
- void(Object::* _mfptr)();
- virtual void sendback(Object* optr)override
- {
- (optr->*_mfptr)();
- }
- virtual omfptr get_mfptr() override
- {
- return omfptr(_mfptr);
- }
- };
- template<int ...>
- struct seq {};
- template<int N, int ...S>
- struct gens : gens<N - 1, N - 1, S...> {};
- template<int ...S>
- struct gens<0, S...> {
- typedef seq<S...> type;
- };
- template<int ...S, typename T, typename... Types>
- void callFunc(seq<S...>, const T& tuple, MPointer* mptr, Object* optr, std::tuple<Types...>& ty) {
- auto mfptr = mptr->get_mfptr();
- auto cast_omfptr = (void (Object::*)(Types...))mfptr;
- (optr->*cast_omfptr)(std::get<S>(tuple) ...);
- }
- template<typename T, typename... Types>
- void delayed_dispatch(const T& tup, MPointer* mptr, Object* optr, std::tuple<Types...>& ty) {
- callFunc(typename gens<std::tuple_size<T>::value >::type(), tup, mptr, optr, ty);
- }
- std::map<std::pair<std::pair<std::string, MPointer*>, Object*>, std::pair<std::pair<std::string, MPointer*>, Object*>> _map;
- #if 0
- #define connect(obj_ptr1,omfunc1,obj_ptr2,omfunc2)\
- do{\
- auto mfptr1=omfunc1;\
- auto mfptr2=omfunc2;\
- auto cast_mid_mfptr1=(void (std::remove_reference<decltype(*obj_ptr2)>::type ::*)())(mfptr1);\
- auto cast_mfptr1=omfptr(cast_mid_mfptr1);\
- auto cast_mid_mfptr2=(void (std::remove_reference<decltype(*obj_ptr2)>::type ::*)())(mfptr2);\
- auto cast_mfptr2=omfptr(cast_mid_mfptr2);\
- auto m1=new DPointer(cast_mfptr1);\
- auto m2=new DPointer(cast_mfptr2);\
- _map.insert(make_pair(std::make_pair(std::make_pair(#omfunc1,m1),obj_ptr1),std::make_pair(std::make_pair(#omfunc2,m2),obj_ptr2)));}\
- while(0);
- #else
- #define connect(obj_ptr1,omfunc1,obj_ptr2,omfunc2)\
- do{\
- auto mfptr1=omfunc1;\
- auto mfptr2=omfunc2;\
- auto cast_mid_mfptr1=(void (std::remove_reference<decltype(*obj_ptr1)>::type ::*)())(mfptr1);\
- auto cast_mfptr1=omfptr(cast_mid_mfptr1);\
- auto cast_mid_mfptr2=(void (std::remove_reference<decltype(*obj_ptr2)>::type ::*)())(mfptr2);\
- auto cast_mfptr2=omfptr(cast_mid_mfptr2);\
- auto m1=new DPointer(cast_mfptr1);\
- auto m2=new DPointer(cast_mfptr2);\
- _map.insert(make_pair(std::make_pair(std::make_pair(#omfunc1,m1),obj_ptr1),std::make_pair(std::make_pair(#omfunc2,m2),obj_ptr2)));}\
- while(0);
- #endif
- #define emit(func)\
- do{\
- func();\
- for(auto _outPair:_map){\
- std::size_t pos=_outPair.first.first.first.rfind("::");\
- std::string funcName=_outPair.first.first.first.substr(pos+2);\
- if((funcName==#func)&&(_outPair.first.second==this)){\
- _outPair.second.first.second->sendback(_outPair.second.second);}}}\
- while(0);
- auto t = std::make_tuple(10, 20);
- #define emitWithParam(func,signalArgs,slotsArgs)\
- do{\
- func signalArgs ;\
- auto tuple = std::make_tuple slotsArgs ;\
- for(auto _outPair:_map){\
- std::size_t pos=_outPair.first.first.first.rfind("::");\
- std::string funcName=_outPair.first.first.first.substr(pos+2);\
- if((funcName==#func)&&(_outPair.first.second==this)){\
- delayed_dispatch(tuple,_outPair.second.first.second,_outPair.second.second,tuple);\
- }}}\
- while(0);
- #else
- // https://github.com/HeranGa0/Signals-and-Slots-in-100-lines-Cpp-code/tree/master
- using namespace std;
- class cBaseGraphics;
- using omfptr = void (cBaseGraphics::*)();
- class MPointer
- {
- public:
- virtual void sendback(cBaseGraphics* optr) = 0;
- virtual omfptr get_mfptr() = 0;
- bool operator<(const MPointer& rhs) const
- {
- return true;
- }
- };
- class DPointer : public MPointer
- {
- public:
- DPointer(void (cBaseGraphics::* mfptr)()) : _mfptr(mfptr) {}
- void (cBaseGraphics::* _mfptr)();
- virtual void sendback(cBaseGraphics* optr) override
- {
- (optr->*_mfptr)();
- }
- virtual omfptr get_mfptr() override
- {
- return omfptr(_mfptr);
- }
- };
- template <int...>
- struct seq
- {
- };
- template <int N, int... S>
- struct gens : gens<N - 1, N - 1, S...>
- {
- };
- template <int... S>
- struct gens<0, S...>
- {
- typedef seq<S...> type;
- };
- template <int... S, typename T, typename... Types>
- void callFunc(seq<S...>, const T& tuple, MPointer* mptr, cBaseGraphics* optr, std::tuple<Types...>& ty)
- {
- auto mfptr = mptr->get_mfptr();
- auto cast_omfptr = (void (cBaseGraphics::*)(Types...))mfptr;
- (optr->*cast_omfptr)(std::get<S>(tuple)...);
- }
- template <typename T, typename... Types>
- void delayed_dispatch(const T& tup, MPointer* mptr, cBaseGraphics* optr, std::tuple<Types...>& ty)
- {
- callFunc(typename gens<std::tuple_size<T>::value>::type(), tup, mptr, optr, ty);
- }
- std::map<std::pair<std::pair<std::string, MPointer*>, cBaseGraphics*>, std::pair<std::pair<std::string, MPointer*>, cBaseGraphics*>> _map;
- #define connect(obj_ptr1, omfunc1, obj_ptr2, omfunc2) \
- do \
- { \
- auto mfptr1 = omfunc1; \
- auto mfptr2 = omfunc2; \
- auto cast_mid_mfptr1 = (void (std::remove_reference<decltype(*obj_ptr1)>::type ::*)())(mfptr1); \
- auto cast_mfptr1 = omfptr(cast_mid_mfptr1); \
- auto cast_mid_mfptr2 = (void (std::remove_reference<decltype(*obj_ptr2)>::type ::*)())(mfptr2); \
- auto cast_mfptr2 = omfptr(cast_mid_mfptr2); \
- auto m1 = new DPointer(cast_mfptr1); \
- auto m2 = new DPointer(cast_mfptr2); \
- _map.insert(make_pair(std::make_pair(std::make_pair(#omfunc1, m1), obj_ptr1), std::make_pair(std::make_pair(#omfunc2, m2), obj_ptr2))); \
- } while (0);
- #define emit(func) \
- do \
- { \
- func(); \
- for (auto _outPair : _map) \
- { \
- std::size_t pos = _outPair.first.first.first.rfind("::"); \
- std::string funcName = _outPair.first.first.first.substr(pos + 2); \
- if ((funcName == #func) && (_outPair.first.second == this)) \
- { \
- _outPair.second.first.second->sendback(_outPair.second.second); \
- } \
- } \
- } while (0);
- auto t = std::make_tuple(10, 20);
- #define emitWithParam(func, signalArgs, slotsArgs) \
- do \
- { \
- func signalArgs; \
- auto tuple = std::make_tuple slotsArgs; \
- for (auto _outPair : _map) \
- { \
- std::size_t pos = _outPair.first.first.first.rfind("::"); \
- std::string funcName = _outPair.first.first.first.substr(pos + 2); \
- if ((funcName == #func) && (_outPair.first.second == this)) \
- { \
- delayed_dispatch(tuple, _outPair.second.first.second, _outPair.second.second, tuple); \
- } \
- } \
- } while (0);
- #endif
|