Feature: actor output (#1)
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Co-authored-by: Erki <erki@skullnet.me> Reviewed-on: #1 Co-authored-by: erki <erki.meinberg@gmail.com> Co-committed-by: erki <erki.meinberg@gmail.com>
This commit is contained in:
parent
3b2b535ad5
commit
806416e943
@ -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<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()
|
||||
{
|
||||
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