Feature: actor output #1
@ -51,6 +51,11 @@ public:
|
|||||||
: q_(q)
|
: q_(q)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
Signal(const Signal&) = default;
|
||||||
|
Signal(Signal&&) = default;
|
||||||
|
Signal& operator=(const Signal&) = default;
|
||||||
|
Signal& operator=(Signal&&) = default;
|
||||||
|
|
||||||
void emit(const T& data) override
|
void emit(const T& data) override
|
||||||
{
|
{
|
||||||
parent::value_type to_send = data;
|
parent::value_type to_send = data;
|
||||||
@ -79,6 +84,14 @@ public:
|
|||||||
return Signal<U>(this);
|
return Signal<U>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
Signal<U>* getAllocatedSignal()
|
||||||
|
{
|
||||||
|
static_assert(std::is_convertible_v<U, value_type>, "value_type cannot be constructed from U.");
|
||||||
|
|
||||||
|
return new Signal<U>(this);
|
||||||
|
}
|
||||||
|
|
||||||
Signallable<value_type>* getStaticSignal()
|
Signallable<value_type>* getStaticSignal()
|
||||||
{
|
{
|
||||||
return &signal_;
|
return &signal_;
|
||||||
|
|||||||
117
Threads/Inc/threads_actor_output.hpp
Normal file
117
Threads/Inc/threads_actor_output.hpp
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* threads_actor_output.hpp
|
||||||
|
*
|
||||||
|
* Created on: Oct 24, 2021
|
||||||
|
* Author: erki
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SKULLC_THREADS_ACTOR_OUTPUT_HPP_
|
||||||
|
#define SKULLC_THREADS_ACTOR_OUTPUT_HPP_
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <optional>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
#include <threads_signal.hpp>
|
||||||
|
|
||||||
|
namespace Threads
|
||||||
|
{
|
||||||
|
|
||||||
|
template<std::size_t N, typename... Ts>
|
||||||
|
class ActorOutput
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
using signal_variant = std::variant<std::monostate, Signallable<Ts>*...>;
|
||||||
|
std::array<signal_variant, N> 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<typename decltype(stored_signals_)::iterator>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
connection_type addConnection(Signallable<T>* signal)
|
||||||
|
{
|
||||||
|
static_assert(std::disjunction_v<std::is_same<T, Ts>...>, "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<std::monostate>(&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)
|
||||||
|
{
|
||||||
|
delete *it;
|
||||||
|
|
||||||
|
*it = std::monostate{};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template<typename T>
|
||||||
|
void emitOutput(const T& data)
|
||||||
|
{
|
||||||
|
static_assert(std::disjunction_v<std::is_same<T, Ts>...>, "T is not a member of Ts.");
|
||||||
|
|
||||||
|
for (auto& s : stored_signals_)
|
||||||
|
{
|
||||||
|
if (auto** signal = std::get_if<Signallable<T>*>(&s))
|
||||||
|
(*signal)->emit(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void emitOutputFromIsr(const T& data)
|
||||||
|
{
|
||||||
|
static_assert(std::disjunction_v<std::is_same<T, Ts>...>, "T is not a member of Ts.");
|
||||||
|
|
||||||
|
for (auto& s : stored_signals_)
|
||||||
|
{
|
||||||
|
if (auto** signal = std::get_if<Signallable<T>*>(&s))
|
||||||
|
(*signal)->emitFromIsr(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, typename Sender, typename Receiver>
|
||||||
|
auto connectActors(Sender* sender, Receiver* receiver)
|
||||||
|
{
|
||||||
|
auto* signal = receiver->template getAllocatedSignal<T>();
|
||||||
|
return sender->addConnection(signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename Sender, typename Receiver>
|
||||||
|
auto connectActors(Sender& sender, Receiver& receiver)
|
||||||
|
{
|
||||||
|
auto* signal = receiver.template getAllocatedSignal<T>();
|
||||||
|
return sender.addConnection(signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace Threads
|
||||||
|
|
||||||
|
#endif// SKULLC_THREADS_ACTOR_OUTPUT_HPP_
|
||||||
Loading…
x
Reference in New Issue
Block a user