69 lines
1.4 KiB
C++
69 lines
1.4 KiB
C++
//
|
|
// Created by Grant Horner on 12/1/25.
|
|
//
|
|
|
|
#pragma once
|
|
#include <atomic>
|
|
#include <mutex>
|
|
#include <thread>
|
|
|
|
template<typename T, size_t N>
|
|
struct Spawner {
|
|
std::mutex mutex;
|
|
std::condition_variable cv;
|
|
std::atomic<bool> running;
|
|
std::atomic<bool> paused;
|
|
std::jthread timer;
|
|
long long rate_secs;
|
|
T values[N];
|
|
|
|
explicit Spawner(long long rate_secs);
|
|
|
|
virtual void spawn();
|
|
|
|
template <typename F>
|
|
void for_each(F&& func) {
|
|
std::lock_guard lock{mutex};
|
|
for (auto& value : values) {
|
|
func(value);
|
|
}
|
|
}
|
|
|
|
void start();
|
|
|
|
virtual ~Spawner();
|
|
};
|
|
|
|
template<typename T, size_t N>
|
|
Spawner<T, N>::Spawner(const long long rate_secs) : rate_secs(rate_secs) {
|
|
}
|
|
|
|
template<typename T, size_t N>
|
|
void Spawner<T, N>::spawn() {
|
|
}
|
|
|
|
template<typename T, size_t N>
|
|
void Spawner<T, N>::start() {
|
|
running.store(true);
|
|
timer = std::jthread([&] {
|
|
while (running.load()) {
|
|
const auto start = std::chrono::steady_clock::now();
|
|
|
|
std::unique_lock lock{mutex};
|
|
if (!paused.load()) {
|
|
spawn();
|
|
}
|
|
|
|
auto next = start + std::chrono::seconds(rate_secs);
|
|
cv.wait_until(lock, next, [&] { return !running.load(); });
|
|
}
|
|
});
|
|
}
|
|
|
|
template<typename T, size_t N>
|
|
Spawner<T, N>::~Spawner() {
|
|
running.store(false);
|
|
cv.notify_all();
|
|
}
|
|
|