Files
Aethera/kernel/kernel/include/function/frame_policy/global.cpp
T
2026-08-31 18:03:39 +08:00

88 lines
2.3 KiB
C++

#include "global.ipp"
#include "time_thread/Timer_Service.hpp"
#include <exception>
#include <utility>
namespace aethera {
Throttled_Latest_only::Private::Private(
proxy<FP_Scene> scene,
proxy<FP_Sink> sink) :
state(std::make_shared<detail::Throttled_Latest_Only_State>(
std::move(scene),
std::move(sink))) {}
Throttled_Latest_only::Throttled_Latest_only(
proxy<FP_Scene> scene,
proxy<FP_Sink> sink) :
d(std::make_unique<Private>(std::move(scene), std::move(sink))) {}
Throttled_Latest_only::~Throttled_Latest_only() noexcept {
if (!d->state->destructible()) {
std::terminate();
}
}
Start_Throttled_Latest_Only_Result
Throttled_Latest_only::start(double frames_per_second) {
const auto interval =
detail::timer_interval_from_frames_per_second(frames_per_second);
if (!interval) {
return interval.error() ==
Schedule_Every_Fps_Result::invalid_frames_per_second
? Start_Throttled_Latest_Only_Result::invalid_frames_per_second
: Start_Throttled_Latest_Only_Result::interval_out_of_range;
}
const auto prepared = d->state->prepare_start();
if (prepared != Start_Throttled_Latest_Only_Result::started) {
return prepared;
}
const auto state = d->state;
Timer_Id timer_id{};
try {
timer_id =
Timer_Service::instance().schedule_every(
*interval,
[state] {
state->frame_due();
});
}
catch (...) {
state->start_failed();
throw;
}
state->timer_started(timer_id);
return Start_Throttled_Latest_Only_Result::started;
}
Stop_Throttled_Latest_Only_Result
Throttled_Latest_only::stop(
Throttled_Latest_Only_Stop_Completion completion) {
auto request = d->state->request_stop(std::move(completion));
if (request.result !=
Stop_Throttled_Latest_Only_Result::stopping) {
return request.result;
}
if (!request.timer_id) {
std::terminate();
}
try {
const auto state = d->state;
Timer_Service::instance().cancel(
*request.timer_id,
[state] {
state->timer_cancelled();
});
}
catch (...) {
d->state->cancel_failed();
throw;
}
return Stop_Throttled_Latest_Only_Result::stopping;
}
}