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