1370 lines
No EOL
94 KiB
C++
1370 lines
No EOL
94 KiB
C++
#pragma once
|
|
|
|
#include <cgv/signal/abst_signal.h>
|
|
#include <cgv/type/invalid_type.h>
|
|
#include <cgv/type/cond/is_base_of.h>
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
namespace cgv {
|
|
namespace signal {
|
|
|
|
template <int i, typename T1 = type::invalid_type, typename T2 = type::invalid_type, typename T3 = type::invalid_type, typename T4 = type::invalid_type, typename T5 = type::invalid_type, typename T6 = type::invalid_type, typename T7 = type::invalid_type, typename T8 = type::invalid_type>
|
|
class functor;
|
|
|
|
template <int i, typename T1 = type::invalid_type, typename T2 = type::invalid_type, typename T3 = type::invalid_type, typename T4 = type::invalid_type, typename T5 = type::invalid_type, typename T6 = type::invalid_type, typename T7 = type::invalid_type, typename T8 = type::invalid_type>
|
|
class signal_impl;
|
|
|
|
// signal that sends callbacks to connected functions, methods or functors when executing the ()-oeprator of the signal
|
|
template <typename T1 = type::invalid_type, typename T2 = type::invalid_type, typename T3 = type::invalid_type, typename T4 = type::invalid_type, typename T5 = type::invalid_type, typename T6 = type::invalid_type, typename T7 = type::invalid_type, typename T8 = type::invalid_type>
|
|
class signal : public signal_impl<type::count_valid_types<T1, T2, T3, T4, T5, T6, T7, T8>::value, T1, T2, T3, T4, T5, T6, T7, T8>, public tacker
|
|
{
|
|
};
|
|
|
|
template <int i, typename T1 = type::invalid_type, typename T2 = type::invalid_type, typename T3 = type::invalid_type, typename T4 = type::invalid_type, typename T5 = type::invalid_type, typename T6 = type::invalid_type, typename T7 = type::invalid_type, typename T8 = type::invalid_type>
|
|
class function_functor;
|
|
|
|
template <int i, class X, class Y, typename T1 = type::invalid_type, typename T2 = type::invalid_type, typename T3 = type::invalid_type, typename T4 = type::invalid_type, typename T5 = type::invalid_type, typename T6 = type::invalid_type, typename T7 = type::invalid_type, typename T8 = type::invalid_type>
|
|
class method_functor;
|
|
|
|
template <int i, typename X, typename T1 = type::invalid_type, typename T2 = type::invalid_type, typename T3 = type::invalid_type, typename T4 = type::invalid_type, typename T5 = type::invalid_type, typename T6 = type::invalid_type, typename T7 = type::invalid_type, typename T8 = type::invalid_type>
|
|
class object_functor;
|
|
|
|
template <int i, class X, class Y, typename T1 = type::invalid_type, typename T2 = type::invalid_type, typename T3 = type::invalid_type, typename T4 = type::invalid_type, typename T5 = type::invalid_type, typename T6 = type::invalid_type, typename T7 = type::invalid_type, typename T8 = type::invalid_type>
|
|
class const_method_functor;
|
|
|
|
//template <int i, typename X, typename T1 = type::invalid_type, typename T2 = type::invalid_type, typename T3 = type::invalid_type, typename T4 = type::invalid_type, typename T5 = type::invalid_type, typename T6 = type::invalid_type, typename T7 = type::invalid_type, typename T8 = type::invalid_type>
|
|
//class const_object_functor;
|
|
|
|
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<n; ++i)
|
|
(*static_cast<functor_type*>(functors[i]))(v1);
|
|
}
|
|
functor_type& connect(const functor_type& _f) { functor_type *f = static_cast<functor_type*>(_f.clone()); signal_base::connect(f); return *f; }
|
|
void disconnect(const functor_type& f) { signal_base::disconnect(&f); }
|
|
};
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1>
|
|
void connect(signal<T1>& s, void (*fp)(T1)) { s.connect(function_functor<1,T1>(fp)); }
|
|
|
|
// disconnect signal from a void function
|
|
template <typename T1>
|
|
void disconnect(signal<T1>& s, void (*fp)(T1)) { s.disconnect(function_functor<1,T1>(fp)); }
|
|
|
|
|
|
template <class X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<const Y*>(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 <class X, typename T1>
|
|
void connect(signal<T1>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1>
|
|
void connect(signal<T1>& 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 <class X, typename T1>
|
|
void disconnect(signal<T1>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1>
|
|
void disconnect(signal<T1>& s, X* ip, void (X::*mp)(T1)) { s.disconnect(method_functor<1,X,Y,T1>(ip,mp)); }
|
|
|
|
template <class X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<Y*>(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 <class X, typename T1>
|
|
void connect(signal<T1>& 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 <class X, typename T1>
|
|
void disconnect(signal<T1>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1>
|
|
void connect(signal<T1>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1>
|
|
void disconnect(signal<T1>& s, X* ip, void (X::*mp)(T1) const) { s.disconnect(const_method_functor<1,X,Y,T1>(ip,mp)); }
|
|
|
|
|
|
template <typename X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<X>::type _ip) : ip(_ip) {}
|
|
void operator() (typename S::A1 v1) const { ip(v1); }
|
|
const tacker* get_tacker() const { return type::cond::is_base_of<tacker,X>::value?reinterpret_cast<const tacker*>(&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 <class X, typename T1>
|
|
void connect(signal<T1>& s, X& ip) { s.connect(object_functor<1,X&,T1>(ip)); }
|
|
// disconnect signal from the ()-operator of a referenced object
|
|
template <class X, typename T1>
|
|
void disconnect(signal<T1>& s, X& ip) { s.disconnect(object_functor<1,X&,T1>(ip)); }
|
|
// connect signal to the const ()-operator of a referenced const object
|
|
template <class X, typename T1>
|
|
void connect(signal<T1>& 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 <class X, typename T1>
|
|
void disconnect(signal<T1>& 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 <class X, typename T1>
|
|
X& connect_copy(signal<T1>& s, const X& ip) {
|
|
return static_cast<const object_functor<1,X,T1>&>(s.connect(object_functor<1,X,T1>(ip))).ip;
|
|
}
|
|
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<n; ++i)
|
|
(*static_cast<functor_type*>(functors[i]))(v1, v2);
|
|
}
|
|
functor_type& connect(const functor_type& _f) { functor_type *f = static_cast<functor_type*>(_f.clone()); signal_base::connect(f); return *f; }
|
|
void disconnect(const functor_type& f) { signal_base::disconnect(&f); }
|
|
};
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2>
|
|
void connect(signal<T1,T2>& s, void (*fp)(T1, T2)) { s.connect(function_functor<2,T1, T2>(fp)); }
|
|
|
|
// disconnect signal from a void function
|
|
template <typename T1, typename T2>
|
|
void disconnect(signal<T1,T2>& s, void (*fp)(T1, T2)) { s.disconnect(function_functor<2,T1, T2>(fp)); }
|
|
|
|
|
|
template <class X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<const Y*>(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 <class X, typename T1, typename T2>
|
|
void connect(signal<T1, T2>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2>
|
|
void connect(signal<T1, T2>& 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 <class X, typename T1, typename T2>
|
|
void disconnect(signal<T1, T2>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2>
|
|
void disconnect(signal<T1, T2>& s, X* ip, void (X::*mp)(T1, T2)) { s.disconnect(method_functor<2,X,Y,T1, T2>(ip,mp)); }
|
|
|
|
template <class X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<Y*>(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 <class X, typename T1, typename T2>
|
|
void connect(signal<T1, T2>& 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 <class X, typename T1, typename T2>
|
|
void disconnect(signal<T1, T2>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2>
|
|
void connect(signal<T1, T2>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2>
|
|
void disconnect(signal<T1, T2>& s, X* ip, void (X::*mp)(T1, T2) const) { s.disconnect(const_method_functor<2,X,Y,T1, T2>(ip,mp)); }
|
|
|
|
|
|
template <typename X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<X>::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<tacker,X>::value?reinterpret_cast<const tacker*>(&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 <class X, typename T1, typename T2>
|
|
void connect(signal<T1, T2>& s, X& ip) { s.connect(object_functor<2,X&,T1, T2>(ip)); }
|
|
// disconnect signal from the ()-operator of a referenced object
|
|
template <class X, typename T1, typename T2>
|
|
void disconnect(signal<T1, T2>& s, X& ip) { s.disconnect(object_functor<2,X&,T1, T2>(ip)); }
|
|
// connect signal to the const ()-operator of a referenced const object
|
|
template <class X, typename T1, typename T2>
|
|
void connect(signal<T1, T2>& 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 <class X, typename T1, typename T2>
|
|
void disconnect(signal<T1, T2>& 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 <class X, typename T1, typename T2>
|
|
X& connect_copy(signal<T1, T2>& s, const X& ip) {
|
|
return static_cast<const object_functor<2,X,T1, T2>&>(s.connect(object_functor<2,X,T1, T2>(ip))).ip;
|
|
}
|
|
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<n; ++i)
|
|
(*static_cast<functor_type*>(functors[i]))(v1, v2, v3);
|
|
}
|
|
functor_type& connect(const functor_type& _f) { functor_type *f = static_cast<functor_type*>(_f.clone()); signal_base::connect(f); return *f; }
|
|
void disconnect(const functor_type& f) { signal_base::disconnect(&f); }
|
|
};
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3>
|
|
void connect(signal<T1,T2,T3>& s, void (*fp)(T1, T2, T3)) { s.connect(function_functor<3,T1, T2, T3>(fp)); }
|
|
|
|
// disconnect signal from a void function
|
|
template <typename T1, typename T2, typename T3>
|
|
void disconnect(signal<T1,T2,T3>& s, void (*fp)(T1, T2, T3)) { s.disconnect(function_functor<3,T1, T2, T3>(fp)); }
|
|
|
|
|
|
template <class X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<const Y*>(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 <class X, typename T1, typename T2, typename T3>
|
|
void connect(signal<T1, T2, T3>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3>
|
|
void connect(signal<T1, T2, T3>& 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 <class X, typename T1, typename T2, typename T3>
|
|
void disconnect(signal<T1, T2, T3>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3>
|
|
void disconnect(signal<T1, T2, T3>& s, X* ip, void (X::*mp)(T1, T2, T3)) { s.disconnect(method_functor<3,X,Y,T1, T2, T3>(ip,mp)); }
|
|
|
|
template <class X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<Y*>(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 <class X, typename T1, typename T2, typename T3>
|
|
void connect(signal<T1, T2, T3>& 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 <class X, typename T1, typename T2, typename T3>
|
|
void disconnect(signal<T1, T2, T3>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3>
|
|
void connect(signal<T1, T2, T3>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3>
|
|
void disconnect(signal<T1, T2, T3>& s, X* ip, void (X::*mp)(T1, T2, T3) const) { s.disconnect(const_method_functor<3,X,Y,T1, T2, T3>(ip,mp)); }
|
|
|
|
|
|
template <typename X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<X>::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<tacker,X>::value?reinterpret_cast<const tacker*>(&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 <class X, typename T1, typename T2, typename T3>
|
|
void connect(signal<T1, T2, T3>& s, X& ip) { s.connect(object_functor<3,X&,T1, T2, T3>(ip)); }
|
|
// disconnect signal from the ()-operator of a referenced object
|
|
template <class X, typename T1, typename T2, typename T3>
|
|
void disconnect(signal<T1, T2, T3>& 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 <class X, typename T1, typename T2, typename T3>
|
|
void connect(signal<T1, T2, T3>& 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 <class X, typename T1, typename T2, typename T3>
|
|
void disconnect(signal<T1, T2, T3>& 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 <class X, typename T1, typename T2, typename T3>
|
|
X& connect_copy(signal<T1, T2, T3>& s, const X& ip) {
|
|
return static_cast<const object_functor<3,X,T1, T2, T3>&>(s.connect(object_functor<3,X,T1, T2, T3>(ip))).ip;
|
|
}
|
|
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<n; ++i)
|
|
(*static_cast<functor_type*>(functors[i]))(v1, v2, v3, v4);
|
|
}
|
|
functor_type& connect(const functor_type& _f) { functor_type *f = static_cast<functor_type*>(_f.clone()); signal_base::connect(f); return *f; }
|
|
void disconnect(const functor_type& f) { signal_base::disconnect(&f); }
|
|
};
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4>
|
|
void connect(signal<T1,T2,T3,T4>& s, void (*fp)(T1, T2, T3, T4)) { s.connect(function_functor<4,T1, T2, T3, T4>(fp)); }
|
|
|
|
// disconnect signal from a void function
|
|
template <typename T1, typename T2, typename T3, typename T4>
|
|
void disconnect(signal<T1,T2,T3,T4>& s, void (*fp)(T1, T2, T3, T4)) { s.disconnect(function_functor<4,T1, T2, T3, T4>(fp)); }
|
|
|
|
|
|
template <class X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<const Y*>(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 <class X, typename T1, typename T2, typename T3, typename T4>
|
|
void connect(signal<T1, T2, T3, T4>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4>
|
|
void connect(signal<T1, T2, T3, T4>& 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 <class X, typename T1, typename T2, typename T3, typename T4>
|
|
void disconnect(signal<T1, T2, T3, T4>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4>
|
|
void disconnect(signal<T1, T2, T3, T4>& 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 X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<Y*>(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 <class X, typename T1, typename T2, typename T3, typename T4>
|
|
void connect(signal<T1, T2, T3, T4>& 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 <class X, typename T1, typename T2, typename T3, typename T4>
|
|
void disconnect(signal<T1, T2, T3, T4>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4>
|
|
void connect(signal<T1, T2, T3, T4>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4>
|
|
void disconnect(signal<T1, T2, T3, T4>& 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 <typename X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<X>::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<tacker,X>::value?reinterpret_cast<const tacker*>(&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 <class X, typename T1, typename T2, typename T3, typename T4>
|
|
void connect(signal<T1, T2, T3, T4>& s, X& ip) { s.connect(object_functor<4,X&,T1, T2, T3, T4>(ip)); }
|
|
// disconnect signal from the ()-operator of a referenced object
|
|
template <class X, typename T1, typename T2, typename T3, typename T4>
|
|
void disconnect(signal<T1, T2, T3, T4>& 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 <class X, typename T1, typename T2, typename T3, typename T4>
|
|
void connect(signal<T1, T2, T3, T4>& 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 <class X, typename T1, typename T2, typename T3, typename T4>
|
|
void disconnect(signal<T1, T2, T3, T4>& 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 <class X, typename T1, typename T2, typename T3, typename T4>
|
|
X& connect_copy(signal<T1, T2, T3, T4>& s, const X& ip) {
|
|
return static_cast<const object_functor<4,X,T1, T2, T3, T4>&>(s.connect(object_functor<4,X,T1, T2, T3, T4>(ip))).ip;
|
|
}
|
|
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<n; ++i)
|
|
(*static_cast<functor_type*>(functors[i]))(v1, v2, v3, v4, v5);
|
|
}
|
|
functor_type& connect(const functor_type& _f) { functor_type *f = static_cast<functor_type*>(_f.clone()); signal_base::connect(f); return *f; }
|
|
void disconnect(const functor_type& f) { signal_base::disconnect(&f); }
|
|
};
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void connect(signal<T1,T2,T3,T4,T5>& 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 <typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void disconnect(signal<T1,T2,T3,T4,T5>& s, void (*fp)(T1, T2, T3, T4, T5)) { s.disconnect(function_functor<5,T1, T2, T3, T4, T5>(fp)); }
|
|
|
|
|
|
template <class X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<const Y*>(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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void connect(signal<T1, T2, T3, T4, T5>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void connect(signal<T1, T2, T3, T4, T5>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void disconnect(signal<T1, T2, T3, T4, T5>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void disconnect(signal<T1, T2, T3, T4, T5>& 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 X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<Y*>(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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void connect(signal<T1, T2, T3, T4, T5>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void disconnect(signal<T1, T2, T3, T4, T5>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void connect(signal<T1, T2, T3, T4, T5>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void disconnect(signal<T1, T2, T3, T4, T5>& 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 <typename X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<X>::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<tacker,X>::value?reinterpret_cast<const tacker*>(&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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void connect(signal<T1, T2, T3, T4, T5>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void disconnect(signal<T1, T2, T3, T4, T5>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void connect(signal<T1, T2, T3, T4, T5>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
void disconnect(signal<T1, T2, T3, T4, T5>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5>
|
|
X& connect_copy(signal<T1, T2, T3, T4, T5>& s, const X& ip) {
|
|
return static_cast<const object_functor<5,X,T1, T2, T3, T4, T5>&>(s.connect(object_functor<5,X,T1, T2, T3, T4, T5>(ip))).ip;
|
|
}
|
|
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<n; ++i)
|
|
(*static_cast<functor_type*>(functors[i]))(v1, v2, v3, v4, v5, v6);
|
|
}
|
|
functor_type& connect(const functor_type& _f) { functor_type *f = static_cast<functor_type*>(_f.clone()); signal_base::connect(f); return *f; }
|
|
void disconnect(const functor_type& f) { signal_base::disconnect(&f); }
|
|
};
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void connect(signal<T1,T2,T3,T4,T5,T6>& 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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void disconnect(signal<T1,T2,T3,T4,T5,T6>& s, void (*fp)(T1, T2, T3, T4, T5, T6)) { s.disconnect(function_functor<6,T1, T2, T3, T4, T5, T6>(fp)); }
|
|
|
|
|
|
template <class X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<const Y*>(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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6>& 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 X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<Y*>(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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6>& 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 <typename X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<X>::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<tacker,X>::value?reinterpret_cast<const tacker*>(&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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
|
X& connect_copy(signal<T1, T2, T3, T4, T5, T6>& s, const X& ip) {
|
|
return static_cast<const object_functor<6,X,T1, T2, T3, T4, T5, T6>&>(s.connect(object_functor<6,X,T1, T2, T3, T4, T5, T6>(ip))).ip;
|
|
}
|
|
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<n; ++i)
|
|
(*static_cast<functor_type*>(functors[i]))(v1, v2, v3, v4, v5, v6, v7);
|
|
}
|
|
functor_type& connect(const functor_type& _f) { functor_type *f = static_cast<functor_type*>(_f.clone()); signal_base::connect(f); return *f; }
|
|
void disconnect(const functor_type& f) { signal_base::disconnect(&f); }
|
|
};
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void connect(signal<T1,T2,T3,T4,T5,T6,T7>& 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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void disconnect(signal<T1,T2,T3,T4,T5,T6,T7>& 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 X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<const Y*>(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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7>& 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 X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<Y*>(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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7>& 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 <typename X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<X>::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<tacker,X>::value?reinterpret_cast<const tacker*>(&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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
|
X& connect_copy(signal<T1, T2, T3, T4, T5, T6, T7>& s, const X& ip) {
|
|
return static_cast<const object_functor<7,X,T1, T2, T3, T4, T5, T6, T7>&>(s.connect(object_functor<7,X,T1, T2, T3, T4, T5, T6, T7>(ip))).ip;
|
|
}
|
|
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<n; ++i)
|
|
(*static_cast<functor_type*>(functors[i]))(v1, v2, v3, v4, v5, v6, v7, v8);
|
|
}
|
|
functor_type& connect(const functor_type& _f) { functor_type *f = static_cast<functor_type*>(_f.clone()); signal_base::connect(f); return *f; }
|
|
void disconnect(const functor_type& f) { signal_base::disconnect(&f); }
|
|
};
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void connect(signal<T1,T2,T3,T4,T5,T6,T7,T8>& 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 <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void disconnect(signal<T1,T2,T3,T4,T5,T6,T7,T8>& 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 X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<const Y*>(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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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 X, class Y, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<const tacker*>(static_cast<Y*>(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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y is to be used and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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<cgv::signal::tacker> 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<Y>(sig,x,&X::callback) if the tacker of Y has been connected with connect<Y>
|
|
and connect<Z>(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 <class Y, class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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 <typename X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
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<X>::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<tacker,X>::value?reinterpret_cast<const tacker*>(&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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void connect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
void disconnect(signal<T1, T2, T3, T4, T5, T6, T7, T8>& 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 <class X, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
|
X& connect_copy(signal<T1, T2, T3, T4, T5, T6, T7, T8>& s, const X& ip) {
|
|
return static_cast<const object_functor<8,X,T1, T2, T3, T4, T5, T6, T7, T8>&>(s.connect(object_functor<8,X,T1, T2, T3, T4, T5, T6, T7, T8>(ip))).ip;
|
|
}
|
|
|
|
|
|
}
|
|
} |