2015-07-16 00:37:37 +00:00
|
|
|
/* Signals/slots for OctaSTD.
|
|
|
|
*
|
|
|
|
* This file is part of OctaSTD. See COPYING.md for futher information.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef OSTD_SIGNAL_HH
|
|
|
|
#define OSTD_SIGNAL_HH
|
|
|
|
|
|
|
|
#include "ostd/functional.hh"
|
|
|
|
#include "ostd/utility.hh"
|
|
|
|
|
|
|
|
namespace ostd {
|
|
|
|
|
|
|
|
template<typename C, typename ...A>
|
|
|
|
struct Event {
|
|
|
|
Event(C *cl = nullptr): p_class(cl), p_funcs(nullptr), p_nfuncs(0) {}
|
|
|
|
|
|
|
|
Event(const Event &ev): p_class(ev.p_class), p_nfuncs(ev.p_nfuncs) {
|
|
|
|
using Func = Function<void(C &, A...)>;
|
|
|
|
Func *nbuf = (Func *)new byte[sizeof(Func) * p_nfuncs];
|
|
|
|
for (Size i = 0; i < p_nfuncs; ++i)
|
|
|
|
new (&nbuf[i]) Func(ev.p_funcs[i]);
|
|
|
|
p_funcs = nbuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
Event(Event &&ev): p_class(ev.p_class), p_funcs(ev.p_funcs),
|
|
|
|
p_nfuncs(ev.p_nfuncs) {
|
|
|
|
ev.p_class = nullptr;
|
|
|
|
ev.p_funcs = nullptr;
|
|
|
|
ev.p_nfuncs = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
~Event() {
|
2015-07-16 00:40:58 +00:00
|
|
|
clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void clear() {
|
2015-07-16 00:37:37 +00:00
|
|
|
for (Size i = 0; i < p_nfuncs; ++i)
|
|
|
|
p_funcs[i].~Function<void(C &, A...)>();
|
|
|
|
delete[] (byte *)p_funcs;
|
2015-07-16 00:40:58 +00:00
|
|
|
p_funcs = nullptr;
|
|
|
|
p_nfuncs = 0;
|
2015-07-16 00:37:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename F>
|
|
|
|
Size connect(F func) {
|
|
|
|
using Func = Function<void(C &, A...)>;
|
|
|
|
Func *nbuf = (Func *)new byte[sizeof(Func) * (p_nfuncs + 1)];
|
|
|
|
for (Size i = 0; i < p_nfuncs; ++i) {
|
|
|
|
new (&nbuf[i]) Func(move(p_funcs[i]));
|
|
|
|
p_funcs[i].~Func();
|
|
|
|
}
|
|
|
|
new (&nbuf[p_nfuncs]) Func(func);
|
|
|
|
delete[] (byte *)p_funcs;
|
|
|
|
p_funcs = nbuf;
|
|
|
|
return p_nfuncs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool disconnect(Size idx) {
|
|
|
|
if ((idx >= p_nfuncs) || !p_funcs[idx]) return false;
|
|
|
|
p_funcs[idx] = nullptr;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename ...Args>
|
2015-07-16 00:42:35 +00:00
|
|
|
void emit(Args &&...args) const {
|
2015-07-16 00:37:37 +00:00
|
|
|
if (!p_class) return;
|
|
|
|
for (Size i = 0; i < p_nfuncs; ++i)
|
|
|
|
if (p_funcs[i]) p_funcs[i](*p_class, args...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename ...Args>
|
2015-07-16 00:42:35 +00:00
|
|
|
void operator()(Args &&...args) const {
|
2015-07-16 00:37:37 +00:00
|
|
|
emit(forward<Args>(args)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
C *p_class;
|
|
|
|
Function<void(C &, A...)> *p_funcs;
|
|
|
|
Size p_nfuncs;
|
|
|
|
};
|
|
|
|
|
|
|
|
} /* namespace ostd */
|
|
|
|
|
|
|
|
#endif
|