Added shared_message example

This commit is contained in:
John Wellbelove 2021-01-15 11:07:41 +00:00
parent 472035d69f
commit 0257275c3c
2 changed files with 52 additions and 34 deletions

View File

@ -41,12 +41,14 @@ struct Message2 : public etl::message<2>
};
//*****************************************************************************
void Print(const std::string& prefix, const etl::shared_message& sm)
void Print(const std::string& prefix, etl::shared_message sm)
{
std::cout << prefix << " : " << int(sm.get_message().get_message_id()) << "\n";
}
//*****************************************************************************
// This router accepts Message1 and Message2 types.
// If a shared message it received, it will be processed immediately.
class MessageRouter1 : public etl::message_router<MessageRouter1, Message1, Message2>
{
public:
@ -60,23 +62,26 @@ public:
//****************************************
void on_receive(etl::imessage_router& source, const Message1& msg)
{
std::cout << "on_receive Message1 : " << msg.s << "\n";
std::cout << "MessageRouter1 : on_receive Message1 : " << msg.s << "\n";
}
//****************************************
void on_receive(etl::imessage_router& source, const Message2& msg)
{
std::cout << "on_receive Message2 : " << msg.s << "\n";
std::cout << "MessageRouter1 : on_receive Message2 : " << msg.s << "\n";
}
//****************************************
void on_receive_unknown(etl::imessage_router& source, const etl::imessage& msg)
{
std::cout << "on_receive Unknown\n";
std::cout << "MessageRouter1 : on_receive Unknown\n";
}
};
//*****************************************************************************
// This router accepts Message1 and Message2 types.
// If a shared message it received it will queue them.
// The messages will be processed when process_queue() is called.
class MessageRouter2 : public etl::message_router<MessageRouter2, Message1, Message2>
{
public:
@ -96,7 +101,7 @@ public:
{
if (!queue.full())
{
Print("Queueing shared message", shared_msg);
Print("MessageRouter2 : Queueing shared message", shared_msg);
queue.push(QueuedData{ &source, shared_msg });
}
@ -110,7 +115,7 @@ public:
// Get the shared message from the queue.
QueuedData data = queue.front();
Print("Process queued shared messages", data.shared_msg);
Print("MessageRouter2 : Process queued shared messages", data.shared_msg);
// Send it to the base implementation for routing.
base_t::receive(*data.source, data.shared_msg);
@ -122,19 +127,19 @@ public:
//****************************************
void on_receive(etl::imessage_router& source, const Message1& msg)
{
std::cout << "on_receive Message1 : " << msg.s << "\n";
std::cout << "MessageRouter2 : on_receive Message1 : " << msg.s << "\n";
}
//****************************************
void on_receive(etl::imessage_router& source, const Message2& msg)
{
std::cout << "on_receive Message2 : " << msg.s << "\n";
std::cout << "MessageRouter2 : on_receive Message2 : " << msg.s << "\n";
}
//****************************************
void on_receive_unknown(etl::imessage_router& source, const etl::imessage& msg)
{
std::cout << "on_receive Unknown\n";
std::cout << "MessageRouter2 : on_receive Unknown\n";
}
private:
@ -149,11 +154,13 @@ private:
};
//*****************************************************************************
// A message bus that can accomodate two subscribers.
struct Bus : public etl::message_bus<2U>
{
};
//*****************************************************************************
// Define the routers and bus.
MessageRouter1 router1;
MessageRouter2 router2;
Bus bus;
@ -161,12 +168,23 @@ Bus bus;
//*****************************************************************************
// The memory block allocator that supplies the pool with memory
// to store reference counted messages in.
etl::fixed_sized_memory_block_allocator<100U, 4U, 4U> memory_pool;
// The reference counted message pool type. Uses atomic uint32_t for counting.
using ref_message_pool = etl::reference_counted_message_pool<std::atomic_int32_t>;
// The reference counted message parameters type for the messages we will use.
using ref_message_parameters = ref_message_pool::pool_message_parameters<Message1, Message2>;
constexpr size_t max_size = ref_message_parameters::max_size;
constexpr size_t max_alignment = ref_message_parameters::max_alignment;
// A fixed memory block allocator for 4 items, using the parameters from the pool.
etl::fixed_sized_memory_block_allocator<max_size, max_alignment, 4U> memory_pool;
//*****************************************************************************
// The pool that supplies reference counted messages.
// Uses memory_pool as its allocator.
etl::reference_counted_message_pool<std::atomic_int32_t> pool(memory_pool);
ref_message_pool pool(memory_pool);
//*****************************************************************************
int main()

View File

@ -142,7 +142,7 @@ namespace etl
#if ETL_CPP11_SUPPORTED
//*****************************************************
template <typename TMessage1, typename... TMessages>
struct max_pool_message_size
struct pool_message_parameters
{
private:
@ -150,26 +150,26 @@ namespace etl
static constexpr size_t size1 = sizeof(etl::reference_counted_message<TMessage1, TCounter>);
// Maximum size of the the rest of the pool message types.
static constexpr size_t size2 = max_pool_message_size<TMessages...>::size;
static constexpr size_t size2 = pool_message_parameters<TMessages...>::size;
// Size of the first pool message type.
static constexpr size_t alignment1 = etl::alignment_of<etl::reference_counted_message<TMessage1, TCounter>>::value;
// Maximum size of the the rest of the pool message types.
static constexpr size_t alignment2 = max_pool_message_size<TMessages...>::alignment;
static constexpr size_t alignment2 = pool_message_parameters<TMessages...>::alignment;
public:
// The maximum size.
static constexpr size_t size = (size1 < size2) ? size2 : size1;
static constexpr size_t max_size = (size1 < size2) ? size2 : size1;
// The maximum alignment.
static constexpr size_t alignment = (alignment1 < alignment2) ? alignment2 : alignment1;
static constexpr size_t max_alignment = (alignment1 < alignment2) ? alignment2 : alignment1;
};
//*****************************************************
template <typename TMessage1>
struct max_pool_message_size<TMessage1>
struct pool_message_parameters<TMessage1>
{
public:
@ -184,7 +184,7 @@ namespace etl
#else
template <typename TMessage1, typename TMessage2 = TMessage1, typename TMessage3 = TMessage1, typename TMessage4 = TMessage1,
typename TMessage5 = TMessage1, typename TMessage6 = TMessage1, typename TMessage7 = TMessage1, typename TMessage8 = TMessage1>
struct max_pool_message_size
struct pool_message_parameters
{
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage1 not derived from etl::imessage");
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage2 not derived from etl::imessage");
@ -195,24 +195,24 @@ namespace etl
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage7 not derived from etl::imessage");
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage8 not derived from etl::imessage");
static const size_t size = etl::largest<etl::reference_counted_message<TMessage1, TCounter>,
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::size;
static const size_t max_size = etl::largest<etl::reference_counted_message<TMessage1, TCounter>,
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::size;
static const size_t alignment = etl::largest<etl::reference_counted_message<TMessage1, TCounter>,
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::alignment;
static const size_t max_alignment = etl::largest<etl::reference_counted_message<TMessage1, TCounter>,
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::alignment;
};
#endif