You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/components/misc/progressreporter.hpp

53 lines
1.6 KiB
C++

#ifndef OPENMW_COMPONENTS_MISC_PROGRESSREPORTER_H
#define OPENMW_COMPONENTS_MISC_PROGRESSREPORTER_H
#include <algorithm>
#include <chrono>
#include <mutex>
#include <type_traits>
#include <utility>
namespace Misc
{
template <class Report>
class ProgressReporter
{
public:
explicit ProgressReporter(Report&& report = Report{})
: mReport(std::forward<Report>(report))
{
}
explicit ProgressReporter(std::chrono::steady_clock::duration interval, Report&& report = Report{})
: mInterval(interval)
, mReport(std::forward<Report>(report))
{
}
void operator()(std::size_t provided, std::size_t expected)
{
expected = std::max(expected, provided);
const bool shouldReport = [&] {
const std::lock_guard lock(mMutex);
const auto now = std::chrono::steady_clock::now();
if (mNextReport > now || provided == expected)
return false;
if (mInterval.count() > 0)
mNextReport
= mNextReport + mInterval * ((now - mNextReport + mInterval).count() / mInterval.count());
return true;
}();
if (shouldReport)
mReport(provided, expected);
}
private:
const std::chrono::steady_clock::duration mInterval = std::chrono::seconds(1);
Report mReport;
std::mutex mMutex;
std::chrono::steady_clock::time_point mNextReport{ std::chrono::steady_clock::now() + mInterval };
};
}
#endif