96 lines
2.1 KiB
C++
96 lines
2.1 KiB
C++
/*
|
|
* 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_
|