From 6bbdf4cb718bac1754f2701c41054bbd8912bccb Mon Sep 17 00:00:00 2001 From: Erki Date: Wed, 23 Jun 2021 12:27:32 +0300 Subject: [PATCH] Threads: Implement multivariate actors --- Threads/Inc/threads_actor.hpp | 49 +++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/Threads/Inc/threads_actor.hpp b/Threads/Inc/threads_actor.hpp index a3cd524..0d7bc08 100644 --- a/Threads/Inc/threads_actor.hpp +++ b/Threads/Inc/threads_actor.hpp @@ -13,6 +13,7 @@ #include #include +#include #include "threads_primitivethread.hpp" #include "threads_signal.hpp" @@ -20,18 +21,18 @@ namespace Threads { -template +template class Actor { public: - using value_type = T; + using value_type = std::variant; - static_assert(std::is_default_constructible_v, "T must be default constructible."); - static_assert(std::is_trivially_copyable_v, "T must be trivially copyable."); + static_assert(std::is_default_constructible_v, "Ts must be default constructible."); + static_assert(std::is_trivially_copyable_v, "Ts must be trivially copyable."); Actor(const std::uint32_t queue_size, const char* name, const osPriority_t priority, const std::uint32_t stack_size) : thread_([](void* d) { - auto* dd = static_cast*>(d); + auto* dd = static_cast*>(d); (*dd)(); }, this, name, priority, stack_size), @@ -40,6 +41,8 @@ public: assert(msg_queue_); } + virtual ~Actor() {} + Signallable* getSignal() { return &signal_; @@ -47,12 +50,28 @@ public: protected: virtual void init() = 0; - virtual void onSignal(const value_type& data) = 0; private: PrimitiveThread thread_; QueueHandle_t msg_queue_; + struct Visitor_ + { + using parent = Actor; + parent* q; + + Visitor_(parent* q) + : q(q) + {} + + template + void operator()(const U& u) + { + CRTP* s = static_cast(q); + s->onSignal(u); + } + }; + void operator()() { init(); @@ -65,7 +84,7 @@ private: if (got == pdTRUE) { - onSignal(data); + std::visit(Visitor_{this}, data); } } } @@ -74,7 +93,7 @@ private: struct Signal_ : Signallable { - using parent = Actor; + using parent = Actor; parent& q; explicit Signal_(parent& q) @@ -99,15 +118,15 @@ private: Signal_ signal_; }; -template<> -class Actor +template +class Actor { public: using value_type = void; Actor(const std::uint32_t queue_size, const char* name, const osPriority_t priority, const std::uint32_t stack_size) : thread_([](void* d) { - auto* dd = static_cast*>(d); + auto* dd = static_cast*>(d); (*dd)(); }, this, name, priority, stack_size), @@ -116,6 +135,8 @@ public: assert(msg_queue_); } + virtual ~Actor() {} + Signallable* getSignal() { return &signal_; @@ -123,7 +144,6 @@ public: protected: virtual void init() = 0; - virtual void onSignal() = 0; private: PrimitiveThread thread_; @@ -141,7 +161,8 @@ private: if (got == pdTRUE) { - onSignal(); + auto* crtp = static_cast(this); + crtp->onSignal(); } } } @@ -150,7 +171,7 @@ private: struct Signal_ : Signallable { - using parent = Actor; + using parent = Actor; parent& q; explicit Signal_(parent& q)