Threads: Implement multivariate actors
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
15652f7347
commit
6bbdf4cb71
@ -13,6 +13,7 @@
|
|||||||
#include <queue.h>
|
#include <queue.h>
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
#include "threads_primitivethread.hpp"
|
#include "threads_primitivethread.hpp"
|
||||||
#include "threads_signal.hpp"
|
#include "threads_signal.hpp"
|
||||||
@ -20,18 +21,18 @@
|
|||||||
namespace Threads
|
namespace Threads
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename T>
|
template<typename CRTP, typename... Ts>
|
||||||
class Actor
|
class Actor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using value_type = T;
|
using value_type = std::variant<Ts...>;
|
||||||
|
|
||||||
static_assert(std::is_default_constructible_v<value_type>, "T must be default constructible.");
|
static_assert(std::is_default_constructible_v<value_type>, "Ts must be default constructible.");
|
||||||
static_assert(std::is_trivially_copyable_v<value_type>, "T must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<value_type>, "Ts must be trivially copyable.");
|
||||||
|
|
||||||
Actor(const std::uint32_t queue_size, const char* name, const osPriority_t priority, const std::uint32_t stack_size)
|
Actor(const std::uint32_t queue_size, const char* name, const osPriority_t priority, const std::uint32_t stack_size)
|
||||||
: thread_([](void* d) {
|
: thread_([](void* d) {
|
||||||
auto* dd = static_cast<Actor<value_type>*>(d);
|
auto* dd = static_cast<Actor<CRTP, Ts...>*>(d);
|
||||||
(*dd)();
|
(*dd)();
|
||||||
},
|
},
|
||||||
this, name, priority, stack_size),
|
this, name, priority, stack_size),
|
||||||
@ -40,6 +41,8 @@ public:
|
|||||||
assert(msg_queue_);
|
assert(msg_queue_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ~Actor() {}
|
||||||
|
|
||||||
Signallable<value_type>* getSignal()
|
Signallable<value_type>* getSignal()
|
||||||
{
|
{
|
||||||
return &signal_;
|
return &signal_;
|
||||||
@ -47,12 +50,28 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void init() = 0;
|
virtual void init() = 0;
|
||||||
virtual void onSignal(const value_type& data) = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PrimitiveThread thread_;
|
PrimitiveThread thread_;
|
||||||
QueueHandle_t msg_queue_;
|
QueueHandle_t msg_queue_;
|
||||||
|
|
||||||
|
struct Visitor_
|
||||||
|
{
|
||||||
|
using parent = Actor<CRTP, Ts...>;
|
||||||
|
parent* q;
|
||||||
|
|
||||||
|
Visitor_(parent* q)
|
||||||
|
: q(q)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
void operator()(const U& u)
|
||||||
|
{
|
||||||
|
CRTP* s = static_cast<CRTP*>(q);
|
||||||
|
s->onSignal(u);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
@ -65,7 +84,7 @@ private:
|
|||||||
|
|
||||||
if (got == pdTRUE)
|
if (got == pdTRUE)
|
||||||
{
|
{
|
||||||
onSignal(data);
|
std::visit(Visitor_{this}, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,7 +93,7 @@ private:
|
|||||||
|
|
||||||
struct Signal_ : Signallable<value_type>
|
struct Signal_ : Signallable<value_type>
|
||||||
{
|
{
|
||||||
using parent = Actor<value_type>;
|
using parent = Actor<CRTP, Ts...>;
|
||||||
parent& q;
|
parent& q;
|
||||||
|
|
||||||
explicit Signal_(parent& q)
|
explicit Signal_(parent& q)
|
||||||
@ -99,15 +118,15 @@ private:
|
|||||||
Signal_ signal_;
|
Signal_ signal_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<typename CRTP>
|
||||||
class Actor<void>
|
class Actor<CRTP, void>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using value_type = void;
|
using value_type = void;
|
||||||
|
|
||||||
Actor(const std::uint32_t queue_size, const char* name, const osPriority_t priority, const std::uint32_t stack_size)
|
Actor(const std::uint32_t queue_size, const char* name, const osPriority_t priority, const std::uint32_t stack_size)
|
||||||
: thread_([](void* d) {
|
: thread_([](void* d) {
|
||||||
auto* dd = static_cast<Actor<value_type>*>(d);
|
auto* dd = static_cast<Actor<CRTP, value_type>*>(d);
|
||||||
(*dd)();
|
(*dd)();
|
||||||
},
|
},
|
||||||
this, name, priority, stack_size),
|
this, name, priority, stack_size),
|
||||||
@ -116,6 +135,8 @@ public:
|
|||||||
assert(msg_queue_);
|
assert(msg_queue_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ~Actor() {}
|
||||||
|
|
||||||
Signallable<value_type>* getSignal()
|
Signallable<value_type>* getSignal()
|
||||||
{
|
{
|
||||||
return &signal_;
|
return &signal_;
|
||||||
@ -123,7 +144,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void init() = 0;
|
virtual void init() = 0;
|
||||||
virtual void onSignal() = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PrimitiveThread thread_;
|
PrimitiveThread thread_;
|
||||||
@ -141,7 +161,8 @@ private:
|
|||||||
|
|
||||||
if (got == pdTRUE)
|
if (got == pdTRUE)
|
||||||
{
|
{
|
||||||
onSignal();
|
auto* crtp = static_cast<CRTP*>(this);
|
||||||
|
crtp->onSignal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,7 +171,7 @@ private:
|
|||||||
|
|
||||||
struct Signal_ : Signallable<value_type>
|
struct Signal_ : Signallable<value_type>
|
||||||
{
|
{
|
||||||
using parent = Actor<value_type>;
|
using parent = Actor<CRTP, void>;
|
||||||
parent& q;
|
parent& q;
|
||||||
|
|
||||||
explicit Signal_(parent& q)
|
explicit Signal_(parent& q)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user