1#ifndef UVW_EMITTER_INCLUDE_H
2#define UVW_EMITTER_INCLUDE_H
11#include <unordered_map>
14#include "type_info.hpp"
24 template<
typename U,
typename = std::enable_if_t<std::is_
integral_v<U>>>
26 : ec{
static_cast<int>(val)} {}
49 const char *
what() const noexcept;
58 const
char *
name() const noexcept;
70 explicit operator
bool() const noexcept;
85 virtual ~BaseHandler()
noexcept =
default;
86 virtual bool empty()
const noexcept = 0;
87 virtual void clear()
noexcept = 0;
91 struct Handler final: BaseHandler {
92 using Listener = std::function<void(E &, T &)>;
93 using Element = std::pair<bool, Listener>;
94 using ListenerList = std::list<Element>;
95 using Connection =
typename ListenerList::iterator;
97 bool empty()
const noexcept override {
98 auto pred = [](
auto &&element) {
return element.first; };
100 return std::all_of(onceL.cbegin(), onceL.cend(), pred) && std::all_of(onL.cbegin(), onL.cend(), pred);
103 void clear()
noexcept override {
105 auto func = [](
auto &&element) { element.first =
true; };
106 std::for_each(onceL.begin(), onceL.end(), func);
107 std::for_each(onL.begin(), onL.end(), func);
115 return onceL.emplace(onceL.cend(),
false, std::move(f));
119 return onL.emplace(onL.cend(),
false, std::move(f));
126 auto pred = [](
auto &&element) {
return element.first; };
127 onceL.remove_if(pred);
132 void publish(E event, T &ref) {
133 ListenerList currentL;
134 onceL.swap(currentL);
136 auto func = [&event, &ref](
auto &&element) {
137 return element.first ? void() : element.second(event, ref);
142 std::for_each(onL.rbegin(), onL.rend(), func);
143 std::for_each(currentL.rbegin(), currentL.rend(), func);
147 onL.remove_if([](
auto &&element) {
return element.first; });
151 bool publishing{
false};
152 ListenerList onceL{};
157 Handler<E> &handler()
noexcept {
160 if(!handlers.count(
id)) {
161 handlers[id] = std::make_unique<Handler<E>>();
164 return static_cast<Handler<E> &
>(*handlers.at(
id));
169 void publish(E event) {
170 handler<E>().publish(std::move(event), *
static_cast<T *
>(
this));
175 using Listener =
typename Handler<E>::Listener;
193 Connection(
typename Handler<E>::Connection conn)
194 : Handler<E>::Connection{std::move(conn)} {}
201 static_assert(std::is_base_of_v<Emitter<T>, T>);
221 return handler<E>().on(std::move(f));
241 return handler<E>().once(std::move(f));
250 handler<E>().erase(std::move(conn));
258 handler<E>().clear();
265 std::for_each(handlers.begin(), handlers.end(), [](
auto &&hdlr) { if(hdlr.second) { hdlr.second->clear(); } });
277 return (!handlers.count(
id) ||
static_cast<Handler<E> &
>(*handlers.at(
id)).empty());
286 return std::all_of(handlers.cbegin(), handlers.cend(), [](
auto &&hdlr) { return !hdlr.second || hdlr.second->empty(); });
290 std::unordered_map<std::uint32_t, std::unique_ptr<BaseHandler>> handlers{};
296# include "emitter.cpp"
Event emitter base class.
Connection< E > once(Listener< E > f)
Registers a short-lived listener with the event emitter.
bool empty() const noexcept
Checks if there are listeners registered for the specific event.
void clear() noexcept
Disconnects all the listeners for the given event type.
void erase(Connection< E > conn) noexcept
Disconnects a listener from the event emitter.
void clear() noexcept
Disconnects all the listeners.
bool empty() const noexcept
Checks if there are listeners registered with the event emitter.
Connection< E > on(Listener< E > f)
Registers a long-lived listener with the event emitter.
Connection type for a given event type.
const char * what() const noexcept
Returns the error message for the given error code.
int code() const noexcept
Gets the underlying error code, that is an error constant of libuv.
static int translate(int sys) noexcept
Returns the libuv error code equivalent to the given platform dependent error code.
const char * name() const noexcept
Returns the error name for the given error code.