364 bool is_null_router() const ETL_OVERRIDE
370 bool is_producer() const ETL_OVERRIDE
376 bool is_consumer() const ETL_OVERRIDE
385 template <
typename T>
393 template <
typename TRouter,
typename TMessage>
394 static typename etl::enable_if< etl::is_message_router<TRouter>::value && etl::is_message<TMessage>::value,
void>
::type
395 send_message(TRouter& destination,
const TMessage&
message)
403 template <
typename TRouter>
404 static typename etl::enable_if<etl::is_message_router<TRouter>::value,
void>
::type send_message(TRouter& destination,
etl::shared_message message)
406 destination.receive(message);
412 template <
typename TRouter,
typename TMessage>
413 static typename etl::enable_if< etl::is_message_router<TRouter>::value && etl::is_message<TMessage>::value,
void>::type
414 send_message(TRouter& destination, etl::message_router_id_t
id,
const TMessage&
message)
416 destination.receive(
id,
message);
422 template <
typename TRouter>
423 static typename etl::enable_if<etl::is_message_router<TRouter>::value,
void>::type send_message(TRouter& destination, etl::message_router_id_t
id,
426 destination.receive(
id,
message);
432#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_ROUTER_FORCE_CPP03_IMPLEMENTATION)
436 template <
typename TDerived,
typename... TMessageTypes>
443 using typename private_message_router::traits<TMessageTypes...>::message_packet;
444 using typename private_message_router::traits<TMessageTypes...>::message_types;
445 using typename private_message_router::traits< TMessageTypes...>::sorted_message_types;
451 : imessage_router(etl::imessage_router::MESSAGE_ROUTER)
459 message_router(etl::imessage_router& successor_)
460 : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_)
467 message_router(etl::message_router_id_t id_)
468 : imessage_router(id_)
470 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));
476 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_)
477 : imessage_router(id_, successor_)
479 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));
485 using etl::imessage_router::receive;
493 void receive(
const etl::imessage& msg) ETL_OVERRIDE
507 dispatch(msg, index);
521 static_cast<TDerived*
>(
this)->on_receive_unknown(msg);
531 template <
typename TMessage,
typename etl::enable_if<etl::is_one_of<TMessage, TMessageTypes...>::value,
int>::type = 0>
532 void receive(
const TMessage& msg)
535 static_cast<TDerived*
>(
this)->on_receive(msg);
545 template <
typename TMessage,
546 typename etl::enable_if< etl::is_message<TMessage>::value && !etl::is_one_of<TMessage, TMessageTypes...>::value,
int>::type = 0>
547 void receive(
const TMessage& msg)
556 static_cast<TDerived*
>(
this)->on_receive_unknown(msg);
564 using imessage_router::accepts;
572 if (
id >= Message_Id_Start)
574 const size_t index = get_dispatch_index_from_message_id(
id);
576 if (index < Number_Of_Messages)
587 bool is_null_router() const ETL_OVERRIDE
593 bool is_producer() const ETL_OVERRIDE
599 bool is_consumer() const ETL_OVERRIDE
606 static constexpr size_t Number_Of_Messages =
sizeof...(TMessageTypes);
607 static constexpr etl::message_id_t Message_Id_Start = etl::type_list_type_at_index_t<sorted_message_types, 0>::ID;
612 template <
size_t Index,
bool Last = (Index + 1U >= Number_Of_Messages)>
613 struct contiguous_impl;
615 template <
size_t Index>
616 struct contiguous_impl<Index, true> : etl::true_type
620 template <
size_t Index>
621 struct contiguous_impl<Index, false>
622 : etl::bool_constant< (etl::type_list_type_at_index_t<sorted_message_types, Index>::ID + 1U
623 == etl::type_list_type_at_index_t<sorted_message_types, Index + 1U>::ID)
624 && contiguous_impl<Index + 1U>::value>
630 static constexpr bool Message_Ids_Are_Contiguous = (Number_Of_Messages <= 1U) ? true : contiguous_impl<0U>::value;
632 using handler_ptr = void (*)(TDerived&,
633 const etl::imessage&);
636 using message_dispatch_table_t = etl::array<handler_ptr,
648 template <
typename TMessage>
649 static void call_on_receive(TDerived& derived,
const imessage& msg)
659 template <
size_t Index>
660 static constexpr handler_ptr get_message_handler()
662 return &call_on_receive< etl::type_list_type_at_index_t<sorted_message_types, Index>>;
669 template <
size_t... Indices>
670 static constexpr message_dispatch_table_t make_message_dispatch_table(etl::index_sequence<Indices...>)
672 return message_dispatch_table_t{{get_message_handler<Indices>()...}};
680 template <
size_t Index>
683 return etl::type_list_type_at_index_t<sorted_message_types, Index>::ID;
690 template <
size_t... Indices>
691 static constexpr message_id_table_t make_message_id_table(etl::index_sequence<Indices...>)
693 return message_id_table_t{{get_message_id_from_index<Indices>()...}};
706 if ETL_IF_CONSTEXPR (Message_Ids_Are_Contiguous)
709 return static_cast<size_t>(
id - Message_Id_Start);
715 size_t right = Number_Of_Messages;
719 size_t mid = (left + right) / 2;
721 if (message_id_table[mid] ==
id)
725 else if (message_id_table[mid] <
id)
736 return Number_Of_Messages;
743 void dispatch(
const etl::imessage& msg,
size_t index)
745 message_dispatch_table[index](
static_cast<TDerived&
>(*this), msg);
752 static ETL_INLINE_VAR
constexpr message_dispatch_table_t message_dispatch_table =
753 etl::message_router<TDerived, TMessageTypes...>::make_message_dispatch_table(
754 etl::make_index_sequence< etl::message_router< TDerived, TMessageTypes...>::Number_Of_Messages>{});
760 static ETL_INLINE_VAR
constexpr message_id_table_t message_id_table = etl::message_router<TDerived, TMessageTypes...>::make_message_id_table(
761 etl::make_index_sequence< etl::message_router< TDerived, TMessageTypes...>::Number_Of_Messages>{});
764 #if ETL_USING_CPP11 && !ETL_USING_CPP17
765 template <
typename TDerived,
typename... TMessageTypes>
766 constexpr const typename etl::message_router< TDerived, TMessageTypes...>::message_dispatch_table_t
767 etl::message_router<TDerived, TMessageTypes...>::message_dispatch_table;
769 template <
typename TDerived,
typename... TMessageTypes>
770 constexpr const typename etl::message_router< TDerived, TMessageTypes...>::message_id_table_t
771 etl::message_router<TDerived, TMessageTypes...>::message_id_table;
777 template <
typename TDerived>
788 : imessage_router(etl::imessage_router::MESSAGE_ROUTER)
796 message_router(etl::imessage_router& successor_)
797 : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_)
814 : imessage_router(id_, successor_)
821 using etl::imessage_router::receive;
842 using imessage_router::accepts;
861 bool is_null_router() const ETL_OVERRIDE
867 bool is_producer() const ETL_OVERRIDE
873 bool is_consumer() const ETL_OVERRIDE
883 template <
typename TDerived,
typename TList>
884 struct message_router_from_type_list;
886 template <
typename TDerived,
typename... TMessageTypes>
887 struct message_router_from_type_list<TDerived, etl::type_list<TMessageTypes...>>
889 using type = etl::message_router<TDerived, TMessageTypes...>;
892 template <
typename TDerived,
typename TTypeList>
893 using message_router_from_type_list_t =
typename message_router_from_type_list<TDerived, TTypeList>::type;
896 #include "private/message_router_cpp03.h"