Feature: actor output #1
@ -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_;
|
||||
|
||||
95
Threads/Inc/threads_actor_output.hpp
Normal file
95
Threads/Inc/threads_actor_output.hpp
Normal file
@ -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<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:
|
||||
using connection_type = std::optional<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)
|
||||
{
|
||||
*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>
|
||||
typename Receiver::connection_type connectActors(Sender& sender, Receiver& receiver)
|
||||
{
|
||||
auto* signal = sender.getAllocatedSignal<T>();
|
||||
return receiver.addConnection(signal);
|
||||
}
|
||||
|
||||
}// namespace Threads
|
||||
|
||||
#endif// SKULLC_THREADS_ACTOR_OUTPUT_HPP_
|
||||
Loading…
x
Reference in New Issue
Block a user