From 74d901cc86882c80bef299ab48a409aab7633b10 Mon Sep 17 00:00:00 2001 From: Erki Date: Sun, 20 Jun 2021 23:23:27 +0300 Subject: [PATCH] Threads: void specialization for Actor --- Threads/Inc/threads_actor.hpp | 90 +++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 5 deletions(-) diff --git a/Threads/Inc/threads_actor.hpp b/Threads/Inc/threads_actor.hpp index f5f94bd..e5f3be5 100644 --- a/Threads/Inc/threads_actor.hpp +++ b/Threads/Inc/threads_actor.hpp @@ -28,7 +28,7 @@ public: 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), @@ -37,14 +37,14 @@ public: assert(msg_queue_); } - Signallable* getSignal() + Signallable* getSignal() { return &signal_; } protected: virtual void init() = 0; - virtual void onSignal(const T& data) = 0; + virtual void onSignal(const value_type& data) = 0; private: PrimitiveThread thread_; @@ -60,7 +60,7 @@ private: { const BaseType_t got = xQueueReceive(msg_queue_, &data, portMAX_DELAY); - if (got) + if (got == pdTRUE) { onSignal(data); } @@ -71,7 +71,7 @@ private: struct Signal_ : Signallable { - using parent = Actor; + using parent = Actor; parent& q; explicit Signal_(parent& q) @@ -96,6 +96,86 @@ private: Signal_ signal_; }; +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); + (*dd)(); + }, + this, name, priority, stack_size), + msg_queue_(xQueueCreate(queue_size, sizeof(int))), signal_(*this) + { + assert(msg_queue_); + } + + Signallable* getSignal() + { + return &signal_; + } + +protected: + virtual void init() = 0; + virtual void onSignal() = 0; + +private: + PrimitiveThread thread_; + QueueHandle_t msg_queue_; + + void operator()() + { + init(); + + int data; + + while (true) + { + const BaseType_t got = xQueueReceive(msg_queue_, &data, portMAX_DELAY); + + if (got == pdTRUE) + { + onSignal(); + } + } + } + + friend struct Signal_; + + struct Signal_ : Signallable + { + using parent = Actor; + parent& q; + + explicit Signal_(parent& q) + : q(q) + {} + + bool emit() override + { + const int data = 0; + + const BaseType_t success = xQueueSend(q.msg_queue_, &data, 0); + return success == pdTRUE; + } + + std::pair emitFromIsr() override + { + const int data = 0; + + BaseType_t was_awoken = pdFALSE; + const BaseType_t success = xQueueSendFromISR(q.msg_queue_, &data, &was_awoken); + + return {success == pdTRUE, was_awoken}; + } + }; + + Signal_ signal_; +}; + }// namespace Threads