7 #include <shared_mutex>
10 #include <unordered_map>
13 #include "detail/function_traits.hpp"
26 const void* handle_{
nullptr};
39 [[nodiscard]]
const void*
handle()
const;
66 template <
typename EventType,
typename EventHandler,
67 typename = std::enable_if_t<std::is_invocable_v<EventHandler> ||
68 std::is_invocable_v<EventHandler, EventType>>>
70 using traits = detail::function_traits<EventHandler>;
71 const auto type_idx = std::type_index(
typeid(EventType));
74 if constexpr (traits::arity == 0) {
75 safe_unique_registrations_access([&]() {
76 auto it = handler_registrations_.emplace(
78 [handler = std::forward<EventHandler>(handler)](
auto) { handler(); });
80 handle =
static_cast<const void*
>(&(it->second));
83 safe_unique_registrations_access([&]() {
84 auto it = handler_registrations_.emplace(
85 type_idx, [func = std::forward<EventHandler>(handler)](
auto value) {
86 func(std::any_cast<EventType>(value));
89 handle =
static_cast<const void*
>(&(it->second));
104 template <
typename EventType,
typename ClassType,
typename MemberFunction>
106 MemberFunction&&
function) noexcept {
107 using traits = detail::function_traits<MemberFunction>;
108 static_assert(std::is_same_v<ClassType, std::decay_t<typename traits::owner_type>>,
109 "Member function pointer must match instance type.");
111 const auto type_idx = std::type_index(
typeid(EventType));
114 if constexpr (traits::arity == 0) {
115 safe_unique_registrations_access([&]() {
116 auto it = handler_registrations_.emplace(
118 [class_instance,
function](
auto) { (class_instance->*
function)(); });
120 handle =
static_cast<const void*
>(&(it->second));
123 safe_unique_registrations_access([&]() {
124 auto it = handler_registrations_.emplace(
125 type_idx, [class_instance,
function](
auto value) {
126 (class_instance->*
function)(std::any_cast<EventType>(value));
129 handle =
static_cast<const void*
>(&(it->second));
140 template <
typename EventType,
typename = std::enable_if_t<!std::is_po
inter_v<EventType>>>
142 safe_shared_registrations_access([
this, local_event = std::forward<EventType>(evt)]() {
144 for (
auto [begin_evt_id, end_evt_id] =
145 handler_registrations_.equal_range(std::type_index(
typeid(EventType)));
146 begin_evt_id != end_evt_id; ++begin_evt_id) {
147 begin_evt_id->second(local_event);
158 if (!registration.handle()) {
163 safe_unique_registrations_access([
this, &result, ®istration]() {
164 for (
auto it = handler_registrations_.begin(); it != handler_registrations_.end();
166 if (static_cast<const void*>(&(it->second)) == registration.handle()) {
167 handler_registrations_.erase(it);
180 safe_unique_registrations_access([
this]() { handler_registrations_.clear(); });
189 safe_shared_registrations_access(
190 [
this, &count]() { count = handler_registrations_.size(); });
195 using mutex_type = std::shared_mutex;
196 mutable mutex_type registration_mutex_;
197 std::unordered_multimap<std::type_index, std::function<void(std::any)>>
198 handler_registrations_;
200 template <
typename Callable>
201 void safe_shared_registrations_access(Callable&& callable) {
203 std::shared_lock<mutex_type> lock(registration_mutex_);
205 }
catch (std::system_error&) {
208 template <
typename Callable>
209 void safe_unique_registrations_access(Callable&& callable) {
212 std::unique_lock<mutex_type> lock(registration_mutex_);
214 }
catch (std::system_error&) {
223 if (event_bus_ && handle_) {
230 : handle_(handle), event_bus_(bus) {}
233 : handle_(std::exchange(other.handle_,
nullptr)),
234 event_bus_(std::exchange(other.event_bus_,
nullptr)) {}
238 handle_ = std::exchange(other.handle_,
nullptr);
239 event_bus_ = std::exchange(other.event_bus_,
nullptr);
A central event handler class that connects event handlers with the events.
Definition: event_bus.hpp:54
void fire_event(EventType &&evt) noexcept
Fire an event to notify event handlers.
Definition: event_bus.hpp:141
void remove_handlers() noexcept
Remove all handlers from event bus.
Definition: event_bus.hpp:179
handler_registration register_handler(EventHandler &&handler)
Register an event handler for a given event type.
Definition: event_bus.hpp:69
bool remove_handler(const handler_registration ®istration) noexcept
Remove a given handler from the event bus.
Definition: event_bus.hpp:157
std::size_t handler_count() noexcept
Get the number of handlers registered with the event bus.
Definition: event_bus.hpp:187
handler_registration register_handler(ClassType *class_instance, MemberFunction &&function) noexcept
Register an event handler for a given event type.
Definition: event_bus.hpp:105
A registration handle for a particular handler of an event type.
Definition: event_bus.hpp:25
const void * handle() const
Pointer to the underlying handle.
Definition: event_bus.hpp:220
handler_registration(const handler_registration &other)=delete
~handler_registration()
Definition: event_bus.hpp:243
handler_registration & operator=(const handler_registration &other)=delete
void unregister() noexcept
Unregister this handler from the event bus.
Definition: event_bus.hpp:222
Definition: event_bus.hpp:15