#pragma once #include #include #include #include #include namespace cgv { namespace signal { template class functor; template class signal_impl; // signal that sends callbacks to connected functions, methods or functors when executing the ()-oeprator of the signal template class signal : public signal_impl::value, T1, T2, T3, T4, T5, T6, T7, T8>, public tacker { }; template class function_functor; template class method_functor; template class object_functor; template class const_method_functor; //template //class const_object_functor; template class functor<1,T1, T2, T3, T4, T5, T6, T7, T8> : public functor_base, public signature<1,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<1,T1, T2, T3, T4, T5, T6, T7, T8> S; virtual void operator() (typename S::A1 v1) const = 0; }; // implementation of a boolean signal with a signature of length 1 template class signal_impl<1,T1, T2, T3, T4, T5, T6, T7, T8> : public signal_base, public signature<1,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<1,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef functor<1,T1, T2, T3, T4, T5, T6, T7, T8> functor_type; // emit the signal with the ()-operator by using it like bool function void operator ()(typename S::A1 v1) const { unsigned n = (unsigned) functors.size(); for (unsigned i=0; i(functors[i]))(v1); } functor_type& connect(const functor_type& _f) { functor_type *f = static_cast(_f.clone()); signal_base::connect(f); return *f; } void disconnect(const functor_type& f) { signal_base::disconnect(&f); } }; template class function_functor<1,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<1,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<1,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (*function_ptr)(T1); function_ptr fp; function_functor(function_ptr _fp) : fp(_fp) {} void operator() (typename S::A1 v1) const { fp(v1); } void put_pointers(const void* &p1, const void* &p2) const { p1 = 0; p2 = (const void*)fp; } virtual functor_base* clone() const { return new function_functor(*this); } }; // connect signal to a void function template void connect(signal& s, void (*fp)(T1)) { s.connect(function_functor<1,T1>(fp)); } // disconnect signal from a void function template void disconnect(signal& s, void (*fp)(T1)) { s.disconnect(function_functor<1,T1>(fp)); } template class method_functor<1,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<1,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<1,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*method_ptr)(T1); X* ip; method_ptr mp; method_functor(X* _ip, method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1) const { (ip->*mp)(v1); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new method_functor(*this); } }; /// connect signal to a void method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1)) { s.connect(method_functor<1,X,X,T1>(ip,mp)); } //! connect signal to a void method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1)) { s.connect(method_functor<1,X,Y,T1>(ip,mp)); } /// disconnect signal from a void method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1)) { s.disconnect(method_functor<1,X,X,T1>(ip,mp)); } //! disconnect signal from a void method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1)) { s.disconnect(method_functor<1,X,Y,T1>(ip,mp)); } template class const_method_functor<1,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<1,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<1,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*const_method_ptr)(T1) const; const X* ip; const_method_ptr mp; const_method_functor(const X* _ip, const_method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1) const { (ip->*mp)(v1); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new const_method_functor(*this); } }; /// connect signal to a void const method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1) const) { s.connect(const_method_functor<1,X,X,T1>(ip,mp)); } /// disconnect signal from a void const method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1) const) { s.disconnect(const_method_functor<1,X,X,T1>(ip,mp)); } //! connect signal to a void const method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1) const) { s.connect(const_method_functor<1,X,Y,T1>(ip,mp)); } //! disconnect signal from a void const method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1) const) { s.disconnect(const_method_functor<1,X,Y,T1>(ip,mp)); } template class object_functor<1,X,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<1,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<1,T1, T2, T3, T4, T5, T6, T7, T8> S; mutable X ip; object_functor(typename type::func::make_argument::type _ip) : ip(_ip) {} void operator() (typename S::A1 v1) const { ip(v1); } const tacker* get_tacker() const { return type::cond::is_base_of::value?reinterpret_cast(&ip):0; } void put_pointers(const void* &p1, const void* &p2) const { p1 = &ip; p2 = 0; } virtual functor_base* clone() const { return new object_functor(*this); } }; // connect signal to the ()-operator of a referenced object template void connect(signal& s, X& ip) { s.connect(object_functor<1,X&,T1>(ip)); } // disconnect signal from the ()-operator of a referenced object template void disconnect(signal& s, X& ip) { s.disconnect(object_functor<1,X&,T1>(ip)); } // connect signal to the const ()-operator of a referenced const object template void connect(signal& s, const X& ip) { s.connect(object_functor<1,const X&,T1>(ip)); } // disconnect signal from the const ()-operator of a referenced const object template void disconnect(signal& s, const X& ip) { s.disconnect(object_functor<1,const X&,T1>(ip)); } // connect signal to the ()-operator of a copy of a temporary object, a reference to the copy is returned for disconnection template X& connect_copy(signal& s, const X& ip) { return static_cast&>(s.connect(object_functor<1,X,T1>(ip))).ip; } template class functor<2,T1, T2, T3, T4, T5, T6, T7, T8> : public functor_base, public signature<2,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<2,T1, T2, T3, T4, T5, T6, T7, T8> S; virtual void operator() (typename S::A1 v1, typename S::A2 v2) const = 0; }; // implementation of a boolean signal with a signature of length 2 template class signal_impl<2,T1, T2, T3, T4, T5, T6, T7, T8> : public signal_base, public signature<2,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<2,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef functor<2,T1, T2, T3, T4, T5, T6, T7, T8> functor_type; // emit the signal with the ()-operator by using it like bool function void operator ()(typename S::A1 v1, typename S::A2 v2) const { unsigned n = (unsigned) functors.size(); for (unsigned i=0; i(functors[i]))(v1, v2); } functor_type& connect(const functor_type& _f) { functor_type *f = static_cast(_f.clone()); signal_base::connect(f); return *f; } void disconnect(const functor_type& f) { signal_base::disconnect(&f); } }; template class function_functor<2,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<2,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<2,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (*function_ptr)(T1, T2); function_ptr fp; function_functor(function_ptr _fp) : fp(_fp) {} void operator() (typename S::A1 v1, typename S::A2 v2) const { fp(v1,v2); } void put_pointers(const void* &p1, const void* &p2) const { p1 = 0; p2 = (const void*)fp; } virtual functor_base* clone() const { return new function_functor(*this); } }; // connect signal to a void function template void connect(signal& s, void (*fp)(T1, T2)) { s.connect(function_functor<2,T1, T2>(fp)); } // disconnect signal from a void function template void disconnect(signal& s, void (*fp)(T1, T2)) { s.disconnect(function_functor<2,T1, T2>(fp)); } template class method_functor<2,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<2,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<2,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*method_ptr)(T1, T2); X* ip; method_ptr mp; method_functor(X* _ip, method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2) const { (ip->*mp)(v1, v2); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new method_functor(*this); } }; /// connect signal to a void method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2)) { s.connect(method_functor<2,X,X,T1, T2>(ip,mp)); } //! connect signal to a void method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2)) { s.connect(method_functor<2,X,Y,T1, T2>(ip,mp)); } /// disconnect signal from a void method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2)) { s.disconnect(method_functor<2,X,X,T1, T2>(ip,mp)); } //! disconnect signal from a void method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2)) { s.disconnect(method_functor<2,X,Y,T1, T2>(ip,mp)); } template class const_method_functor<2,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<2,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<2,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*const_method_ptr)(T1, T2) const; const X* ip; const_method_ptr mp; const_method_functor(const X* _ip, const_method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2) const { (ip->*mp)(v1, v2); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new const_method_functor(*this); } }; /// connect signal to a void const method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2) const) { s.connect(const_method_functor<2,X,X,T1, T2>(ip,mp)); } /// disconnect signal from a void const method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2) const) { s.disconnect(const_method_functor<2,X,X,T1, T2>(ip,mp)); } //! connect signal to a void const method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2) const) { s.connect(const_method_functor<2,X,Y,T1, T2>(ip,mp)); } //! disconnect signal from a void const method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2) const) { s.disconnect(const_method_functor<2,X,Y,T1, T2>(ip,mp)); } template class object_functor<2,X,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<2,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<2,T1, T2, T3, T4, T5, T6, T7, T8> S; mutable X ip; object_functor(typename type::func::make_argument::type _ip) : ip(_ip) {} void operator() (typename S::A1 v1, typename S::A2 v2) const { ip(v1, v2); } const tacker* get_tacker() const { return type::cond::is_base_of::value?reinterpret_cast(&ip):0; } void put_pointers(const void* &p1, const void* &p2) const { p1 = &ip; p2 = 0; } virtual functor_base* clone() const { return new object_functor(*this); } }; // connect signal to the ()-operator of a referenced object template void connect(signal& s, X& ip) { s.connect(object_functor<2,X&,T1, T2>(ip)); } // disconnect signal from the ()-operator of a referenced object template void disconnect(signal& s, X& ip) { s.disconnect(object_functor<2,X&,T1, T2>(ip)); } // connect signal to the const ()-operator of a referenced const object template void connect(signal& s, const X& ip) { s.connect(object_functor<2,const X&,T1, T2>(ip)); } // disconnect signal from the const ()-operator of a referenced const object template void disconnect(signal& s, const X& ip) { s.disconnect(object_functor<2,const X&,T1, T2>(ip)); } // connect signal to the ()-operator of a copy of a temporary object, a reference to the copy is returned for disconnection template X& connect_copy(signal& s, const X& ip) { return static_cast&>(s.connect(object_functor<2,X,T1, T2>(ip))).ip; } template class functor<3,T1, T2, T3, T4, T5, T6, T7, T8> : public functor_base, public signature<3,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<3,T1, T2, T3, T4, T5, T6, T7, T8> S; virtual void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3) const = 0; }; // implementation of a boolean signal with a signature of length 3 template class signal_impl<3,T1, T2, T3, T4, T5, T6, T7, T8> : public signal_base, public signature<3,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<3,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef functor<3,T1, T2, T3, T4, T5, T6, T7, T8> functor_type; // emit the signal with the ()-operator by using it like bool function void operator ()(typename S::A1 v1, typename S::A2 v2, typename S::A3 v3) const { unsigned n = (unsigned) functors.size(); for (unsigned i=0; i(functors[i]))(v1, v2, v3); } functor_type& connect(const functor_type& _f) { functor_type *f = static_cast(_f.clone()); signal_base::connect(f); return *f; } void disconnect(const functor_type& f) { signal_base::disconnect(&f); } }; template class function_functor<3,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<3,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<3,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (*function_ptr)(T1, T2, T3); function_ptr fp; function_functor(function_ptr _fp) : fp(_fp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3) const { fp(v1,v2,v3); } void put_pointers(const void* &p1, const void* &p2) const { p1 = 0; p2 = (const void*)fp; } virtual functor_base* clone() const { return new function_functor(*this); } }; // connect signal to a void function template void connect(signal& s, void (*fp)(T1, T2, T3)) { s.connect(function_functor<3,T1, T2, T3>(fp)); } // disconnect signal from a void function template void disconnect(signal& s, void (*fp)(T1, T2, T3)) { s.disconnect(function_functor<3,T1, T2, T3>(fp)); } template class method_functor<3,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<3,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<3,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*method_ptr)(T1, T2, T3); X* ip; method_ptr mp; method_functor(X* _ip, method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3) const { (ip->*mp)(v1, v2, v3); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new method_functor(*this); } }; /// connect signal to a void method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3)) { s.connect(method_functor<3,X,X,T1, T2, T3>(ip,mp)); } //! connect signal to a void method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3)) { s.connect(method_functor<3,X,Y,T1, T2, T3>(ip,mp)); } /// disconnect signal from a void method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3)) { s.disconnect(method_functor<3,X,X,T1, T2, T3>(ip,mp)); } //! disconnect signal from a void method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3)) { s.disconnect(method_functor<3,X,Y,T1, T2, T3>(ip,mp)); } template class const_method_functor<3,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<3,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<3,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*const_method_ptr)(T1, T2, T3) const; const X* ip; const_method_ptr mp; const_method_functor(const X* _ip, const_method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3) const { (ip->*mp)(v1, v2, v3); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new const_method_functor(*this); } }; /// connect signal to a void const method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3) const) { s.connect(const_method_functor<3,X,X,T1, T2, T3>(ip,mp)); } /// disconnect signal from a void const method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3) const) { s.disconnect(const_method_functor<3,X,X,T1, T2, T3>(ip,mp)); } //! connect signal to a void const method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3) const) { s.connect(const_method_functor<3,X,Y,T1, T2, T3>(ip,mp)); } //! disconnect signal from a void const method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3) const) { s.disconnect(const_method_functor<3,X,Y,T1, T2, T3>(ip,mp)); } template class object_functor<3,X,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<3,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<3,T1, T2, T3, T4, T5, T6, T7, T8> S; mutable X ip; object_functor(typename type::func::make_argument::type _ip) : ip(_ip) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3) const { ip(v1, v2, v3); } const tacker* get_tacker() const { return type::cond::is_base_of::value?reinterpret_cast(&ip):0; } void put_pointers(const void* &p1, const void* &p2) const { p1 = &ip; p2 = 0; } virtual functor_base* clone() const { return new object_functor(*this); } }; // connect signal to the ()-operator of a referenced object template void connect(signal& s, X& ip) { s.connect(object_functor<3,X&,T1, T2, T3>(ip)); } // disconnect signal from the ()-operator of a referenced object template void disconnect(signal& s, X& ip) { s.disconnect(object_functor<3,X&,T1, T2, T3>(ip)); } // connect signal to the const ()-operator of a referenced const object template void connect(signal& s, const X& ip) { s.connect(object_functor<3,const X&,T1, T2, T3>(ip)); } // disconnect signal from the const ()-operator of a referenced const object template void disconnect(signal& s, const X& ip) { s.disconnect(object_functor<3,const X&,T1, T2, T3>(ip)); } // connect signal to the ()-operator of a copy of a temporary object, a reference to the copy is returned for disconnection template X& connect_copy(signal& s, const X& ip) { return static_cast&>(s.connect(object_functor<3,X,T1, T2, T3>(ip))).ip; } template class functor<4,T1, T2, T3, T4, T5, T6, T7, T8> : public functor_base, public signature<4,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<4,T1, T2, T3, T4, T5, T6, T7, T8> S; virtual void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4) const = 0; }; // implementation of a boolean signal with a signature of length 4 template class signal_impl<4,T1, T2, T3, T4, T5, T6, T7, T8> : public signal_base, public signature<4,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<4,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef functor<4,T1, T2, T3, T4, T5, T6, T7, T8> functor_type; // emit the signal with the ()-operator by using it like bool function void operator ()(typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4) const { unsigned n = (unsigned) functors.size(); for (unsigned i=0; i(functors[i]))(v1, v2, v3, v4); } functor_type& connect(const functor_type& _f) { functor_type *f = static_cast(_f.clone()); signal_base::connect(f); return *f; } void disconnect(const functor_type& f) { signal_base::disconnect(&f); } }; template class function_functor<4,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<4,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<4,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (*function_ptr)(T1, T2, T3, T4); function_ptr fp; function_functor(function_ptr _fp) : fp(_fp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4) const { fp(v1,v2,v3,v4); } void put_pointers(const void* &p1, const void* &p2) const { p1 = 0; p2 = (const void*)fp; } virtual functor_base* clone() const { return new function_functor(*this); } }; // connect signal to a void function template void connect(signal& s, void (*fp)(T1, T2, T3, T4)) { s.connect(function_functor<4,T1, T2, T3, T4>(fp)); } // disconnect signal from a void function template void disconnect(signal& s, void (*fp)(T1, T2, T3, T4)) { s.disconnect(function_functor<4,T1, T2, T3, T4>(fp)); } template class method_functor<4,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<4,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<4,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*method_ptr)(T1, T2, T3, T4); X* ip; method_ptr mp; method_functor(X* _ip, method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4) const { (ip->*mp)(v1, v2, v3, v4); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new method_functor(*this); } }; /// connect signal to a void method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4)) { s.connect(method_functor<4,X,X,T1, T2, T3, T4>(ip,mp)); } //! connect signal to a void method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4)) { s.connect(method_functor<4,X,Y,T1, T2, T3, T4>(ip,mp)); } /// disconnect signal from a void method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4)) { s.disconnect(method_functor<4,X,X,T1, T2, T3, T4>(ip,mp)); } //! disconnect signal from a void method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4)) { s.disconnect(method_functor<4,X,Y,T1, T2, T3, T4>(ip,mp)); } template class const_method_functor<4,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<4,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<4,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*const_method_ptr)(T1, T2, T3, T4) const; const X* ip; const_method_ptr mp; const_method_functor(const X* _ip, const_method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4) const { (ip->*mp)(v1, v2, v3, v4); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new const_method_functor(*this); } }; /// connect signal to a void const method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4) const) { s.connect(const_method_functor<4,X,X,T1, T2, T3, T4>(ip,mp)); } /// disconnect signal from a void const method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4) const) { s.disconnect(const_method_functor<4,X,X,T1, T2, T3, T4>(ip,mp)); } //! connect signal to a void const method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4) const) { s.connect(const_method_functor<4,X,Y,T1, T2, T3, T4>(ip,mp)); } //! disconnect signal from a void const method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4) const) { s.disconnect(const_method_functor<4,X,Y,T1, T2, T3, T4>(ip,mp)); } template class object_functor<4,X,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<4,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<4,T1, T2, T3, T4, T5, T6, T7, T8> S; mutable X ip; object_functor(typename type::func::make_argument::type _ip) : ip(_ip) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4) const { ip(v1, v2, v3, v4); } const tacker* get_tacker() const { return type::cond::is_base_of::value?reinterpret_cast(&ip):0; } void put_pointers(const void* &p1, const void* &p2) const { p1 = &ip; p2 = 0; } virtual functor_base* clone() const { return new object_functor(*this); } }; // connect signal to the ()-operator of a referenced object template void connect(signal& s, X& ip) { s.connect(object_functor<4,X&,T1, T2, T3, T4>(ip)); } // disconnect signal from the ()-operator of a referenced object template void disconnect(signal& s, X& ip) { s.disconnect(object_functor<4,X&,T1, T2, T3, T4>(ip)); } // connect signal to the const ()-operator of a referenced const object template void connect(signal& s, const X& ip) { s.connect(object_functor<4,const X&,T1, T2, T3, T4>(ip)); } // disconnect signal from the const ()-operator of a referenced const object template void disconnect(signal& s, const X& ip) { s.disconnect(object_functor<4,const X&,T1, T2, T3, T4>(ip)); } // connect signal to the ()-operator of a copy of a temporary object, a reference to the copy is returned for disconnection template X& connect_copy(signal& s, const X& ip) { return static_cast&>(s.connect(object_functor<4,X,T1, T2, T3, T4>(ip))).ip; } template class functor<5,T1, T2, T3, T4, T5, T6, T7, T8> : public functor_base, public signature<5,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<5,T1, T2, T3, T4, T5, T6, T7, T8> S; virtual void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5) const = 0; }; // implementation of a boolean signal with a signature of length 5 template class signal_impl<5,T1, T2, T3, T4, T5, T6, T7, T8> : public signal_base, public signature<5,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<5,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef functor<5,T1, T2, T3, T4, T5, T6, T7, T8> functor_type; // emit the signal with the ()-operator by using it like bool function void operator ()(typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5) const { unsigned n = (unsigned) functors.size(); for (unsigned i=0; i(functors[i]))(v1, v2, v3, v4, v5); } functor_type& connect(const functor_type& _f) { functor_type *f = static_cast(_f.clone()); signal_base::connect(f); return *f; } void disconnect(const functor_type& f) { signal_base::disconnect(&f); } }; template class function_functor<5,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<5,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<5,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (*function_ptr)(T1, T2, T3, T4, T5); function_ptr fp; function_functor(function_ptr _fp) : fp(_fp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5) const { fp(v1,v2,v3,v4,v5); } void put_pointers(const void* &p1, const void* &p2) const { p1 = 0; p2 = (const void*)fp; } virtual functor_base* clone() const { return new function_functor(*this); } }; // connect signal to a void function template void connect(signal& s, void (*fp)(T1, T2, T3, T4, T5)) { s.connect(function_functor<5,T1, T2, T3, T4, T5>(fp)); } // disconnect signal from a void function template void disconnect(signal& s, void (*fp)(T1, T2, T3, T4, T5)) { s.disconnect(function_functor<5,T1, T2, T3, T4, T5>(fp)); } template class method_functor<5,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<5,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<5,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*method_ptr)(T1, T2, T3, T4, T5); X* ip; method_ptr mp; method_functor(X* _ip, method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5) const { (ip->*mp)(v1, v2, v3, v4, v5); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new method_functor(*this); } }; /// connect signal to a void method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5)) { s.connect(method_functor<5,X,X,T1, T2, T3, T4, T5>(ip,mp)); } //! connect signal to a void method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5)) { s.connect(method_functor<5,X,Y,T1, T2, T3, T4, T5>(ip,mp)); } /// disconnect signal from a void method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5)) { s.disconnect(method_functor<5,X,X,T1, T2, T3, T4, T5>(ip,mp)); } //! disconnect signal from a void method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5)) { s.disconnect(method_functor<5,X,Y,T1, T2, T3, T4, T5>(ip,mp)); } template class const_method_functor<5,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<5,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<5,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*const_method_ptr)(T1, T2, T3, T4, T5) const; const X* ip; const_method_ptr mp; const_method_functor(const X* _ip, const_method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5) const { (ip->*mp)(v1, v2, v3, v4, v5); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new const_method_functor(*this); } }; /// connect signal to a void const method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5) const) { s.connect(const_method_functor<5,X,X,T1, T2, T3, T4, T5>(ip,mp)); } /// disconnect signal from a void const method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5) const) { s.disconnect(const_method_functor<5,X,X,T1, T2, T3, T4, T5>(ip,mp)); } //! connect signal to a void const method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5) const) { s.connect(const_method_functor<5,X,Y,T1, T2, T3, T4, T5>(ip,mp)); } //! disconnect signal from a void const method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5) const) { s.disconnect(const_method_functor<5,X,Y,T1, T2, T3, T4, T5>(ip,mp)); } template class object_functor<5,X,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<5,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<5,T1, T2, T3, T4, T5, T6, T7, T8> S; mutable X ip; object_functor(typename type::func::make_argument::type _ip) : ip(_ip) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5) const { ip(v1, v2, v3, v4, v5); } const tacker* get_tacker() const { return type::cond::is_base_of::value?reinterpret_cast(&ip):0; } void put_pointers(const void* &p1, const void* &p2) const { p1 = &ip; p2 = 0; } virtual functor_base* clone() const { return new object_functor(*this); } }; // connect signal to the ()-operator of a referenced object template void connect(signal& s, X& ip) { s.connect(object_functor<5,X&,T1, T2, T3, T4, T5>(ip)); } // disconnect signal from the ()-operator of a referenced object template void disconnect(signal& s, X& ip) { s.disconnect(object_functor<5,X&,T1, T2, T3, T4, T5>(ip)); } // connect signal to the const ()-operator of a referenced const object template void connect(signal& s, const X& ip) { s.connect(object_functor<5,const X&,T1, T2, T3, T4, T5>(ip)); } // disconnect signal from the const ()-operator of a referenced const object template void disconnect(signal& s, const X& ip) { s.disconnect(object_functor<5,const X&,T1, T2, T3, T4, T5>(ip)); } // connect signal to the ()-operator of a copy of a temporary object, a reference to the copy is returned for disconnection template X& connect_copy(signal& s, const X& ip) { return static_cast&>(s.connect(object_functor<5,X,T1, T2, T3, T4, T5>(ip))).ip; } template class functor<6,T1, T2, T3, T4, T5, T6, T7, T8> : public functor_base, public signature<6,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<6,T1, T2, T3, T4, T5, T6, T7, T8> S; virtual void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6) const = 0; }; // implementation of a boolean signal with a signature of length 6 template class signal_impl<6,T1, T2, T3, T4, T5, T6, T7, T8> : public signal_base, public signature<6,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<6,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef functor<6,T1, T2, T3, T4, T5, T6, T7, T8> functor_type; // emit the signal with the ()-operator by using it like bool function void operator ()(typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6) const { unsigned n = (unsigned) functors.size(); for (unsigned i=0; i(functors[i]))(v1, v2, v3, v4, v5, v6); } functor_type& connect(const functor_type& _f) { functor_type *f = static_cast(_f.clone()); signal_base::connect(f); return *f; } void disconnect(const functor_type& f) { signal_base::disconnect(&f); } }; template class function_functor<6,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<6,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<6,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (*function_ptr)(T1, T2, T3, T4, T5, T6); function_ptr fp; function_functor(function_ptr _fp) : fp(_fp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6) const { fp(v1,v2,v3,v4,v5,v6); } void put_pointers(const void* &p1, const void* &p2) const { p1 = 0; p2 = (const void*)fp; } virtual functor_base* clone() const { return new function_functor(*this); } }; // connect signal to a void function template void connect(signal& s, void (*fp)(T1, T2, T3, T4, T5, T6)) { s.connect(function_functor<6,T1, T2, T3, T4, T5, T6>(fp)); } // disconnect signal from a void function template void disconnect(signal& s, void (*fp)(T1, T2, T3, T4, T5, T6)) { s.disconnect(function_functor<6,T1, T2, T3, T4, T5, T6>(fp)); } template class method_functor<6,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<6,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<6,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*method_ptr)(T1, T2, T3, T4, T5, T6); X* ip; method_ptr mp; method_functor(X* _ip, method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6) const { (ip->*mp)(v1, v2, v3, v4, v5, v6); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new method_functor(*this); } }; /// connect signal to a void method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6)) { s.connect(method_functor<6,X,X,T1, T2, T3, T4, T5, T6>(ip,mp)); } //! connect signal to a void method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6)) { s.connect(method_functor<6,X,Y,T1, T2, T3, T4, T5, T6>(ip,mp)); } /// disconnect signal from a void method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6)) { s.disconnect(method_functor<6,X,X,T1, T2, T3, T4, T5, T6>(ip,mp)); } //! disconnect signal from a void method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6)) { s.disconnect(method_functor<6,X,Y,T1, T2, T3, T4, T5, T6>(ip,mp)); } template class const_method_functor<6,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<6,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<6,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*const_method_ptr)(T1, T2, T3, T4, T5, T6) const; const X* ip; const_method_ptr mp; const_method_functor(const X* _ip, const_method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6) const { (ip->*mp)(v1, v2, v3, v4, v5, v6); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new const_method_functor(*this); } }; /// connect signal to a void const method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6) const) { s.connect(const_method_functor<6,X,X,T1, T2, T3, T4, T5, T6>(ip,mp)); } /// disconnect signal from a void const method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6) const) { s.disconnect(const_method_functor<6,X,X,T1, T2, T3, T4, T5, T6>(ip,mp)); } //! connect signal to a void const method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6) const) { s.connect(const_method_functor<6,X,Y,T1, T2, T3, T4, T5, T6>(ip,mp)); } //! disconnect signal from a void const method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6) const) { s.disconnect(const_method_functor<6,X,Y,T1, T2, T3, T4, T5, T6>(ip,mp)); } template class object_functor<6,X,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<6,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<6,T1, T2, T3, T4, T5, T6, T7, T8> S; mutable X ip; object_functor(typename type::func::make_argument::type _ip) : ip(_ip) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6) const { ip(v1, v2, v3, v4, v5, v6); } const tacker* get_tacker() const { return type::cond::is_base_of::value?reinterpret_cast(&ip):0; } void put_pointers(const void* &p1, const void* &p2) const { p1 = &ip; p2 = 0; } virtual functor_base* clone() const { return new object_functor(*this); } }; // connect signal to the ()-operator of a referenced object template void connect(signal& s, X& ip) { s.connect(object_functor<6,X&,T1, T2, T3, T4, T5, T6>(ip)); } // disconnect signal from the ()-operator of a referenced object template void disconnect(signal& s, X& ip) { s.disconnect(object_functor<6,X&,T1, T2, T3, T4, T5, T6>(ip)); } // connect signal to the const ()-operator of a referenced const object template void connect(signal& s, const X& ip) { s.connect(object_functor<6,const X&,T1, T2, T3, T4, T5, T6>(ip)); } // disconnect signal from the const ()-operator of a referenced const object template void disconnect(signal& s, const X& ip) { s.disconnect(object_functor<6,const X&,T1, T2, T3, T4, T5, T6>(ip)); } // connect signal to the ()-operator of a copy of a temporary object, a reference to the copy is returned for disconnection template X& connect_copy(signal& s, const X& ip) { return static_cast&>(s.connect(object_functor<6,X,T1, T2, T3, T4, T5, T6>(ip))).ip; } template class functor<7,T1, T2, T3, T4, T5, T6, T7, T8> : public functor_base, public signature<7,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<7,T1, T2, T3, T4, T5, T6, T7, T8> S; virtual void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7) const = 0; }; // implementation of a boolean signal with a signature of length 7 template class signal_impl<7,T1, T2, T3, T4, T5, T6, T7, T8> : public signal_base, public signature<7,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<7,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef functor<7,T1, T2, T3, T4, T5, T6, T7, T8> functor_type; // emit the signal with the ()-operator by using it like bool function void operator ()(typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7) const { unsigned n = (unsigned) functors.size(); for (unsigned i=0; i(functors[i]))(v1, v2, v3, v4, v5, v6, v7); } functor_type& connect(const functor_type& _f) { functor_type *f = static_cast(_f.clone()); signal_base::connect(f); return *f; } void disconnect(const functor_type& f) { signal_base::disconnect(&f); } }; template class function_functor<7,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<7,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<7,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (*function_ptr)(T1, T2, T3, T4, T5, T6, T7); function_ptr fp; function_functor(function_ptr _fp) : fp(_fp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7) const { fp(v1,v2,v3,v4,v5,v6,v7); } void put_pointers(const void* &p1, const void* &p2) const { p1 = 0; p2 = (const void*)fp; } virtual functor_base* clone() const { return new function_functor(*this); } }; // connect signal to a void function template void connect(signal& s, void (*fp)(T1, T2, T3, T4, T5, T6, T7)) { s.connect(function_functor<7,T1, T2, T3, T4, T5, T6, T7>(fp)); } // disconnect signal from a void function template void disconnect(signal& s, void (*fp)(T1, T2, T3, T4, T5, T6, T7)) { s.disconnect(function_functor<7,T1, T2, T3, T4, T5, T6, T7>(fp)); } template class method_functor<7,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<7,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<7,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*method_ptr)(T1, T2, T3, T4, T5, T6, T7); X* ip; method_ptr mp; method_functor(X* _ip, method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7) const { (ip->*mp)(v1, v2, v3, v4, v5, v6, v7); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new method_functor(*this); } }; /// connect signal to a void method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7)) { s.connect(method_functor<7,X,X,T1, T2, T3, T4, T5, T6, T7>(ip,mp)); } //! connect signal to a void method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7)) { s.connect(method_functor<7,X,Y,T1, T2, T3, T4, T5, T6, T7>(ip,mp)); } /// disconnect signal from a void method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7)) { s.disconnect(method_functor<7,X,X,T1, T2, T3, T4, T5, T6, T7>(ip,mp)); } //! disconnect signal from a void method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7)) { s.disconnect(method_functor<7,X,Y,T1, T2, T3, T4, T5, T6, T7>(ip,mp)); } template class const_method_functor<7,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<7,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<7,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*const_method_ptr)(T1, T2, T3, T4, T5, T6, T7) const; const X* ip; const_method_ptr mp; const_method_functor(const X* _ip, const_method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7) const { (ip->*mp)(v1, v2, v3, v4, v5, v6, v7); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new const_method_functor(*this); } }; /// connect signal to a void const method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7) const) { s.connect(const_method_functor<7,X,X,T1, T2, T3, T4, T5, T6, T7>(ip,mp)); } /// disconnect signal from a void const method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7) const) { s.disconnect(const_method_functor<7,X,X,T1, T2, T3, T4, T5, T6, T7>(ip,mp)); } //! connect signal to a void const method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7) const) { s.connect(const_method_functor<7,X,Y,T1, T2, T3, T4, T5, T6, T7>(ip,mp)); } //! disconnect signal from a void const method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7) const) { s.disconnect(const_method_functor<7,X,Y,T1, T2, T3, T4, T5, T6, T7>(ip,mp)); } template class object_functor<7,X,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<7,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<7,T1, T2, T3, T4, T5, T6, T7, T8> S; mutable X ip; object_functor(typename type::func::make_argument::type _ip) : ip(_ip) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7) const { ip(v1, v2, v3, v4, v5, v6, v7); } const tacker* get_tacker() const { return type::cond::is_base_of::value?reinterpret_cast(&ip):0; } void put_pointers(const void* &p1, const void* &p2) const { p1 = &ip; p2 = 0; } virtual functor_base* clone() const { return new object_functor(*this); } }; // connect signal to the ()-operator of a referenced object template void connect(signal& s, X& ip) { s.connect(object_functor<7,X&,T1, T2, T3, T4, T5, T6, T7>(ip)); } // disconnect signal from the ()-operator of a referenced object template void disconnect(signal& s, X& ip) { s.disconnect(object_functor<7,X&,T1, T2, T3, T4, T5, T6, T7>(ip)); } // connect signal to the const ()-operator of a referenced const object template void connect(signal& s, const X& ip) { s.connect(object_functor<7,const X&,T1, T2, T3, T4, T5, T6, T7>(ip)); } // disconnect signal from the const ()-operator of a referenced const object template void disconnect(signal& s, const X& ip) { s.disconnect(object_functor<7,const X&,T1, T2, T3, T4, T5, T6, T7>(ip)); } // connect signal to the ()-operator of a copy of a temporary object, a reference to the copy is returned for disconnection template X& connect_copy(signal& s, const X& ip) { return static_cast&>(s.connect(object_functor<7,X,T1, T2, T3, T4, T5, T6, T7>(ip))).ip; } template class functor<8,T1, T2, T3, T4, T5, T6, T7, T8> : public functor_base, public signature<8,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<8,T1, T2, T3, T4, T5, T6, T7, T8> S; virtual void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7, typename S::A8 v8) const = 0; }; // implementation of a boolean signal with a signature of length 8 template class signal_impl<8,T1, T2, T3, T4, T5, T6, T7, T8> : public signal_base, public signature<8,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<8,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef functor<8,T1, T2, T3, T4, T5, T6, T7, T8> functor_type; // emit the signal with the ()-operator by using it like bool function void operator ()(typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7, typename S::A8 v8) const { unsigned n = (unsigned) functors.size(); for (unsigned i=0; i(functors[i]))(v1, v2, v3, v4, v5, v6, v7, v8); } functor_type& connect(const functor_type& _f) { functor_type *f = static_cast(_f.clone()); signal_base::connect(f); return *f; } void disconnect(const functor_type& f) { signal_base::disconnect(&f); } }; template class function_functor<8,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<8,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<8,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (*function_ptr)(T1, T2, T3, T4, T5, T6, T7, T8); function_ptr fp; function_functor(function_ptr _fp) : fp(_fp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7, typename S::A8 v8) const { fp(v1,v2,v3,v4,v5,v6,v7,v8); } void put_pointers(const void* &p1, const void* &p2) const { p1 = 0; p2 = (const void*)fp; } virtual functor_base* clone() const { return new function_functor(*this); } }; // connect signal to a void function template void connect(signal& s, void (*fp)(T1, T2, T3, T4, T5, T6, T7, T8)) { s.connect(function_functor<8,T1, T2, T3, T4, T5, T6, T7, T8>(fp)); } // disconnect signal from a void function template void disconnect(signal& s, void (*fp)(T1, T2, T3, T4, T5, T6, T7, T8)) { s.disconnect(function_functor<8,T1, T2, T3, T4, T5, T6, T7, T8>(fp)); } template class method_functor<8,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<8,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<8,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*method_ptr)(T1, T2, T3, T4, T5, T6, T7, T8); X* ip; method_ptr mp; method_functor(X* _ip, method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7, typename S::A8 v8) const { (ip->*mp)(v1, v2, v3, v4, v5, v6, v7, v8); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new method_functor(*this); } }; /// connect signal to a void method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7, T8)) { s.connect(method_functor<8,X,X,T1, T2, T3, T4, T5, T6, T7, T8>(ip,mp)); } //! connect signal to a void method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7, T8)) { s.connect(method_functor<8,X,Y,T1, T2, T3, T4, T5, T6, T7, T8>(ip,mp)); } /// disconnect signal from a void method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7, T8)) { s.disconnect(method_functor<8,X,X,T1, T2, T3, T4, T5, T6, T7, T8>(ip,mp)); } //! disconnect signal from a void method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7, T8)) { s.disconnect(method_functor<8,X,Y,T1, T2, T3, T4, T5, T6, T7, T8>(ip,mp)); } template class const_method_functor<8,X,Y,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<8,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<8,T1, T2, T3, T4, T5, T6, T7, T8> S; typedef void (X::*const_method_ptr)(T1, T2, T3, T4, T5, T6, T7, T8) const; const X* ip; const_method_ptr mp; const_method_functor(const X* _ip, const_method_ptr _mp) : ip(_ip), mp(_mp) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7, typename S::A8 v8) const { (ip->*mp)(v1, v2, v3, v4, v5, v6, v7, v8); } const tacker* get_tacker() const { return static_cast(static_cast(ip)); } void put_pointers(const void* &p1, const void* &p2) const { p1 = ip; p2 = (void*&)mp; } virtual functor_base* clone() const { return new const_method_functor(*this); } }; /// connect signal to a void const method of an object template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7, T8) const) { s.connect(const_method_functor<8,X,X,T1, T2, T3, T4, T5, T6, T7, T8>(ip,mp)); } /// disconnect signal from a void const method of an object template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7, T8) const) { s.disconnect(const_method_functor<8,X,X,T1, T2, T3, T4, T5, T6, T7, T8>(ip,mp)); } //! connect signal to a void const method, where an additional template argument can be used to specify a base class /*! This version of connect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to connect an instance x of type X via connect(sig,x,&X::callback) if the tacker of Y is to be used and connect(sig,x,&X::callback) if the tacker of Z is to be used. In most cases it does not matter which tacker is used. */ template void connect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7, T8) const) { s.connect(const_method_functor<8,X,Y,T1, T2, T3, T4, T5, T6, T7, T8>(ip,mp)); } //! disconnect signal from a void const method of an object, where an additional template argument can be used to specify a base class /*! This version of disconnect is necessary for class types X derived via multiple inheritance from cgv::signal::tacker via several base classes, such that the conversion static_cast becomes ambigeous. For an example suppose X inherits Y and Z and both Y and Z inherit cgv::signal::tacker. Then once needs to disconnect an instance x of type X via disconnect(sig,x,&X::callback) if the tacker of Y has been connected with connect and connect(sig,x,&X::callback) if the tacker of Z had been used. For disconnect the same tacker has to be used as in the corresponding connect call!!! */ template void disconnect(signal& s, X* ip, void (X::*mp)(T1, T2, T3, T4, T5, T6, T7, T8) const) { s.disconnect(const_method_functor<8,X,Y,T1, T2, T3, T4, T5, T6, T7, T8>(ip,mp)); } template class object_functor<8,X,T1, T2, T3, T4, T5, T6, T7, T8> : public functor<8,T1, T2, T3, T4, T5, T6, T7, T8> { public: typedef signature<8,T1, T2, T3, T4, T5, T6, T7, T8> S; mutable X ip; object_functor(typename type::func::make_argument::type _ip) : ip(_ip) {} void operator() (typename S::A1 v1, typename S::A2 v2, typename S::A3 v3, typename S::A4 v4, typename S::A5 v5, typename S::A6 v6, typename S::A7 v7, typename S::A8 v8) const { ip(v1, v2, v3, v4, v5, v6, v7, v8); } const tacker* get_tacker() const { return type::cond::is_base_of::value?reinterpret_cast(&ip):0; } void put_pointers(const void* &p1, const void* &p2) const { p1 = &ip; p2 = 0; } virtual functor_base* clone() const { return new object_functor(*this); } }; // connect signal to the ()-operator of a referenced object template void connect(signal& s, X& ip) { s.connect(object_functor<8,X&,T1, T2, T3, T4, T5, T6, T7, T8>(ip)); } // disconnect signal from the ()-operator of a referenced object template void disconnect(signal& s, X& ip) { s.disconnect(object_functor<8,X&,T1, T2, T3, T4, T5, T6, T7, T8>(ip)); } // connect signal to the const ()-operator of a referenced const object template void connect(signal& s, const X& ip) { s.connect(object_functor<8,const X&,T1, T2, T3, T4, T5, T6, T7, T8>(ip)); } // disconnect signal from the const ()-operator of a referenced const object template void disconnect(signal& s, const X& ip) { s.disconnect(object_functor<8,const X&,T1, T2, T3, T4, T5, T6, T7, T8>(ip)); } // connect signal to the ()-operator of a copy of a temporary object, a reference to the copy is returned for disconnection template X& connect_copy(signal& s, const X& ip) { return static_cast&>(s.connect(object_functor<8,X,T1, T2, T3, T4, T5, T6, T7, T8>(ip))).ip; } } }