From 3ccacc2ca9411b6cbc3f1394aeb7f644b0aee49f Mon Sep 17 00:00:00 2001 From: Erki Date: Sun, 24 Oct 2021 11:10:42 +0300 Subject: [PATCH 1/3] Threads: initial ActorOutput class --- Threads/Inc/threads_actor.hpp | 13 ++++ Threads/Inc/threads_actor_output.hpp | 95 ++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 Threads/Inc/threads_actor_output.hpp diff --git a/Threads/Inc/threads_actor.hpp b/Threads/Inc/threads_actor.hpp index 607615a..41037a1 100644 --- a/Threads/Inc/threads_actor.hpp +++ b/Threads/Inc/threads_actor.hpp @@ -51,6 +51,11 @@ public: : q_(q) {} + Signal(const Signal&) = default; + Signal(Signal&&) = default; + Signal& operator=(const Signal&) = default; + Signal& operator=(Signal&&) = default; + void emit(const T& data) override { parent::value_type to_send = data; @@ -79,6 +84,14 @@ public: return Signal(this); } + template + Signal* getAllocatedSignal() + { + static_assert(std::is_convertible_v, "value_type cannot be constructed from U."); + + return new Signal(this); + } + Signallable* getStaticSignal() { return &signal_; diff --git a/Threads/Inc/threads_actor_output.hpp b/Threads/Inc/threads_actor_output.hpp new file mode 100644 index 0000000..d08a943 --- /dev/null +++ b/Threads/Inc/threads_actor_output.hpp @@ -0,0 +1,95 @@ +/* + * threads_actor_output.hpp + * + * Created on: Oct 24, 2021 + * Author: erki + */ + +#ifndef SKULLC_THREADS_ACTOR_OUTPUT_HPP_ +#define SKULLC_THREADS_ACTOR_OUTPUT_HPP_ + +namespace Threads +{ + +template +class ActorOutput +{ +private: + using signal_variant = std::variant*...>; + std::array stored_signals_; + +public: + using connection_type = std::optional; + + template + connection_type addConnection(Signallable* signal) + { + static_assert(std::disjunction_v...>, "T is not a member of Ts."); + + for (auto it = stored_signals_.begin(); it != stored_signals_.end(); ++it) + { + auto& storage = *it; + + if (std::get_if(&storage)) + { + storage = signal_variant{signal}; + return it; + } + } + + return std::nullopt; + } + + bool removeConnection(connection_type& connection) + { + if (!connection) + return true; + + for (auto it = stored_signals_.begin(); it != stored_signals_.end(); ++it) + { + if (it == *connection) + { + *it = std::monostate; + return true; + } + } + + return false; + } + +protected: + template + void emitOutput(const T& data) + { + static_assert(std::disjunction_v...>, "T is not a member of Ts."); + + for (auto& s : stored_signals_) + { + if (auto** signal = std::get_if*>(&s)) + (*signal)->emit(data); + } + } + + template + void emitOutputFromIsr(const T& data) + { + static_assert(std::disjunction_v...>, "T is not a member of Ts."); + + for (auto& s : stored_signals_) + { + if (auto** signal = std::get_if*>(&s)) + (*signal)->emitFromIsr(data); + } + } +}; + +template +typename Receiver::connection_type connectActors(Sender& sender, Receiver& receiver) +{ + auto* signal = sender.getAllocatedSignal(); + return receiver.addConnection(signal); +} + +}// namespace Threads + +#endif// SKULLC_THREADS_ACTOR_OUTPUT_HPP_ -- 2.47.2 From e77adb65c027e1dfda35cd34fead3d05012a004a Mon Sep 17 00:00:00 2001 From: Erki Date: Fri, 12 Nov 2021 00:58:45 +0200 Subject: [PATCH 2/3] Minor fixes to actor wiring --- Threads/Inc/threads_actor_output.hpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/Threads/Inc/threads_actor_output.hpp b/Threads/Inc/threads_actor_output.hpp index d08a943..b223572 100644 --- a/Threads/Inc/threads_actor_output.hpp +++ b/Threads/Inc/threads_actor_output.hpp @@ -8,6 +8,12 @@ #ifndef SKULLC_THREADS_ACTOR_OUTPUT_HPP_ #define SKULLC_THREADS_ACTOR_OUTPUT_HPP_ +#include +#include +#include + +#include + namespace Threads { @@ -19,7 +25,7 @@ private: std::array stored_signals_; public: - using connection_type = std::optional; + using connection_type = std::optional; template connection_type addConnection(Signallable* signal) @@ -49,7 +55,9 @@ public: { if (it == *connection) { - *it = std::monostate; + delete *it; + + *it = std::monostate{}; return true; } } @@ -84,10 +92,17 @@ protected: }; template -typename Receiver::connection_type connectActors(Sender& sender, Receiver& receiver) +auto connectActors(Sender* sender, Receiver* receiver) { - auto* signal = sender.getAllocatedSignal(); - return receiver.addConnection(signal); + auto* signal = receiver->template getAllocatedSignal(); + return sender->addConnection(signal); +} + +template +auto connectActors(Sender& sender, Receiver& receiver) +{ + auto* signal = receiver.template getAllocatedSignal(); + return sender.addConnection(signal); } }// namespace Threads -- 2.47.2 From a63873c8e4a2329ab7ff8d8c25610c3a2cae3f38 Mon Sep 17 00:00:00 2001 From: Erki Date: Fri, 12 Nov 2021 23:22:32 +0200 Subject: [PATCH 3/3] Specify constructors --- Threads/Inc/threads_actor_output.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Threads/Inc/threads_actor_output.hpp b/Threads/Inc/threads_actor_output.hpp index b223572..748a3e2 100644 --- a/Threads/Inc/threads_actor_output.hpp +++ b/Threads/Inc/threads_actor_output.hpp @@ -25,6 +25,13 @@ private: std::array stored_signals_; public: + ActorOutput() = default; + + ActorOutput(const ActorOutput&) = delete; + ActorOutput(ActorOutput&&) = delete; + ActorOutput& operator=(const ActorOutput&) = delete; + ActorOutput& operator=(ActorOutput&&) = delete; + using connection_type = std::optional; template -- 2.47.2