12USERVER_NAMESPACE_BEGIN
17enum class UnsubscribingKind;
19template <
typename... Args>
20class AsyncEventSource;
24class AsyncEventSourceBase {
26 virtual void RemoveListener(FunctionId, UnsubscribingKind)
noexcept = 0;
30 ~AsyncEventSourceBase();
37class FunctionId
final {
39 constexpr FunctionId() =
default;
41 template <
typename Class>
42 explicit FunctionId(Class* obj) : FunctionId(obj,
typeid(Class)) {}
44 explicit operator
bool()
const;
46 bool operator==(
const FunctionId& other)
const;
49 std::size_t operator()(FunctionId id)
const noexcept;
53 FunctionId(
void* ptr,
const std::type_info& type);
56 const std::type_info* type_{
nullptr};
59enum class UnsubscribingKind { kManual, kAutomatic };
68class [[nodiscard]] AsyncEventSubscriberScope
final {
70 AsyncEventSubscriberScope() =
default;
72 template <
typename... Args>
73 AsyncEventSubscriberScope(AsyncEventSource<Args...>& channel, FunctionId id)
74 : AsyncEventSubscriberScope(
75 static_cast<impl::AsyncEventSourceBase&>(channel), id) {}
77 AsyncEventSubscriberScope(AsyncEventSubscriberScope&& scope)
noexcept;
79 AsyncEventSubscriberScope& operator=(
80 AsyncEventSubscriberScope&& other)
noexcept;
82 ~AsyncEventSubscriberScope();
89 AsyncEventSubscriberScope(impl::AsyncEventSourceBase& channel, FunctionId id);
91 impl::AsyncEventSourceBase* channel_{
nullptr};
101template <
typename... Args>
102class AsyncEventSource :
public impl::AsyncEventSourceBase {
104 using Function = std::function<
void(Args... args)>;
106 virtual ~AsyncEventSource() =
default;
128 template <
class Class>
129 AsyncEventSubscriberScope
AddListener(Class* obj, std::string_view name,
130 void (Class::*func)(Args...)) {
131 return AddListener(FunctionId(obj), name,
132 [obj, func](Args... args) { (obj->*func)(args...); });
140 AsyncEventSubscriberScope
AddListener(FunctionId id, std::string_view name,
142 return DoAddListener(id, name, std::move(func));
149 virtual AsyncEventSubscriberScope DoAddListener(FunctionId id,
150 std::string_view name,
151 Function&& func) = 0;