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

51 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