1 #ifndef UVW_EMITTER_INCLUDE_H
2 #define UVW_EMITTER_INCLUDE_H
10 #include <unordered_map>
14 #include "type_info.hpp"
26 template<
typename U,
typename = std::enable_if_t<std::is_
integral_v<U>>>
28 : ec{
static_cast<int>(val)}
52 const char *
what() const noexcept;
61 const
char *
name() const noexcept;
73 explicit operator
bool() const noexcept;
89 virtual ~BaseHandler() noexcept =
default;
90 virtual bool empty()
const noexcept = 0;
91 virtual void clear() noexcept = 0;
95 struct Handler final: BaseHandler {
96 using Listener = std::function<void(E &, T &)>;
97 using Element = std::pair<bool, Listener>;
98 using ListenerList = std::list<Element>;
99 using Connection =
typename ListenerList::iterator;
101 bool empty()
const noexcept
override {
102 auto pred = [](
auto &&element){
return element.first; };
104 return std::all_of(onceL.cbegin(), onceL.cend(), pred) &&
105 std::all_of(onL.cbegin(), onL.cend(), pred);
108 void clear() noexcept
override {
110 auto func = [](
auto &&element){ element.first =
true; };
111 std::for_each(onceL.begin(), onceL.end(), func);
112 std::for_each(onL.begin(), onL.end(), func);
120 return onceL.emplace(onceL.cend(),
false, std::move(f));
124 return onL.emplace(onL.cend(),
false, std::move(f));
131 auto pred = [](
auto &&element){
return element.first; };
132 onceL.remove_if(pred);
137 void publish(E event, T &ref) {
138 ListenerList currentL;
139 onceL.swap(currentL);
141 auto func = [&event, &ref](
auto &&element) {
142 return element.first ? void() : element.second(event, ref);
147 std::for_each(onL.rbegin(), onL.rend(), func);
148 std::for_each(currentL.rbegin(), currentL.rend(), func);
152 onL.remove_if([](
auto &&element){
return element.first; });
156 bool publishing{
false};
157 ListenerList onceL{};
162 Handler<E> & handler() noexcept {
165 if(!handlers.count(
id)) {
166 handlers[id] = std::make_unique<Handler<E>>();
169 return static_cast<Handler<E>&
>(*handlers.at(
id));
174 void publish(E event) {
175 handler<E>().publish(std::move(event), *
static_cast<T*
>(
this));
180 using Listener =
typename Handler<E>::Listener;
191 template<
typename>
friend class Emitter;
197 Connection(
typename Handler<E>::Connection conn)
198 : Handler<E>::Connection{std::move(conn)}
206 static_assert(std::is_base_of_v<
Emitter<T>, T>);
226 return handler<E>().on(std::move(f));
246 return handler<E>().once(std::move(f));
255 handler<E>().erase(std::move(conn));
263 handler<E>().clear();
270 std::for_each(handlers.begin(), handlers.end(),
271 [](
auto &&hdlr){ if(hdlr.second) { hdlr.second->clear(); } });
283 return (!handlers.count(
id) ||
284 static_cast<Handler<E>&
>(*handlers.at(
id)).empty());
293 return std::all_of(handlers.cbegin(), handlers.cend(),
294 [](
auto &&hdlr){ return !hdlr.second || hdlr.second->empty(); });
298 std::unordered_map<std::uint32_t, std::unique_ptr<BaseHandler>> handlers{};
306 #include "emitter.cpp"
Event emitter base class.
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.
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 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 * name() const noexcept
Returns the error name for the given error code.
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.