Allow creation of a message_router with no message types

This commit is contained in:
John Wellbelove 2026-01-28 17:45:29 +00:00
parent fed1274324
commit a4ee9d01aa
2 changed files with 206 additions and 4 deletions

View File

@ -418,18 +418,28 @@ namespace etl
message_router()
: imessage_router(etl::imessage_router::MESSAGE_ROUTER)
{
// CRTP validation: Derived must inherit from this exact specialization.
ETL_STATIC_ASSERT((etl::is_base_of<etl::message_router<TDerived, TMessageTypes...>, TDerived>::value),
"Mismatch in derived type: TDerived does not inherit from etl::message_router<TDerived, TMessageTypes...>");
}
//**********************************************
message_router(etl::imessage_router& successor_)
: imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_)
{
// CRTP validation: Derived must inherit from this exact specialization.
ETL_STATIC_ASSERT((etl::is_base_of<etl::message_router<TDerived, TMessageTypes...>, TDerived>::value),
"Mismatch in derived type: TDerived does not inherit from etl::message_router<TDerived, TMessageTypes...>");
}
//**********************************************
message_router(etl::message_router_id_t id_)
: imessage_router(id_)
{
// CRTP validation: Derived must inherit from this exact specialization.
ETL_STATIC_ASSERT((etl::is_base_of<etl::message_router<TDerived, TMessageTypes...>, TDerived>::value),
"Mismatch in derived type: TDerived does not inherit from etl::message_router<TDerived, TMessageTypes...>");
ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));
}
@ -437,6 +447,10 @@ namespace etl
message_router(etl::message_router_id_t id_, etl::imessage_router& successor_)
: imessage_router(id_, successor_)
{
// CRTP validation: Derived must inherit from this exact specialization.
ETL_STATIC_ASSERT((etl::is_base_of<etl::message_router<TDerived, TMessageTypes...>, TDerived>::value),
"Mismatch in derived type: TDerived does not inherit from etl::message_router<TDerived, TMessageTypes...>");
ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));
}
@ -551,6 +565,106 @@ namespace etl
}
};
//***************************************************************************
// The definition for all message types.
//***************************************************************************
template <typename TDerived>
class message_router<TDerived> : public imessage_router
{
public:
using message_packet = etl::message_packet<>;
using message_types = etl::type_list<>;
//**********************************************
message_router()
: imessage_router(etl::imessage_router::MESSAGE_ROUTER)
{
// CRTP validation: Derived must inherit from this exact specialization.
ETL_STATIC_ASSERT((etl::is_base_of<etl::message_router<TDerived>, TDerived>::value),
"Mismatch in derived type: TDerived does not inherit from etl::message_router<TDerived>");
}
//**********************************************
message_router(etl::imessage_router& successor_)
: imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_)
{
// CRTP validation: Derived must inherit from this exact specialization.
ETL_STATIC_ASSERT((etl::is_base_of<etl::message_router<TDerived>, TDerived>::value),
"Mismatch in derived type: TDerived does not inherit from etl::message_router<TDerived>");
}
//**********************************************
message_router(etl::message_router_id_t id_)
: imessage_router(id_)
{
// CRTP validation: Derived must inherit from this exact specialization.
ETL_STATIC_ASSERT((etl::is_base_of<etl::message_router<TDerived>, TDerived>::value),
"Mismatch in derived type: TDerived does not inherit from etl::message_router<TDerived>");
ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));
}
//**********************************************
message_router(etl::message_router_id_t id_, etl::imessage_router& successor_)
: imessage_router(id_, successor_)
{
// CRTP validation: Derived must inherit from this exact specialization.
ETL_STATIC_ASSERT((etl::is_base_of<etl::message_router<TDerived>, TDerived>::value),
"Mismatch in derived type: TDerived does not inherit from etl::message_router<TDerived>");
ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));
}
//**********************************************
using etl::imessage_router::receive;
void receive(const etl::imessage& msg) ETL_OVERRIDE
{
if (has_successor())
{
get_successor().receive(msg);
}
}
template <typename TMessage, typename etl::enable_if<etl::is_base_of<imessage, TMessage>::value, int>::type = 0>
void receive(const TMessage& msg)
{
#include "etl/private/diagnostic_array_bounds_push.h"
if (has_successor())
{
get_successor().receive(msg);
}
#include "etl/private/diagnostic_pop.h"
}
//**********************************************
using imessage_router::accepts;
bool accepts(etl::message_id_t id) const ETL_OVERRIDE
{
return false;
}
//********************************************
ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE
{
return false;
}
//********************************************
bool is_producer() const ETL_OVERRIDE
{
return true;
}
//********************************************
bool is_consumer() const ETL_OVERRIDE
{
return true;
}
};
//***************************************************************************
/// Helper to turn etl::type_list<TTypes...> into etl::tuple<TTypes...>
template <typename TDerived, typename TList>

