7#include <cgv/signal/abst_signal.h>
11#define MSG_ERROR "\x1b[1;31m[error]\x1b[39m[cgv::signal]\x1b[m"
17void connect(signal<>& s,
void(*fp)())
19 s.connect(function_functor<0>(fp));
22void disconnect(signal<>& s,
void(*fp)())
24 s.disconnect(function_functor<0>(fp));
27signal_base::~signal_base() noexcept
33void signal_base::connect_abst(functor_base* fp)
38void signal_base::link(receiver& rcvr)
41 rcvr.tacker_ptr->tack(
this);
44void signal_base::unlink(receiver& rcvr)
47 rcvr.tacker_ptr->untack(
this);
50void signal_base::connect(functor_base* fp)
52 receivers.push_back({std::unique_ptr<functor_base>{fp}, fp->get_tacker()});
53 link(receivers.back());
56void signal_base::disconnect(
const functor_base* fp)
59 receivers.erase(std::remove_if(receivers.begin(), receivers.end(), [
this, &found, fp](receiver& rcvr) {
60 if(*rcvr.functor == *fp) {
70 std::cerr << MSG_ERROR
" Attempted to disconnect a functor from a signal it is not connected to.\n";
74void signal_base::disconnect(
const tacker* c)
77 receivers.erase(std::remove_if(receivers.begin(), receivers.end(), [
this, &found, c](receiver& rcvr) {
78 if(rcvr.tacker_ptr == c) {
88 std::cerr << MSG_ERROR
" Attempted to disconnect a tacker from a signal it is not connected to.\n";
92void signal_base::disconnect_all()
94 for (
auto& rcvr : receivers)
100const tacker* functor_base::get_tacker()
const
102 return dynamic_cast<const tacker*
>(
this);
105bool functor_base::operator == (
const functor_base& f)
const
107 const void *p1, *p2, *q1, *q2;
109 f.put_pointers(q1,q2);
110 return p1 == q1 && p2 == q2;
114void tacker::tack(signal_base* s)
const
118void tacker::untack(signal_base* s)
const
120 const auto s_it = signals.find(s);
121 if (s_it == signals.end()) {
123 std::cout << MSG_ERROR
" Attempted to untack a signal for a tacker that is not connected to it.\n";
128 if (--s_it->second == 0)
132void tacker::untack_all()
const
134 for (
auto& signal : signals) {
135 auto& receivers = signal.first->receivers;
138 receivers.erase(std::remove_if(receivers.begin(), receivers.end(), [
this, &signal, &done, &removed](signal_base::receiver& rcvr) {
139 if(!done && rcvr.tacker_ptr == this) {
140 if(++removed == signal.second)
145 }), receivers.end());
149tacker::~tacker() noexcept
this header is dependency free