ranczo-io/services/floorheat_hub/timer.cpp
Bartosz Wieczorek 9d138b0045 skeleton
2025-08-05 08:10:55 +02:00

59 lines
1.8 KiB
C++

#include "timer.hpp"
#include "spdlog/spdlog.h"
#include <boost/asio/any_io_executor.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/use_awaitable.hpp>
#include <chrono>
#include <functional>
#include <memory>
namespace ranczo {
struct PeriodicTimer::Impl {
private:
std::chrono::milliseconds _interval;
boost::asio::steady_timer _timer;
std::function< void() > _callback;
public:
Impl(boost::asio::any_io_executor & io_context, std::chrono::milliseconds interval, std::function< void() > cb)
: _interval{interval}, _timer(io_context, _interval), _callback{std::move(cb)} {
start();
}
// Coroutine function to handle the timer expiration
boost::asio::awaitable< void > timerCoroutine() {
assert(_callback);
try {
while(true) {
// call my callback
_callback();
// Wait for the timer to expire
co_await _timer.async_wait(boost::asio::use_awaitable);
// Reset the timer for the next interval
_timer.expires_after(_interval);
}
} catch(const std::exception & e) {
spdlog::error("Error: {}", e.what());
}
}
void start() {
spdlog::trace("co_spawn timer");
// Start the coroutine by invoking the timerCoroutine() with boost::asio::co_spawn
boost::asio::co_spawn(_timer.get_executor(), timerCoroutine(), boost::asio::detached);
}
};
PeriodicTimer::PeriodicTimer(executor & executor, std::chrono::milliseconds period, std::function< void() > cb)
: _impl{std::make_unique< Impl >(executor, period, std::move(cb))} {}
PeriodicTimer::~PeriodicTimer() = default;
} // namespace ranczo