// // Created by Grant Horner on 12/1/25. // #pragma once #include #include #include template struct Spawner { std::mutex mutex; std::condition_variable cv; std::atomic paused; std::jthread timer; std::atomic rate_secs; std::array values; explicit Spawner(long long rate_secs); virtual void spawn(); template void for_each(F&& func) { std::lock_guard lock{mutex}; for (auto& value : values) { func(value); } } void start(); virtual ~Spawner(); }; template Spawner::Spawner(const long long rate_secs) : rate_secs(rate_secs) { } template void Spawner::spawn() { } template void Spawner::start() { timer = std::jthread([&] (const std::stop_token &st) { while (!st.stop_requested()) { 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); } }); } template Spawner::~Spawner() { timer.request_stop(); cv.notify_all(); }