34#ifndef QB_EVENT_ROUTER_H
35#define QB_EVENT_ROUTER_H
59 EventPolicy() =
default;
61 ~EventPolicy() =
default;
75 template <
typename _Handler,
typename _Event>
78 if constexpr (has_member_func_is_alive<_Event>::value) {
79 if (handler.is_alive())
94 template <
typename _Event>
97 if constexpr (!std::is_trivially_destructible_v<_Event>) {
98 if constexpr (has_member_func_is_alive<_Event>::value) {
99 if (!
event.is_alive())
117template <
typename _RawEvent,
typename _Handler>
119 using _EventId =
typename _RawEvent::id_type;
120 using _HandlerId =
typename _RawEvent::id_handler_type;
132 explicit sesh(_Handler &handler) noexcept
133 : _handler(handler) {}
141 template <
bool _CleanEvent = true>
145 if constexpr (_CleanEvent)
158template <
typename _RawEvent,
typename _Handler =
void>
160 using _EventId =
typename _RawEvent::id_type;
161 using _HandlerId =
typename _RawEvent::id_handler_type;
179 template <
bool _CleanEvent = true>
182 if constexpr (has_member_func_is_broadcast<_HandlerId>::value) {
183 if (
event.getDestination().is_broadcast()) {
184 for (
auto &it : _subscribed_handlers)
187 if constexpr (_CleanEvent)
194 const auto &it = _subscribed_handlers.find(
event.dest);
195 if (
likely(it != _subscribed_handlers.cend()))
198 if constexpr (_CleanEvent)
209 _subscribed_handlers.erase(handler.id());
210 _subscribed_handlers.insert({handler.id(), handler});
220 _subscribed_handlers.erase(
id);
231template <
typename _RawEvent>
233 using _EventId =
typename _RawEvent::id_type;
234 using _HandlerId =
typename _RawEvent::id_handler_type;
242 class IHandlerResolver {
244 virtual ~IHandlerResolver() =
default;
251 virtual void resolve(_RawEvent &
event) = 0;
259 template <
typename _Handler>
260 class HandlerResolver
261 :
public IHandlerResolver
262 ,
public sesh<_RawEvent, _Handler> {
264 HandlerResolver() =
delete;
265 ~HandlerResolver() =
default;
272 explicit HandlerResolver(_Handler &handler) noexcept
281 resolve(_RawEvent &
event)
final {
295 for (
const auto &it : _subscribed_handlers)
308 template <
bool _CleanEvent = false>
311 if constexpr (has_member_func_is_broadcast<_HandlerId>::value) {
312 if (
event.getDestination().is_broadcast()) {
313 for (
const auto &it : _subscribed_handlers)
314 it.second.resolve(
event);
316 if constexpr (_CleanEvent)
323 const auto &it = _subscribed_handlers.find(
event.getDestination());
324 if (
likely(it != _subscribed_handlers.cend()))
325 it->second.resolve(
event);
327 if constexpr (_CleanEvent)
339 template <
typename _Handler>
342 const auto &it = _subscribed_handlers.find(handler.id());
343 if (it != _subscribed_handlers.cend()) {
345 _subscribed_handlers.erase(it);
347 _subscribed_handlers.insert(
348 {handler.id(), *
new HandlerResolver<_Handler>(handler)});
358 const auto &it = _subscribed_handlers.find(
id);
359 if (it != _subscribed_handlers.end()) {
361 _subscribed_handlers.erase(it);
375template <
typename _RawEvent,
typename _Handler,
bool _CleanEvent = true>
378 using _EventId =
typename _RawEvent::id_type;
379 using _HandlerId =
typename _RawEvent::id_handler_type;
388 class IEventResolver {
390 virtual ~IEventResolver() =
default;
398 virtual void resolve(_Handler &handler, _RawEvent &
event)
const = 0;
406 template <
typename _Event>
408 :
public IEventResolver
411 EventResolver() =
default;
420 resolve(_Handler &handler, _RawEvent &
event)
const final {
421 auto &revent =
reinterpret_cast<_Event &
>(
event);
423 if constexpr (_CleanEvent)
439 explicit mesh(_Handler &handler) noexcept
440 : _handler(handler) {}
465 _registered_events.at(
event.getID()).resolve(_handler,
event);
475 template <
typename _Event>
479 _registered_events.find(_RawEvent::template type_to_id<_Event>());
480 if (it == _registered_events.cend()) {
481 _registered_events.insert(
482 {_RawEvent::template type_to_id<_Event>(), *
new EventResolver<_Event>});
493 template <
typename _Event>
497 _registered_events.find(_RawEvent::template type_to_id<_Event>());
498 if (it != _registered_events.cend()) {
500 _registered_events.erase(it);
511 for (
const auto &it : _registered_events)
513 _registered_events.clear();
526template <
typename _RawEvent,
bool _CleanEvent = true,
typename _Handler =
void>
529 using _EventId =
typename _RawEvent::id_type;
530 using _HandlerId =
typename _RawEvent::id_handler_type;
538 class IEventResolver {
540 virtual ~IEventResolver() =
default;
547 virtual void resolve(_RawEvent &
event) = 0;
554 virtual void unsubscribe(_HandlerId
const &
id) = 0;
562 template <
typename _Event>
564 :
public IEventResolver
565 ,
public semh<_Event, _Handler> {
566 using _HandlerId =
typename _RawEvent::id_handler_type;
572 EventResolver() noexcept
581 resolve(_RawEvent &
event)
final {
582 auto &revent =
reinterpret_cast<_Event &
>(
event);
606 for (
const auto &it : _registered_events)
617 template <
typename _Func>
620 const auto &it = _registered_events.find(
event.getID());
621 if (
likely(it != _registered_events.cend()))
622 it->second.resolve(
event);
638 template <
typename _Event>
642 _registered_events.find(_RawEvent::template type_to_id<_Event>());
643 if (it == _registered_events.cend()) {
644 auto &resolver = *
new EventResolver<_Event>;
645 resolver.subscribe(handler);
646 _registered_events.insert(
647 {_RawEvent::template type_to_id<_Event>(), resolver});
649 dynamic_cast<EventResolver<_Event> &
>(it->second).
subscribe(handler);
659 template <
typename _Event>
663 _registered_events.find(_RawEvent::template type_to_id<_Event>());
664 if (it != _registered_events.cend())
665 it->second.unsubscribe(handler.id());
685 for (
auto const &it : _registered_events) {
686 it.second.unsubscribe(
id);
699template <
typename _RawEvent,
bool _CleanEvent>
700class memh<_RawEvent, _CleanEvent, void> {
702 using _EventId =
typename _RawEvent::id_type;
703 using _HandlerId =
typename _RawEvent::id_handler_type;
713 virtual ~IDisposer() =
default;
720 virtual void dispose(_RawEvent *
event) = 0;
728 template <
typename T>
729 class Disposer :
public IDisposer {
739 dispose(_RawEvent *
event)
final {
740 if constexpr (!std::is_trivially_destructible_v<T>) {
741 reinterpret_cast<T *
>(
event)->~T();
749 static inline std::mutex _disposers_mtx;
756 class IEventResolver {
758 virtual ~IEventResolver() =
default;
765 virtual void resolve(_RawEvent &
event)
const = 0;
772 virtual void unsubscribe(_HandlerId
const &
id) = 0;
780 template <
typename _Event>
782 :
public IEventResolver
783 ,
public semh<_Event> {
788 EventResolver() noexcept
797 resolve(_RawEvent &
event)
const final {
798 auto &revent =
reinterpret_cast<_Event &
>(
event);
808 unsubscribe(
typename _RawEvent::id_handler_type
const &
id)
final {
823 template <
typename T>
829 std::lock_guard lk(_disposers_mtx);
831 _disposers.try_emplace(_RawEvent::template type_to_id<T>(),
844 for (
const auto &it : _registered_events)
855 template <
typename _Func>
858 const auto &it = _registered_events.find(
event.getID());
859 if (
likely(it != _registered_events.cend()))
860 it->second.resolve(
event);
863 if constexpr (_CleanEvent) {
864 std::lock_guard lk(_disposers_mtx);
865 _disposers.at(
event.getID())->dispose(&
event);
877 template <
typename _Event,
typename _Handler>
883 _registered_events.find(_RawEvent::template type_to_id<_Event>());
884 if (it == _registered_events.cend()) {
885 auto &resolver = *
new EventResolver<_Event>;
886 resolver.subscribe(handler);
887 _registered_events.insert(
888 {_RawEvent::template type_to_id<_Event>(), resolver});
890 dynamic_cast<EventResolver<_Event> *
>(&(it->second))->
subscribe(handler);
901 template <
typename _Event,
typename _Handler>
905 _registered_events.find(_RawEvent::template type_to_id<_Event>());
906 if (it != _registered_events.cend())
907 it->second.unsubscribe(handler.id());
916 template <
typename _Handler>
929 for (
auto const &it : _registered_events) {
930 it.second.unsubscribe(
id);
Branch prediction hint utilities for performance optimization.
Base policy for event handling.
Definition router.h:57
void invoke(_Handler &handler, _Event &event) const
Invoke a handler with an event.
Definition router.h:77
void dispose(_Event &event) const noexcept
Dispose of an event if necessary.
Definition router.h:96
void unsubscribe(_HandlerId const &id) const
Unsubscribe a handler by ID from all event types.
Definition router.h:928
void unsubscribe(_Handler const &handler) const
Unsubscribe a handler from all event types.
Definition router.h:918
void route(_RawEvent &event, _Func const &onError) const
Routes an event to the appropriate handlers with error handling.
Definition router.h:857
void unsubscribe(_Handler const &handler) const
Unsubscribe a handler from events of a specific type.
Definition router.h:903
~memh() noexcept
Destructor that cleans up all event resolvers.
Definition router.h:843
void subscribe(_Handler &handler)
Subscribe a handler to events of a specific type.
Definition router.h:879
Multiple-Event Multiple-Handler router (generic version)
Definition router.h:527
void unsubscribe(_Handler &handler) const
Unsubscribe a handler from events of a specific type.
Definition router.h:661
void unsubscribe(_HandlerId const &id) const
Unsubscribe a handler by ID from all event types.
Definition router.h:684
~memh() noexcept
Destructor that cleans up all event resolvers.
Definition router.h:605
void subscribe(_Handler &handler)
Subscribe a handler to events of a specific type.
Definition router.h:640
void route(_RawEvent &event, _Func const &onError) const
Routes an event to the appropriate handlers with error handling.
Definition router.h:619
void unsubscribe(_Handler const &handler) const
Unsubscribe a handler from all event types.
Definition router.h:674
void unsubscribe()
Unsubscribe from all event types.
Definition router.h:510
void route(_RawEvent &event)
Routes an event to the handler.
Definition router.h:457
void subscribe()
Subscribe to events of a specific type.
Definition router.h:477
mesh(_Handler &handler) noexcept
Constructs a MESH router with the given handler.
Definition router.h:439
~mesh() noexcept
Destructor that cleans up all event resolvers.
Definition router.h:445
void unsubscribe()
Unsubscribe from events of a specific type.
Definition router.h:495
~semh() noexcept
Destructor that cleans up all handler resolvers.
Definition router.h:294
void subscribe(_Handler &handler) noexcept
Subscribe a handler to receive events.
Definition router.h:341
void unsubscribe(_HandlerId const &id) noexcept
Unsubscribe a handler by ID.
Definition router.h:357
void route(_RawEvent &event) const noexcept
Routes an event to the appropriate handler.
Definition router.h:310
Single-Event Multiple-Handler router (generic version)
Definition router.h:159
void route(_RawEvent &event) noexcept
Routes an event to the appropriate handler.
Definition router.h:181
void unsubscribe(_HandlerId const &id) noexcept
Unsubscribe a handler by ID.
Definition router.h:219
void subscribe(_Handler &handler) noexcept
Subscribe a handler to receive events.
Definition router.h:208
Single-Event Single-Handler router.
Definition router.h:118
sesh(_Handler &handler) noexcept
Constructs a SESH router with the given handler.
Definition router.h:132
void route(_RawEvent &event)
Routes an event to the handler.
Definition router.h:143
std::unordered_map< K, V, H, E, A > unordered_map
The primary unordered map implementation.
Definition unordered_map.h:90
Event event
Alias for the base Event class.
Definition Event.h:385
bool likely(bool expr)
Hint for branch prediction when a condition is expected to be true.
Definition branch_hints.h:49
Helper to ensure safe disposal of events.
Definition router.h:824
SafeDispose()
Constructor that registers a disposer.
Definition router.h:828
Advanced type traits and metaprogramming utilities for the QB Framework.
Optimized unordered map implementations.