Skip to content

Commit 253b163

Browse files
committed
🐛 Fix handler short-circuiting
The handler should call all the callbacks that match a message, not just the first that matches. This is consistent with the indexed_handler behaviour. NOTE: The order of calling the callbacks is not defined.
1 parent 3a04050 commit 253b163

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

include/msg/handler.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ struct handler : handler_interface<BaseMsg, ExtraCallbackArgs...> {
2121

2222
auto handle(BaseMsg const &msg,
2323
ExtraCallbackArgs... args) const -> bool final {
24-
bool const found_valid_callback = stdx::any_of(
25-
[&](auto &callback) { return callback.handle(msg, args...); },
24+
auto const found_valid_callback = stdx::apply(
25+
[&](auto &...cbs) -> bool {
26+
return (0u | ... | cbs.handle(msg, args...));
27+
},
2628
callbacks);
2729
if (!found_valid_callback) {
2830
CIB_ERROR("None of the registered callbacks claimed this message:");

test/msg/handler.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ TEST_CASE("log mismatch when no match", "[handler]") {
9393

9494
TEST_CASE("match and dispatch only one callback", "[handler]") {
9595
auto callback1 = msg::callback<"cb1", msg_defn>(
96-
id_match<0x80>, [&](msg::const_view<msg_defn>) { CHECK(false); });
96+
id_match<0x80>, [](msg::const_view<msg_defn>) { CHECK(false); });
9797
auto callback2 = msg::callback<"cb2", msg_defn>(
9898
id_match<0x44>, [](msg::const_view<msg_defn>) { dispatched = true; });
9999
auto const msg = std::array{0x4400ba11u, 0x0042d00du};
@@ -107,6 +107,25 @@ TEST_CASE("match and dispatch only one callback", "[handler]") {
107107
CHECK(dispatched);
108108
}
109109

110+
TEST_CASE("dispatch all callbacks that match", "[handler]") {
111+
int count{};
112+
113+
auto callback1 = msg::callback<"cb1", msg_defn>(
114+
id_match<0x80>, [](msg::const_view<msg_defn>) { CHECK(false); });
115+
auto callback2 = msg::callback<"cb2", msg_defn>(
116+
id_match<0x44>, [&](msg::const_view<msg_defn>) { ++count; });
117+
auto callback3 = msg::callback<"cb3", msg_defn>(
118+
id_match<0x44>, [&](msg::const_view<msg_defn>) { ++count; });
119+
auto const msg = std::array{0x4400ba11u, 0x0042d00du};
120+
121+
auto callbacks = stdx::make_tuple(callback1, callback2, callback3);
122+
static auto handler =
123+
msg::handler<decltype(callbacks), decltype(msg)>{callbacks};
124+
125+
CHECK(handler.handle(msg));
126+
CHECK(count == 2);
127+
}
128+
110129
namespace {
111130
template <typename T>
112131
using uint8_view =

0 commit comments

Comments
 (0)