// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ProgressTimer.hpp"
#include <Text.hpp>
#include <ProgressBar.hpp>
#include <ApplicationCommon.hpp>
#include <apps-common/GuiTimer.hpp>
#include <gsl/assert>
namespace app
{
ProgressTimer::ProgressTimer(app::ApplicationCommon *app,
gui::Item &parent,
std::string timerName,
std::chrono::milliseconds baseTick,
ProgressCountdownMode countdownMode,
utils::time::Duration::DisplayedFormat displayFormat)
: app{app}, parent{parent}, name{std::move(timerName)}, baseTickInterval{baseTick},
countdownMode{countdownMode}, displayFormat{displayFormat}
{}
void ProgressTimer::update()
{
app->refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
}
void ProgressTimer::reset(std::chrono::seconds _duration, std::chrono::seconds _interval)
{
Expects(_duration != std::chrono::seconds::zero());
duration = _duration;
elapsed = std::chrono::seconds::zero();
interval = _interval;
hasInterval = _interval != std::chrono::seconds::zero();
update();
}
void ProgressTimer::start()
{
startTimer();
isRunning = true;
}
void ProgressTimer::startTimer()
{
Expects(app != nullptr);
parent.timerCallback = [this]([[maybe_unused]] gui::Item &it, sys::Timer &task) {
return onTimerTimeout(task);
};
timerTask = app::GuiTimerFactory::createPeriodicTimer(app, &parent, name, baseTickInterval);
timerTask.start();
}
auto ProgressTimer::onTimerTimeout(sys::Timer &task) -> bool
{
if (isStopped()) {
task.stop();
return false;
}
elapsed += baseTickInterval;
update();
if (isFinished()) {
task.stop();
if (isFinished() && onFinishedCallback != nullptr) {
onFinishedCallback();
}
return true;
}
if ((intervalReached() || isFinished()) && onIntervalCallback != nullptr) {
onIntervalCallback();
}
return true;
}
auto ProgressTimer::isFinished() const noexcept -> bool
{
return duration <= elapsed;
}
auto ProgressTimer::isStopped() const noexcept -> bool
{
return !isRunning;
}
auto ProgressTimer::intervalReached() const noexcept -> bool
{
return hasInterval &&
(std::chrono::duration_cast<std::chrono::seconds>(elapsed).count() % interval.count()) == 0;
}
void ProgressTimer::stop()
{
isRunning = false;
}
std::chrono::milliseconds ProgressTimer::getElapsed()
{
return elapsed;
}
void ProgressTimer::registerOnFinishedCallback(std::function<void()> cb)
{
onFinishedCallback = std::move(cb);
}
void ProgressTimer::registerOnIntervalCallback(std::function<void()> cb)
{
onIntervalCallback = std::move(cb);
}
} // namespace app