128 lines
5.1 KiB
C++
128 lines
5.1 KiB
C++
#pragma once
|
|
#include "inode.hpp"
|
|
#include "pool_node.hpp" // PoolNode, PoolObjectNode
|
|
|
|
// node.hpp — Node<> and ObjectNode<> as thin wrappers over PoolNode<>.
|
|
//
|
|
// Each Node owns a private single-thread ThreadPool so the API is unchanged:
|
|
// node.start() / node.stop() are self-contained with no external scheduler.
|
|
// Internally, all execution goes through PoolNode::fire_once() — the same code
|
|
// path as explicitly pool-scheduled nodes.
|
|
//
|
|
// To share a thread pool across multiple nodes, use make_pool_node() directly.
|
|
|
|
namespace kpn {
|
|
|
|
namespace detail {
|
|
|
|
// Private base initialized before PoolNode so its pool can be passed to the
|
|
// PoolNode constructor (C++ initialises bases left-to-right).
|
|
struct NodePrivatePool {
|
|
std::shared_ptr<ThreadPool> pool{std::make_shared<ThreadPool>(1)};
|
|
};
|
|
|
|
} // namespace detail
|
|
|
|
// ── Node ─────────────────────────────────────────────────────────────────────
|
|
|
|
template<auto Func,
|
|
typename InputTag = in<>,
|
|
typename OutputTag = out<>,
|
|
fixed_string Label = "",
|
|
std::size_t UniqueTag = 0>
|
|
class Node;
|
|
|
|
template<auto Func, fixed_string... InNames, fixed_string... OutNames,
|
|
fixed_string Label, std::size_t UniqueTag>
|
|
class Node<Func, in<InNames...>, out<OutNames...>, Label, UniqueTag>
|
|
: private detail::NodePrivatePool
|
|
, public PoolNode<Func, in<InNames...>, out<OutNames...>, Label, UniqueTag> {
|
|
using Base = PoolNode<Func, in<InNames...>, out<OutNames...>, Label, UniqueTag>;
|
|
public:
|
|
explicit Node(std::size_t fifo_capacity = 5)
|
|
: detail::NodePrivatePool{}
|
|
, Base(pool, fifo_capacity)
|
|
{}
|
|
|
|
~Node() override { stop(); }
|
|
|
|
void start() override { pool->start(); Base::start(); }
|
|
void stop() override { Base::stop(); pool->stop(); }
|
|
};
|
|
|
|
// ── ObjectNode ────────────────────────────────────────────────────────────────
|
|
|
|
template<typename Obj,
|
|
typename InputTag = in<>,
|
|
typename OutputTag = out<>,
|
|
fixed_string Label = "",
|
|
std::size_t UniqueTag = 0>
|
|
class ObjectNode;
|
|
|
|
template<typename Obj, fixed_string... InNames, fixed_string... OutNames,
|
|
fixed_string Label, std::size_t UniqueTag>
|
|
class ObjectNode<Obj, in<InNames...>, out<OutNames...>, Label, UniqueTag>
|
|
: private detail::NodePrivatePool
|
|
, public PoolObjectNode<Obj, in<InNames...>, out<OutNames...>, Label, UniqueTag> {
|
|
using Base = PoolObjectNode<Obj, in<InNames...>, out<OutNames...>, Label, UniqueTag>;
|
|
public:
|
|
explicit ObjectNode(Obj& obj, std::size_t fifo_capacity = 5)
|
|
: detail::NodePrivatePool{}
|
|
, Base(obj, pool, fifo_capacity)
|
|
{}
|
|
|
|
~ObjectNode() override { stop(); }
|
|
|
|
void start() override { pool->start(); Base::start(); }
|
|
void stop() override { Base::stop(); pool->stop(); }
|
|
};
|
|
|
|
// ── make_node overloads for callable objects ──────────────────────────────────
|
|
|
|
template<typename Obj>
|
|
auto make_node(Obj& obj, std::size_t fifo_capacity = 5) {
|
|
return ObjectNode<Obj, in<>, out<>>(obj, fifo_capacity);
|
|
}
|
|
|
|
template<typename Obj, fixed_string... InNames>
|
|
auto make_node(Obj& obj, in<InNames...>, std::size_t fifo_capacity = 5) {
|
|
return ObjectNode<Obj, in<InNames...>, out<>>(obj, fifo_capacity);
|
|
}
|
|
|
|
template<typename Obj, fixed_string... OutNames>
|
|
auto make_node(Obj& obj, out<OutNames...>, std::size_t fifo_capacity = 5) {
|
|
return ObjectNode<Obj, in<>, out<OutNames...>>(obj, fifo_capacity);
|
|
}
|
|
|
|
template<typename Obj, fixed_string... InNames, fixed_string... OutNames>
|
|
auto make_node(Obj& obj, in<InNames...>, out<OutNames...>, std::size_t fifo_capacity = 5) {
|
|
return ObjectNode<Obj, in<InNames...>, out<OutNames...>>(obj, fifo_capacity);
|
|
}
|
|
|
|
// ── make_node factory (NTTP) ──────────────────────────────────────────────────
|
|
|
|
template<auto Func, fixed_string Label = "", std::size_t UniqueTag = 0>
|
|
auto make_node(std::size_t fifo_capacity = 5) {
|
|
return Node<Func, in<>, out<>, Label, UniqueTag>(fifo_capacity);
|
|
}
|
|
|
|
template<auto Func, fixed_string Label = "", std::size_t UniqueTag = 0,
|
|
fixed_string... InNames>
|
|
auto make_node(in<InNames...>, std::size_t fifo_capacity = 5) {
|
|
return Node<Func, in<InNames...>, out<>, Label, UniqueTag>(fifo_capacity);
|
|
}
|
|
|
|
template<auto Func, fixed_string Label = "", std::size_t UniqueTag = 0,
|
|
fixed_string... OutNames>
|
|
auto make_node(out<OutNames...>, std::size_t fifo_capacity = 5) {
|
|
return Node<Func, in<>, out<OutNames...>, Label, UniqueTag>(fifo_capacity);
|
|
}
|
|
|
|
template<auto Func, fixed_string Label = "", std::size_t UniqueTag = 0,
|
|
fixed_string... InNames, fixed_string... OutNames>
|
|
auto make_node(in<InNames...>, out<OutNames...>, std::size_t fifo_capacity = 5) {
|
|
return Node<Func, in<InNames...>, out<OutNames...>, Label, UniqueTag>(fifo_capacity);
|
|
}
|
|
|
|
} // namespace kpn
|