View File

@ -49,6 +49,7 @@ namespace
enum
{
ROUTER0,
ROUTER1,
ROUTER2,
ROUTER3
@ -119,17 +120,26 @@ namespace
Message5 message5;
//***************************************************************************
// Router that handles no messages.
//***************************************************************************
class Router0 : public etl::message_router<Router0>
{
public:
Router0()
: message_router(ROUTER0)
{
}
};
//***************************************************************************
// Router that handles messages 1, 2, 3, 4 and 5 and returns nothing.
// Created from a type list.
//***************************************************************************
#if ETL_USING_CPP17 && !defined(ETL_MESSAGE_ROUTER_FORCE_CPP03_IMPLEMENTATION)
using Router1Messages = etl::type_list<Message1, Message2, Message3, Message4, Message5>;
class Router1 : public etl::message_router_from_type_list_t<Router1, Router1Messages>
#else
class Router1 : public etl::message_router<Router1, Message1, Message2, Message3, Message4, Message5>
#endif
{
public:
@ -384,6 +394,84 @@ namespace
CHECK_EQUAL(4, r2.callback_count);
}
//*************************************************************************
TEST(message_router_with_no_message_types)
{
Router0 r0;
Router1 r1;
Router2 r2;
Message1 message1(r2);
Message2 message2(r2);
Message3 message3(r2);
Message4 message4(r2);
r0.append_successor(r1); // All messages are passed to r1.
CHECK_TRUE((etl::is_same<Router0::message_types, etl::type_list<>>::value));
CHECK(!r0.is_null_router());
CHECK(r0.is_producer());
CHECK(r0.is_consumer());
r1.receive(message1);
CHECK_EQUAL(1, r1.message1_count);
CHECK_EQUAL(0, r1.message2_count);
CHECK_EQUAL(0, r1.message3_count);
CHECK_EQUAL(0, r1.message4_count);
CHECK_EQUAL(0, r1.message_unknown_count);
CHECK_EQUAL(1, r2.callback_count);
r1.receive(message2);
CHECK_EQUAL(1, r1.message1_count);
CHECK_EQUAL(1, r1.message2_count);
CHECK_EQUAL(0, r1.message3_count);
CHECK_EQUAL(0, r1.message4_count);
CHECK_EQUAL(0, r1.message_unknown_count);
CHECK_EQUAL(2, r2.callback_count);
r1.receive(message3);
CHECK_EQUAL(1, r1.message1_count);
CHECK_EQUAL(1, r1.message2_count);
CHECK_EQUAL(1, r1.message3_count);
CHECK_EQUAL(0, r1.message4_count);
CHECK_EQUAL(0, r1.message_unknown_count);
CHECK_EQUAL(3, r2.callback_count);
r1.receive(message4);
CHECK_EQUAL(1, r1.message1_count);
CHECK_EQUAL(1, r1.message2_count);
CHECK_EQUAL(1, r1.message3_count);
CHECK_EQUAL(1, r1.message4_count);
CHECK_EQUAL(0, r1.message_unknown_count);
CHECK_EQUAL(4, r2.callback_count);
//// Send from the null router.
//etl::send_message(r0, message1);
//CHECK_EQUAL(1, r2.message1_count);
//CHECK_EQUAL(0, r2.message2_count);
//CHECK_EQUAL(0, r2.message4_count);
//CHECK_EQUAL(0, r2.message_unknown_count);
//etl::send_message(r0, message2);
//CHECK_EQUAL(1, r2.message1_count);
//CHECK_EQUAL(1, r2.message2_count);
//CHECK_EQUAL(0, r2.message4_count);
//CHECK_EQUAL(0, r2.message_unknown_count);
//etl::send_message(r0, message3);
//CHECK_EQUAL(1, r2.message1_count);
//CHECK_EQUAL(1, r2.message2_count);
//CHECK_EQUAL(0, r2.message4_count);
//CHECK_EQUAL(1, r2.message_unknown_count);
//etl::send_message(r0, message4);
//CHECK_EQUAL(1, r2.message1_count);
//CHECK_EQUAL(1, r2.message2_count);
//CHECK_EQUAL(1, r2.message4_count);
//CHECK_EQUAL(1, r2.message_unknown_count);
}
//*************************************************************************
TEST(message_null_router)
{