1#ifndef UVW_EMITTER_INCLUDE_H
2#define UVW_EMITTER_INCLUDE_H
10#include <unordered_map>
13#include "type_info.hpp"
23 template<
typename U,
typename = std::enable_if_t<std::is_
integral_v<U>>>
25 : ec{
static_cast<int>(val)} {}
48 const char *
what() const noexcept;
57 const
char *
name() const noexcept;
69 explicit operator
bool() const noexcept;
84 virtual ~BaseHandler()
noexcept =
default;
85 virtual bool empty()
const noexcept = 0;
86 virtual void clear()
noexcept = 0;
90 struct Handler final: BaseHandler {
91 using Listener = std::function<void(E &, T &)>;
92 using Element = std::pair<bool, Listener>;
93 using ListenerList = std::list<Element>;
94 using Connection =
typename ListenerList::iterator;
96 bool empty()
const noexcept override {
97 auto pred = [](
auto &&element) {
return element.first; };
99 return std::all_of(onceL.cbegin(), onceL.cend(), pred) && std::all_of(onL.cbegin(), onL.cend(), pred);
102 void clear()
noexcept override {
104 auto func = [](
auto &&element) { element.first =
true; };
105 std::for_each(onceL.begin(), onceL.end(), func);
106 std::for_each(onL.begin(), onL.end(), func);
114 return onceL.emplace(onceL.cend(),
false, std::move(f));
118 return onL.emplace(onL.cend(),
false, std::move(f));
125 auto pred = [](
auto &&element) {
return element.first; };
126 onceL.remove_if(pred);
131 void publish(E event, T &ref) {
132 ListenerList currentL;
133 onceL.swap(currentL);
135 auto func = [&event, &ref](
auto &&element) {
136 return element.first ? void() : element.second(event, ref);
141 std::for_each(onL.rbegin(), onL.rend(), func);
142 std::for_each(currentL.rbegin(), currentL.rend(), func);
146 onL.remove_if([](
auto &&element) {
return element.first; });
150 bool publishing{
false};
151 ListenerList onceL{};
156 Handler<E> &handler()
noexcept {
159 if(!handlers.count(
id)) {
160 handlers[id] = std::make_unique<Handler<E>>();
163 return static_cast<Handler<E> &
>(*handlers.at(
id));
168 void publish(E event) {
169 handler<E>().publish(std::move(event), *
static_cast<T *
>(
this));
174 using Listener =
typename Handler<E>::Listener;
192 Connection(
typename Handler<E>::Connection conn)
193 : Handler<E>::Connection{std::move(conn)} {}
200 static_assert(std::is_base_of_v<Emitter<T>, T>);
220 return handler<E>().on(std::move(f));
240 return handler<E>().once(std::move(f));
249 handler<E>().erase(std::move(conn));
257 handler<E>().clear();
264 std::for_each(handlers.begin(), handlers.end(), [](
auto &&hdlr) { if(hdlr.second) { hdlr.second->clear(); } });
276 return (!handlers.count(
id) ||
static_cast<Handler<E> &
>(*handlers.at(
id)).empty());
285 return std::all_of(handlers.cbegin(), handlers.cend(), [](
auto &&hdlr) { return !hdlr.second || hdlr.second->empty(); });
289 std::unordered_map<std::uint32_t, std::unique_ptr<BaseHandler>> handlers{};
295# 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.