#include "animatable.hh" using namespace creeper; #include using qwidget = QWidget; using qtimer = QTimer; struct Animatable::Impl { qwidget& component; qtimer scheduler; std::vector> transition_tasks; explicit Impl(auto& component, int hz = 90) noexcept : component { component } { scheduler.connect(&scheduler, &qtimer::timeout, [this] { update(); }); scheduler.setInterval(1'000 / hz); } auto set_frame_rate(int hz) noexcept -> void { scheduler.setInterval(1'000 / hz); } auto push_transition_task(std::unique_ptr task) noexcept -> void { transition_tasks.push_back(std::move(task)); if (!scheduler.isActive()) scheduler.start(); } auto update() noexcept -> void { const auto [first, last] = std::ranges::remove_if(transition_tasks, [](const std::unique_ptr& task) { return !task->update(); }); component.update(); transition_tasks.erase(first, last); if (transition_tasks.empty()) { scheduler.stop(); } } }; Animatable::Animatable(QWidget& component) noexcept : pimpl { std::make_unique(component) } { } Animatable::~Animatable() = default; auto Animatable::set_frame_rate(int hz) noexcept -> void { pimpl->set_frame_rate(hz); // } auto Animatable::push_transition_task(std::unique_ptr task) noexcept -> void { pimpl->push_transition_task(std::move(task)); }