LeviLamina
Loading...
Searching...
No Matches
EventBus.h
1#pragma once
2
3#include <concepts>
4#include <cstddef>
5#include <functional>
6#include <memory>
7#include <string_view>
8#include <type_traits>
9#include <utility>
10
11#include "ll/api/base/Concepts.h"
12#include "ll/api/base/Macro.h"
13#include "ll/api/coro/Generator.h"
14#include "ll/api/event/Event.h"
15#include "ll/api/event/EventId.h"
16#include "ll/api/event/Listener.h"
17#include "ll/api/event/ListenerBase.h"
18
19namespace ll::mod {
20class Mod;
21}
22namespace ll::event {
23class EmitterBase;
24
25class EventBus {
26 class EventBusImpl;
27 std::unique_ptr<EventBusImpl> impl;
28 EventBus();
29
30 void removeModListeners(std::string_view modName);
31
32 void clearMod(std::string_view modName);
33
34public:
35 using FactoryFn = std::function<std::unique_ptr<EmitterBase>()>;
36
37 LLNDAPI static EventBus& getInstance();
38
39 LLAPI void publish(Event&, EventIdView const&);
40
41 LLAPI void publish(std::string_view modName, Event&, EventIdView const&);
42
43 LLAPI bool
44 setEventEmitter(FactoryFn fn, EventIdView const& eventId, std::weak_ptr<mod::Mod> mod = mod::NativeMod::current());
45
46 template <std::derived_from<Event> T>
47 bool setEventEmitter(FactoryFn fn, std::weak_ptr<mod::Mod> mod = mod::NativeMod::current()) {
48 return setEventEmitter(std::move(fn), getEventId<T>, std::move(mod));
49 }
50
51 template <class T>
52 requires(std::derived_from<std::remove_cvref_t<T>, Event>)
53 void publish(T&& event) {
54 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can publish");
55 publish(event, getEventId<T>);
56 }
57
58 template <class T>
59 requires(std::derived_from<std::remove_cvref_t<T>, Event>)
60 void publish(std::string_view modName, T&& event) {
61 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can publish");
62 publish(modName, event, getEventId<T>);
63 }
64
65 LLNDAPI coro::Generator<EventIdView> events(std::string_view modName) const;
66
68
69 LLNDAPI bool hasEvent(EventIdView const& eventId) const;
70
71 LLNDAPI size_t getListenerCount(EventIdView const&);
72
73 template <std::derived_from<Event> T>
74 [[nodiscard]] size_t getListenerCount() {
75 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can be listen");
76 return getListenerCount(getEventId<T>);
77 }
78
79 LLAPI bool addListener(ListenerPtr const&, EventIdView const&);
80
81 template <class T, template <class...> class L, class... LT>
82 requires((std::derived_from<T, LT> || ...) && std::derived_from<L<LT...>, ListenerBase>)
83 bool addListener(std::shared_ptr<L<LT...>> const& listener) {
84 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can be listen");
85 return addListener(listener, getEventId<T>);
86 }
87 template <class T = void, template <class...> class L, class... LT>
88 requires(std::same_as<T, void> && std::derived_from<L<LT...>, ListenerBase>)
89 bool addListener(std::shared_ptr<L<LT...>> const& listener) {
90 return (addListener<LT>(listener) && ...);
91 }
92 template <std::derived_from<Event> T, std::derived_from<ListenerBase> L = Listener<T>, class... Args>
93 inline auto emplaceListener(Args&&... args) {
94 auto res = L::create(std::forward<Args>(args)...);
95 if (!addListener<T>(res)) {
96 res = nullptr;
97 }
98 return res;
99 }
100
101 LLAPI bool removeListener(ListenerPtr const&, EventIdView const&);
102
103 bool removeListener(ListenerPtr const& listener) { return removeListener(listener, EmptyEventId); }
104 template <std::derived_from<Event> T>
105 bool removeListener(ListenerPtr const& listener) {
106 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can be listen");
107 return removeListener(listener, getEventId<T>);
108 }
109
110 [[nodiscard]] bool hasListener(ListenerPtr const& listener) const {
111 return hasListener(listener->getId(), EmptyEventId);
112 }
113 template <std::derived_from<Event> T>
114 [[nodiscard]] bool hasListener(ListenerPtr const& listener) const {
115 return hasListener(listener->getId(), getEventId<T>);
116 }
117
118 LLNDAPI ListenerPtr getListener(ListenerId id) const;
119
120 bool removeListener(ListenerId id) {
121 if (auto listener = getListener(id); listener) {
122 return removeListener(listener, EmptyEventId);
123 }
124 return false;
125 }
126 template <std::derived_from<Event> T>
127 bool removeListener(ListenerId id) {
128 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can be listen");
129 if (auto listener = getListener(id); listener) {
130 return removeListener(listener, getEventId<T>);
131 }
132 return false;
133 }
134
135 LLNDAPI bool hasListener(ListenerId, EventIdView const&) const;
136
137 [[nodiscard]] bool hasListener(ListenerId id) const { return hasListener(id, EmptyEventId); }
138
139 template <std::derived_from<Event> T>
140 [[nodiscard]] bool hasListener(ListenerId id) const {
141 return hasListener(id, getEventId<T>);
142 }
143};
144
145} // namespace ll::event
Definition EventBus.h:25
Definition EventId.h:17
Definition Event.h:14
Definition ListenerBase.h:24
Definition Generator.h:13