Skip to content

Commit 73cf4a8

Browse files
committed
Execution/EventDispatcher: subscribe: Multiple events
1 parent 6d4ee1b commit 73cf4a8

8 files changed

Lines changed: 67 additions & 11 deletions

File tree

modules/Execution/EventDispatcher.mpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,23 @@ export namespace CppUtils::Execution
3131
}
3232
}
3333

34-
template<String::Hasher eventName = Type::Hash{}>
34+
template<String::Hasher... eventNames>
3535
inline auto subscribe(auto&& function) -> void
36+
{
37+
if constexpr (sizeof...(eventNames) == 0)
38+
subscribe(Type::Hash{}, std::forward<decltype(function)>(function));
39+
else
40+
(subscribe(static_cast<Type::Hash>(eventNames), function), ...);
41+
}
42+
43+
inline auto subscribe(Type::Hash eventHash, auto&& function) -> void
3644
{
3745
using FunctionType = std::decay_t<decltype(function)>;
3846
using ArgumentsTypes = typename Type::CallableTrait<FunctionType>::ArgumentsTypes;
3947
[&]<class... Args>(std::tuple<Args...>*) {
4048
using Tuple = std::tuple<std::remove_cvref_t<Args>...>;
4149
auto lockGuard = std::unique_lock{m_mutex};
42-
auto key = std::make_pair(static_cast<Type::Hash>(eventName), std::type_index{typeid(Tuple)});
50+
auto key = std::make_pair(eventHash, std::type_index{typeid(Tuple)});
4351
m_subscribers[key].emplace_back(
4452
[function = std::forward<decltype(function)>(function)](const void* payload) mutable -> void {
4553
const auto& args = *static_cast<const Tuple*>(payload);

modules/Execution/EventQueue.mpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ export namespace CppUtils::Execution
4646
enqueue(std::move(task));
4747
}
4848

49-
template<String::Hasher eventName = Type::Hash{}>
49+
template<String::Hasher... eventNames>
5050
inline auto subscribe(auto&& function) -> void
5151
{
52-
m_dispatcher.subscribe<eventName>(std::forward<decltype(function)>(function));
52+
m_dispatcher.subscribe<eventNames...>(std::forward<decltype(function)>(function));
5353
}
5454

5555
template<Chrono::Duration Duration = std::chrono::milliseconds>

modules/Log/Logger.mpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ export namespace CppUtils
5454
emit<logType>(std::format(fmt, std::forward<Args>(args)...));
5555
}
5656

57-
template<String::Hasher logType = Type::Hash{}>
57+
template<String::Hasher... logTypes>
5858
static inline auto subscribe(auto&& function) -> void
5959
{
60-
eventQueue().template subscribe<logType>(std::forward<decltype(function)>(function));
60+
eventQueue().template subscribe<logTypes...>(std::forward<decltype(function)>(function));
6161
}
6262

6363
template<Chrono::Duration Duration = std::chrono::milliseconds>

modules/Thread/AsyncEventDispatcher.mpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ export namespace CppUtils::Thread
3333
});
3434
}
3535

36-
template<String::Hasher eventName = Type::Hash{}>
36+
template<String::Hasher... eventNames>
3737
inline auto subscribe(auto&& function) -> void
3838
{
39-
m_eventDispatcher.subscribe<eventName>(std::forward<decltype(function)>(function));
39+
m_eventDispatcher.subscribe<eventNames...>(std::forward<decltype(function)>(function));
4040
}
4141

4242
inline auto waitUntilFinished() -> void

modules/Thread/ScheduledEventDispatcher.mpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ export namespace CppUtils::Thread
4646
m_scheduler{step, numberThreads, std::move(onError), std::move(finally)}
4747
{}
4848

49-
template<String::Hasher eventName = Type::Hash{}>
49+
template<String::Hasher... eventNames>
5050
inline auto subscribe(auto&& function) -> void
5151
{
52-
m_eventDispatcher.subscribe<eventName>(std::forward<decltype(function)>(function));
52+
m_eventDispatcher.subscribe<eventNames...>(std::forward<decltype(function)>(function));
5353
}
5454

5555
template<String::Hasher eventName = Type::Hash{}, class... Args, Chrono::Duration Delay = std::chrono::milliseconds>

tests/Execution/EventDispatcher.mpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,29 @@ namespace CppUtils::UnitTest::Execution::EventDispatcher
117117
auto eventDispatcher = CppUtils::Execution::EventDispatcher{};
118118

119119
eventDispatcher.subscribe<"Count">([count = 0, &suite](int expected) mutable {
120-
count++;
120+
++count;
121121
suite.expectEqual(count, expected);
122122
});
123123

124124
eventDispatcher.emit<"Count">(1);
125125
eventDispatcher.emit<"Count">(2);
126126
eventDispatcher.emit<"Count">(3);
127127
});
128+
129+
suite.addTest("Multiple subscribe", [&] {
130+
auto eventDispatcher = CppUtils::Execution::EventDispatcher{};
131+
auto count = std::atomic_size_t{0};
132+
133+
eventDispatcher.subscribe<"A", "B", "C">([&count] {
134+
++count;
135+
});
136+
137+
eventDispatcher.emit<"A">();
138+
eventDispatcher.emit<"B">();
139+
eventDispatcher.emit<"C">();
140+
eventDispatcher.emit<"D">();
141+
142+
suite.expectEqual(count, 3uz);
143+
});
128144
}};
129145
}

tests/Execution/EventQueue.mpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,21 @@ namespace CppUtils::UnitTest::Execution
2323
suite.expect(received);
2424
suite.expectEqual(valueReceived, 42);
2525
});
26+
27+
suite.addTest("Multiple subscribe", [&] {
28+
auto queue = CppUtils::Execution::EventQueue{};
29+
auto count = 0uz;
30+
31+
queue.subscribe<"A", "B">([&count] {
32+
++count;
33+
});
34+
35+
queue.emit<"A">();
36+
queue.emit<"B">();
37+
queue.emit<"C">();
38+
39+
queue.waitUntilFinished();
40+
suite.expectEqual(count, 2uz);
41+
});
2642
}};
2743
}

tests/Thread/AsyncEventDispatcher.mpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,21 @@ namespace CppUtils::UnitTest::Thread::AsyncEventDispatcher
6969
dispatcher.waitUntilFinished();
7070
suite.expectEqual(result.load(), 42);
7171
});
72+
73+
suite.addTest("Multiple subscribe", [&] {
74+
auto dispatcher = CppUtils::Thread::AsyncEventDispatcher{};
75+
auto count = std::atomic_size_t{0};
76+
77+
dispatcher.subscribe<"A", "B">([&count] {
78+
++count;
79+
});
80+
81+
dispatcher.emit<"A">();
82+
dispatcher.emit<"B">();
83+
dispatcher.emit<"C">();
84+
85+
dispatcher.waitUntilFinished();
86+
suite.expectEqual(count, 2uz);
87+
});
7288
}};
7389
}

0 commit comments

Comments
 (0)