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