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 detail::registerRuntimeEventId<T>();
49 return setEventEmitter(std::move(fn), getEventId<T>, std::move(mod));
50 }
51
52 template <class T>
53 requires(std::derived_from<std::remove_cvref_t<T>, Event>)
54 void publish(T&& event) {
55 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can publish");
56 publish(event, getEventId<T>);
57 }
58
59 template <class T>
60 requires(std::derived_from<std::remove_cvref_t<T>, Event>)
61 void publish(std::string_view modName, T&& event) {
62 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can publish");
63 publish(modName, event, getEventId<T>);
64 }
65
66 LLNDAPI coro::Generator<EventIdView> events(std::string_view modName) const;
67
69
70 LLNDAPI bool hasEvent(EventIdView const& eventId) const;
71
72 LLNDAPI size_t getListenerCount(EventIdView const&);
73
74 template <std::derived_from<Event> T>
75 [[nodiscard]] size_t getListenerCount() {
76 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can be listen");
77 return getListenerCount(getEventId<T>);
78 }
79
80 LLAPI bool addListener(ListenerPtr const&, EventIdView const&);
81
82 template <class T, template <class...> class L, class... LT>
83 requires((std::derived_from<T, LT> || ...) && std::derived_from<L<LT...>, ListenerBase>)
84 bool addListener(std::shared_ptr<L<LT...>> const& listener) {
85 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can be listen");
86 return addListener(listener, getEventId<T>);
87 }
88 template <class T = void, template <class...> class L, class... LT>
89 requires(std::same_as<T, void> && std::derived_from<L<LT...>, ListenerBase>)
90 bool addListener(std::shared_ptr<L<LT...>> const& listener) {
91 return (addListener<LT>(listener) && ...);
92 }
93 template <std::derived_from<Event> T, std::derived_from<ListenerBase> L = Listener<T>, class... Args>
94 inline auto emplaceListener(Args&&... args) {
95 auto res = L::create(std::forward<Args>(args)...);
96 if (!addListener<T>(res)) {
97 res = nullptr;
98 }
99 return res;
100 }
101
102 LLAPI bool removeListener(ListenerPtr const&, EventIdView const&);
103
104 bool removeListener(ListenerPtr const& listener) { return removeListener(listener, EmptyEventId); }
105 template <std::derived_from<Event> T>
106 bool removeListener(ListenerPtr const& listener) {
107 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can be listen");
108 return removeListener(listener, getEventId<T>);
109 }
110
111 [[nodiscard]] bool hasListener(ListenerPtr const& listener) const {
112 return hasListener(listener->getId(), EmptyEventId);
113 }
114 template <std::derived_from<Event> T>
115 [[nodiscard]] bool hasListener(ListenerPtr const& listener) const {
116 return hasListener(listener->getId(), getEventId<T>);
117 }
118
119 LLNDAPI ListenerPtr getListener(ListenerId id) const;
120
121 bool removeListener(ListenerId id) {
122 if (auto listener = getListener(id); listener) {
123 return removeListener(listener, EmptyEventId);
124 }
125 return false;
126 }
127 template <std::derived_from<Event> T>
128 bool removeListener(ListenerId id) {
129 static_assert(std::is_final_v<std::remove_cvref_t<T>>, "Only final classes can be listen");
130 if (auto listener = getListener(id); listener) {
131 return removeListener(listener, getEventId<T>);
132 }
133 return false;
134 }
135
136 LLNDAPI bool hasListener(ListenerId, EventIdView const&) const;
137
138 [[nodiscard]] bool hasListener(ListenerId id) const { return hasListener(id, EmptyEventId); }
139
140 template <std::derived_from<Event> T>
141 [[nodiscard]] bool hasListener(ListenerId id) const {
142 return hasListener(id, getEventId<T>);
143 }
144};
145
146} // namespace ll::event
Definition EmitterBase.h:4
Definition EventId.h:17
Definition Event.h:17
Definition ListenerBase.h:24
Definition Mod.h:17
Definition Generator.h:69