C++ (Qt)class A : public ssc::trackable{public: A(){} ssc::signal<std::string> my_signal; /* вот здесь указываем [b]только[/b] тип передаваемого арг: std::string */ void run() { my_signal("Hello Word!"); // эмитем сигнал } };
C++ (Qt) typedef T_return (T_receiver::*function_type_1)(T_arg); typedef T_return (T_receiver::*function_type_2)(const T_arg &); typedef T_return (T_receiver::*function_type_3)(T_arg) const; typedef T_return (T_receiver::*function_type_4)(const T_arg &) const;
C++ (Qt)class B : public ssc::trackable{public: B() {} void slot1(const std::string &str) { std::cout << "slot1, signal - " << str << std::endl; } int slot2(std::string str) const { std::cout << "slot2, signal - " << str << std::endl; return 123; }}; int main(){ B *b = new B; A *a = new A; connect(a->my_signal, b, &B::slot1); connect(a->my_signal, b, &B::slot2); a->run(); delete b; delete a; return 0;}
C++ (Qt)int my_func(const std::string &str) { std::cout << str << std::endl; return str.size();} class A{public: ssc::signal<std::string> my_signal; void run() { my_signal("Hello Word!"); }}; int main(){ B *b = new B; A *a = new A; connect(a->my_signal, b, &B::slot1); connect(a->my_signal, b, &B::slot2); connect(a->my_signal, my_function); // Соединение с обычной функцией a->run(); delete b; delete a; return 0;}
C++ (Qt)template <class T_arg>class base_connection{public: base_connection() {} virtual ~base_connection() {} virtual void operator() (const T_arg &) const = 0; virtual bool valid() const = 0;};
C++ (Qt)std::list<base_connection<T_arg>* > _list;
C++ (Qt)template <class T_receiver, class T_return, class T_arg>class mem_func_connection : public base_connection<T_arg>
C++ (Qt)template <class T_return, class T_arg>class func_connection : public base_connection<T_arg>
C++ (Qt)template <class T_arg>class base_connection{public: base_connection() {} virtual ~base_connection() {} virtual void operator() (const T_arg &) const = 0; virtual bool valid() const = 0; virtual long address_obj() const = 0; /* Вот эта новая функция, которая, к примеру, будет возвращать адрес объекта receivera */ virtual long address_mem_func() const = 0; /* А это адрес функции (слота) */};
C++ (Qt)long mem_func_connection::address_obj() const{ return (long)_receiver; // _receiver - это указатель}long mem_func_connection::address_mem_func() const{ return (long)&_slot; /* _slot - принадлежитодному из 4 типов: typedef T_return (T_receiver::*_function_type_1)(T_arg); (N = 1, 2, 3, 4) typedef T_return (T_receiver::*_function_type_2)(T_arg) const; ...*/}
C++ (Qt) template <typename T>class base_connection{ virtual bool operator== (base_connection const &) const = 0;}; template <typename T, typename Obj, typename Method>class custom_connection : public base_connection <T>{ Obj *o; Method m; bool operator== (base_connection <T> const &b) const { custom_connection *c = dynamic_cast <custom_connection *> (&b); return c && c->o == o && c->m == m; }};
C++ (Qt)template <class T_arg>class base_connection{public: base_connection() {} virtual ~base_connection() {} virtual void operator() (const T_arg &) const = 0; virtual bool valid() const = 0; virtual bool operator==(base_connection<T_arg> *) const = 0; // Вот этот оператор};
C++ (Qt)class signal{public: signal() {} ~signal() { for (_iterator it = _list.begin(); it != _list.end(); it++) { delete *it; } _list.clear(); } void operator() (const T_arg &arg) const { for (_const_iterator it = _list.begin(); it != _list.end(); it++) { if ((*it)->valid()) (*it)->operator()(arg); } } template <class T1, class T2, class T3> friend class mem_func_connection; template <class T1, class T2> friend class func_connection; private: std::list<base_connection<T_arg>* > _list; typedef typename std::list<base_connection<T_arg>* >::iterator _iterator; typedef typename std::list<base_connection<T_arg>* >::const_iterator _const_iterator; void connect(base_connection<T_arg> *c) { for (_iterator it = _list.begin(); it != _list.end(); it++) { if (c->operator ==(*it)) { /* Вот здесь приходится явно вызывать operator==(...) а если просто c == *it то не сработывает :( Где подвох? я сейчас немного не в состоянии думать)) */ delete c; return; } } _list.push_back(c); }};
C++ (Qt)#ifndef SIGNAL_SLOT_H#define SIGNAL_SLOT_H #include <list>#include "smart_ptr.h"#include <iostream> namespace ssc { template <class T_arg>class base_connection{public: base_connection() {} virtual ~base_connection() {} virtual void operator() (const T_arg &) const = 0; virtual bool valid() const = 0; virtual bool operator==(base_connection<T_arg> *) const = 0;}; class trigger{public: trigger() : _flag(true) {} void set(bool flag) { _flag = flag; } bool get() const { return _flag; } private: bool _flag;}; class trackable{public: trackable() { spy = smart_ptr<trigger>(new trigger); } virtual ~trackable() { spy->set(false); } smart_ptr<trigger> spy;}; template <class T_arg>class signal{public: signal() {} ~signal() { for (_iterator it = _list.begin(); it != _list.end(); it++) { delete *it; } _list.clear(); } void operator() (const T_arg &arg) const { for (_const_iterator it = _list.begin(); it != _list.end(); it++) { if ((*it)->valid()) (*it)->operator()(arg); } } template <class T1, class T2, class T3> friend class mem_func_connection; template <class T1, class T2> friend class func_connection; private: std::list<base_connection<T_arg>* > _list; typedef typename std::list<base_connection<T_arg>* >::iterator _iterator; typedef typename std::list<base_connection<T_arg>* >::const_iterator _const_iterator; void connect(base_connection<T_arg> *c) { for (_iterator it = _list.begin(); it != _list.end(); it++) { if (c->operator ==(*it)) { delete c; return; } } _list.push_back(c); }}; template <class T_return, class T_arg>class func_connection : public base_connection<T_arg>{public: typedef T_return (*function_type_1)(T_arg); typedef T_return (*function_type_2)(const T_arg &); func_connection(signal<T_arg> &s, function_type_1 slot) { _slot_1 = slot; _index = 1; s.connect(this); } func_connection(signal<T_arg> &s, function_type_2 slot) { _slot_2 = slot; _index = 2; s.connect(this); } void operator()(const T_arg &arg) const { if (_index == 1) { (*_slot_1)(arg); return; } if (_index == 2) { (*_slot_2)(arg); return; } } bool valid() const { return true; } bool operator==(base_connection<T_arg> *bc) const { func_connection<T_return, T_arg> *fc = dynamic_cast<func_connection<T_return, T_arg>* >(bc); if (fc) { if (_index == 1) return (fc->_slot_1 == _slot_1); if (_index == 2) return (fc->_slot_2 == _slot_2); } return false; } private: function_type_1 _slot_1; function_type_2 _slot_2; int _index; func_connection(); func_connection(const func_connection &);}; template <class T_receiver, class T_return, class T_arg>class mem_func_connection : public base_connection<T_arg>{public: typedef T_return (T_receiver::*function_type_1)(T_arg); typedef T_return (T_receiver::*function_type_2)(const T_arg &); typedef T_return (T_receiver::*function_type_3)(T_arg) const; typedef T_return (T_receiver::*function_type_4)(const T_arg &) const; mem_func_connection(signal<T_arg> &s, T_receiver *obj, function_type_1 slot) { _receiver = obj; _spy = _receiver->spy; _slot_1 = slot; _index = 1; s.connect(this); } mem_func_connection(signal<T_arg> &s, T_receiver *obj, function_type_2 slot) { _receiver = obj; _spy = _receiver->spy; _slot_2 = slot; _index = 2; s.connect(this); } mem_func_connection(signal<T_arg> &s, T_receiver *obj, function_type_3 slot) { _receiver = obj; _spy = _receiver->spy; _slot_3 = slot; _index = 3; s.connect(this); } mem_func_connection(signal<T_arg> &s, T_receiver *obj, function_type_4 slot) { _receiver = obj; _spy = _receiver->spy; _slot_4 = slot; _index = 4; s.connect(this); } void operator()(const T_arg &arg) const { if (_index == 1) { (_receiver->*_slot_1)(arg); return; } if (_index == 2) { (_receiver->*_slot_2)(arg); return; } if (_index == 3) { (_receiver->*_slot_3)(arg); return; } if (_index == 4) { (_receiver->*_slot_4)(arg); return; } } bool valid() const { return _spy->get(); } bool operator==(base_connection<T_arg> *bc) const { mem_func_connection<T_receiver, T_return, T_arg> *mfc = dynamic_cast<mem_func_connection<T_receiver, T_return, T_arg> *>(bc); if (mfc && (mfc->_receiver == _receiver)) { if (_index == 1) return (mfc->_slot_1 == _slot_1); if (_index == 2) return (mfc->_slot_2 == _slot_2); if (_index == 3) return (mfc->_slot_3 == _slot_3); if (_index == 4) return (mfc->_slot_4 == _slot_4); } return false; } private: T_receiver *_receiver; smart_ptr<trigger> _spy; function_type_1 _slot_1; function_type_2 _slot_2; function_type_3 _slot_3; function_type_4 _slot_4; int _index; mem_func_connection(); mem_func_connection(const mem_func_connection &);}; template <class T_return, class T_arg>void connect(signal<T_arg> &s, T_return (*slot)(T_arg)) { new func_connection<T_return, T_arg>(s, slot);} template <class T_return, class T_arg>void connect(signal<T_arg> &s, T_return (*slot)(const T_arg &)) { new func_connection<T_return, T_arg>(s, slot);} template <class T_receiver, class T_return, class T_arg>void connect(signal<T_arg> &s, T_receiver *obj, T_return (T_receiver::*slot)(T_arg)) { new mem_func_connection<T_receiver, T_return, T_arg>(s, obj, slot);} template <class T_receiver, class T_return, class T_arg>void connect(signal<T_arg> &s, T_receiver *obj, T_return (T_receiver::*slot)(const T_arg &)) { new mem_func_connection<T_receiver, T_return, T_arg>(s, obj, slot);} template <class T_receiver, class T_return, class T_arg>void connect(signal<T_arg> &s, T_receiver *obj, T_return (T_receiver::*slot)(T_arg) const) { new mem_func_connection<T_receiver, T_return, T_arg>(s, obj, slot);} template <class T_receiver, class T_return, class T_arg>void connect(signal<T_arg> &s, T_receiver *obj, T_return (T_receiver::*slot)(const T_arg &) const) { new mem_func_connection<T_receiver, T_return, T_arg>(s, obj, slot);} } #endif // SIGNAL_SLOT_H
C++ (Qt)void connect(base_connection<T_arg> *c) { for (_iterator it = _list.begin(); it != _list.end(); it++) { if (c == *it) { delete c; return; } } _list.push_back(c);
C++ (Qt)virtual bool compare(base_connection<T_arg> *) const = 0;
C++ (Qt) function_type_1 _slot_1; function_type_2 _slot_2; function_type_3 _slot_3; function_type_4 _slot_4;
C++ (Qt)template <class T_arg>class base_connection{public: base_connection() {} virtual ~base_connection() {} virtual void operator() (const T_arg &) const = 0; virtual bool valid() const = 0; virtual bool compare(base_connection<T_arg> *) const = 0;};
C++ (Qt)bool compare(base_connection<T_arg> *bc) const { mem_func_connection<T_receiver, T_return, T_arg> *mfc = dynamic_cast<mem_func_connection<T_receiver, T_return, T_arg> *>(bc); if (mfc && (mfc->_receiver == _receiver)) { if (_index == 1) return (mfc->_slot_1 == _slot_1); if (_index == 2) return (mfc->_slot_2 == _slot_2); if (_index == 3) return (mfc->_slot_3 == _slot_3); if (_index == 4) return (mfc->_slot_4 == _slot_4); } return false; }
C++ (Qt)bool compare(base_connection<T_arg> *bc) const { func_connection<T_return, T_arg> *fc = dynamic_cast<func_connection<T_return, T_arg>* >(bc); if (fc) { if (_index == 1) return (fc->_slot_1 == _slot_1); if (_index == 2) return (fc->_slot_2 == _slot_2); } return false; }
C++ (Qt)void connect(base_connection<T_arg> *c) { for (_iterator it = _list.begin(); it != _list.end(); it++) { if (c->compare(*it)) { delete c; return; } } _list.push_back(c); }
C++ (Qt)...if (_index == 1)...
C++ (Qt)...switch(_index) {}...
C++ (Qt)virtual void operator()(const T_arg &) const = 0
C++ (Qt)virtual void handle_evant(const T_arg &) const = 0;