#pragma once #include "common.hpp" #include "events/signal_receiver.hpp" #include "utils/factory.hpp" #include "utils/mixins.hpp" POLYBAR_NS /** * @brief Holds all signal receivers attached to the emitter */ extern signal_receivers_t g_signal_receivers; /** * Wrapper used to delegate emitted signals * to attached signal receivers */ class signal_emitter { public: using make_type = signal_emitter&; static make_type make(); explicit signal_emitter() = default; virtual ~signal_emitter() {} template bool emit(const Signal& sig) { try { for (auto&& item : g_signal_receivers.at(id())) { if (item.second->on(sig)) { return true; } } } catch (...) { } return false; } template bool emit(const Signal& sig) const { return emit(sig) || emit(sig); } template void attach(signal_receiver* s) { attach, Signal, Signals...>(s); } template void detach(signal_receiver* s) { detach, Signal, Signals...>(s); } protected: template uint8_t id() const { return Signal::id(); } template void attach(Receiver* s) { attach(s, id()); } template void attach(Receiver* s) { attach(s, id()); attach(s); } void attach(signal_receiver_interface* s, uint8_t id) { g_signal_receivers[id].emplace(s->priority(), s); } template void detach(Receiver* s) { detach(s, id()); } template void detach(Receiver* s) { detach(s, id()); detach(s); } void detach(signal_receiver_interface* d, uint8_t id) { try { auto& prio_map = g_signal_receivers.at(id); const auto& prio_sink_pair = prio_map.equal_range(d->priority()); for (auto it = prio_sink_pair.first; it != prio_sink_pair.second;) { if (d == it->second) { it = prio_map.erase(it); } else { ++it; } } } catch (...) { } } }; POLYBAR_NS_END