12#include <userver/utils/impl/internal_tag.hpp>
14USERVER_NAMESPACE_BEGIN
19enum class UnsubscribingKind;
21template <
typename... Args>
22class AsyncEventSource;
26class AsyncEventSourceBase {
28 virtual void RemoveListener(FunctionId, UnsubscribingKind)
noexcept = 0;
32 ~AsyncEventSourceBase();
39class FunctionId
final {
41 constexpr FunctionId() =
default;
43 template <
typename Class>
44 explicit FunctionId(Class* obj)
45 : FunctionId(obj,
typeid(Class))
48 explicit operator
bool()
const;
50 bool operator==(
const FunctionId& other)
const;
53 std::size_t operator()(FunctionId id)
const noexcept;
57 FunctionId(
void* ptr,
const std::type_info& type);
60 const std::type_info* type_{
nullptr};
63enum class UnsubscribingKind { kManual, kAutomatic };
72class [[nodiscard]] AsyncEventSubscriberScope
final {
74 AsyncEventSubscriberScope() =
default;
76 AsyncEventSubscriberScope(AsyncEventSubscriberScope&& scope)
noexcept;
77 AsyncEventSubscriberScope& operator=(AsyncEventSubscriberScope&& other)
noexcept;
78 ~AsyncEventSubscriberScope();
86 template <
typename... Args>
87 AsyncEventSubscriberScope(utils::
impl::InternalTag, AsyncEventSource<Args...>& channel, FunctionId id)
88 : AsyncEventSubscriberScope(
static_cast<impl::AsyncEventSourceBase&>(channel), id)
93 AsyncEventSubscriberScope(impl::AsyncEventSourceBase& channel, FunctionId id);
95 impl::AsyncEventSourceBase* channel_{
nullptr};
105template <
typename... Args>
106class AsyncEventSource :
public impl::AsyncEventSourceBase {
108 using Function = std::function<
void(Args... args)>;
110 virtual ~AsyncEventSource() =
default;
132 template <
class Class>
133 AsyncEventSubscriberScope
AddListener(Class* obj, std::string_view name,
void (Class::*func)(Args...)) {
134 return AddListener(FunctionId(obj), name, [obj, func](Args... args) { (obj->*func)(args...); });
142 AsyncEventSubscriberScope
AddListener(FunctionId id, std::string_view name, Function&& func) {
143 return DoAddListener(id, name, std::move(func));
150 virtual AsyncEventSubscriberScope DoAddListener(FunctionId id, std::string_view name, Function&& func) = 0;