#ifndef SYG_connection_HPP #define SYG_connection_HPP #include namespace syg { //------------------------------ // connections //------------------------------ template class connection_base { public: virtual Tret call() const = 0; virtual connection_base* clone() const = 0; virtual ~connection_base() {} }; template class connection_base1 { public: virtual Tret call(Targ0) const = 0; virtual connection_base1* clone() const = 0; virtual ~connection_base1() {} }; template class connection_func : public connection_base { public: typedef Tret (*FuncPtr)(); connection_func(FuncPtr ptr): _func(ptr) {} Tret call() const { return _func(); } connection_base* clone() const { return new connection_func(*this); } private: FuncPtr _func; }; template class connection_func1 : public connection_base1 { public: typedef Tret (*FuncPtr)(Targ0); connection_func1(FuncPtr ptr): _func(ptr) {} Tret call(Targ0 arg0) const { return _func(arg0); } connection_base1* clone() const { return new connection_func1(*this); } private: FuncPtr _func; }; template class connection_meth : public connection_base { public: typedef Tobj TypeObj; typedef Tret (Tobj::*FuncPtr)(); connection_meth(TypeObj& obj, FuncPtr ptr): _obj(obj), _meth(ptr) {} Tret call() const { return (_obj.*_meth)(); } connection_base* clone() const { return new connection_meth(*this); } private: Tobj& _obj; FuncPtr _meth; }; template class connection_meth1 : public connection_base1 { public: typedef Tobj TypeObj; typedef Tret (Tobj::*FuncPtr)(Targ0); connection_meth1(TypeObj& obj, FuncPtr ptr): _obj(obj), _meth(ptr) {} Tret call(Targ0 arg0) const { return (_obj.*_meth)(arg0); } connection_base1* clone() const { return new connection_meth1(*this); } private: Tobj& _obj; FuncPtr _meth; }; //------------------------------ // slots //------------------------------ template class slot; template class slot1; template slot ptr_fun(Tret (*fun)()); template slot mem_fun(Tobj& obj, Tret (Tobj::*fun)()); template slot1 ptr_fun(Tret (*fun)(Targ0)); template slot1 mem_fun(Tobj& obj, Tret (Tobj::*fun)(Targ0)); template class slot { public: slot(): _conn(0) {} slot(const slot& s) { *this = s; } ~slot() { delete _conn; } slot& operator=(const slot& s) { if (s._conn) _conn = s._conn->clone(); else _conn = 0; return *this; } Tret call() const { return _conn->call(); } Tret operator()() const { return call(); } operator bool() const { return _conn; } private: connection_base* _conn; slot(const connection_base& conn): _conn(conn.clone()) {} friend slot ptr_fun(Tret (*fun)()); template friend slot mem_fun(Tobj2& obj, Tret2 (Tobj2::*fun)()); }; template class slot1 { public: typedef slot1 SlotType; slot1(): _conn(0) {} slot1(const SlotType& s) { *this = s; } ~slot1() { delete _conn; } slot1& operator=(const SlotType& s) { if (s._conn) _conn = s._conn->clone(); else _conn = 0; return *this; } Tret call(Targ0 arg0) const { return _conn->call(arg0); } Tret operator()(Targ0 arg0) const { return call(arg0); } operator bool() const { return _conn; } private: typedef connection_base1 Connection; Connection* _conn; slot1(const Connection& conn): _conn(conn.clone()) {} friend SlotType ptr_fun(Tret (*fun)(Targ0)); template friend slot1 mem_fun(Tobj2& obj, Tret2 (Tobj2::*fun)(Targ02)); }; template inline slot ptr_fun(Tret (*fun)()) { return slot(connection_func(fun)); } template inline slot mem_fun(Tobj& obj, Tret (Tobj::*fun)()) { return slot(connection_meth(obj, fun)); } template inline slot1 ptr_fun(Tret (*fun)(Targ0)) { return slot1(connection_func1(fun)); } template inline slot1 mem_fun(Tobj& obj, Tret (Tobj::*fun)(Targ0)) { return slot1(connection_meth1(obj, fun)); } //------------------------------ // signals //------------------------------ /* template class signal; template class connection { public: connection(): _list(0) { } void disconnect() { _list->erase(_iter); } private: typedef std::list > List; typedef typename List::iterator Iterator; List* _list; Iterator _iter; connection(List* list, Iterator iter): _list(list), _iter(iter) {} friend class signal; }; template class signal { public: connection connect(const slot s) { _slots.push_back(s); return connection(&_slots, (++_slots.rbegin()).base()); } Tret emit() const { for (typename Slots::const_iterator iter = _slots.begin(), end = (++_slots.rbegin()).base(); iter != end; ++iter) iter->call(); return _slots.back().call(); } Tret operator()() const { return emit(); } private: typedef std::list > Slots; Slots _slots; }; template class signal1 { public: void connect(const slot s) { _slots.push_back(s); } Tret emit(Targ0 arg0) const { for (typename Slots::const_iterator iter = _slots.begin(); iter != _slots.end() - 1; ++iter) iter->call(); return _slots.back().call(arg0); } Tret operator()(Targ0 arg0) const { return emit(arg0); } private: typedef std::list > Slots; Slots _slots; }; */ } // namespace syg #endif