kernmodule-cpp/src/core/signal.hpp

55 lines
1.3 KiB
C++

#ifndef CANVAS_SIGNAL_HPP
#define CANVAS_SIGNAL_HPP
#include "callable.hpp"
#include <cstdio>
#include <vector>
namespace ce {
/*! Observer-listener implementation
*/
template <class... Args>
class Signal {
std::vector<Callable<void, Args...>> listeners{};
public:
void connect(Callable<void, Args...> callable);
void disconnect(Callable<void, Args...> callable);
void invoke(Args...);
};
template <class... Args> void Signal<Args...>::connect(Callable<void, Args...> callable) {
this->listeners.push_back(callable);
}
template <class... Args> void Signal<Args...>::disconnect(Callable<void, Args...> callable) {
std::erase_if(this->listeners,
[&callable](Callable<void, Args...> &listener) -> bool {
return listener == callable;
});
}
template <class... Args> void Signal<Args...>::invoke(Args... args) {
for(Callable<void, Args...> &listener : this->listeners) {
listener.call(args...);
}
}
#if DEBUG
static inline
void TEST_signals() {
struct A {inline void f(int val) {
std::printf("%d\n", val);
}};
Signal<int> signal;
A object;
Callable<void, int> callable{Callable<void, int>::make(&object, &A::f)};
signal.connect(callable);
signal.invoke(5);
signal.disconnect(callable);
signal.invoke(10);
}
#endif
}
#endif // !CANVAS_SIGNAL_HPP