#ifndef CANVAS_SIGNAL_HPP #define CANVAS_SIGNAL_HPP #include "callable.hpp" #include #include namespace ce { /*! Observer-listener implementation */ template class Signal { std::vector> listeners{}; public: void connect(Callable callable); void disconnect(Callable callable); void invoke(Args...); }; template void Signal::connect(Callable callable) { this->listeners.push_back(callable); } template void Signal::disconnect(Callable callable) { std::erase_if(this->listeners, [&callable](Callable &listener) -> bool { return listener == callable; }); } template void Signal::invoke(Args... args) { for(Callable &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 signal; A object; Callable callable{Callable::make(&object, &A::f)}; signal.connect(callable); signal.invoke(5); signal.disconnect(callable); signal.invoke(10); } #endif } #endif // !CANVAS_SIGNAL_HPP