-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #70 from albertziegenhagel/progress-support
Initial progress and cancelation support
- Loading branch information
Showing
28 changed files
with
1,352 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
|
||
#include <snail/common/progress.hpp> | ||
|
||
#include <algorithm> | ||
#include <cmath> | ||
|
||
using namespace snail::common; | ||
|
||
progress_listener::progress_listener(double resolution) : | ||
resolution_(resolution) | ||
{} | ||
|
||
double progress_listener::resolution() const | ||
{ | ||
return resolution_; | ||
} | ||
|
||
void cancellation_token::cancel() | ||
{ | ||
cancel_ = true; | ||
} | ||
|
||
bool cancellation_token::is_canceled() const | ||
{ | ||
return cancel_.load(); | ||
} | ||
|
||
progress_reporter::progress_reporter(const progress_listener* listener, | ||
work_type total_work) : | ||
listener_(listener), | ||
total_work_(total_work), | ||
step_work_(((listener != nullptr) ? listener->resolution() : 1.0) * total_work_), | ||
current_work_(0), | ||
next_report_step_(1), | ||
next_report_work_(static_cast<work_type>(std::ceil(step_work_ * next_report_step_))) | ||
{ | ||
if(listener_ != nullptr) | ||
{ | ||
listener_->start(); | ||
listener_->report(0.0); | ||
} | ||
} | ||
|
||
void progress_reporter::progress(work_type work) | ||
{ | ||
current_work_ += work; | ||
if(current_work_ < next_report_work_) return; | ||
|
||
const auto current_progress = double(current_work_) / total_work_; | ||
if(listener_ != nullptr) listener_->report(current_progress); | ||
|
||
const auto current_step = static_cast<unsigned int>(double(current_work_) / step_work_); | ||
|
||
next_report_step_ = std::max(next_report_step_ + 1u, current_step + 1u); | ||
|
||
next_report_work_ = static_cast<work_type>(std::ceil(step_work_ * next_report_step_)); | ||
|
||
if(current_work_ < total_work_ && next_report_work_ > total_work_) | ||
{ | ||
// Make sure we always report at 100% | ||
// This does also fix issues with rounding around 100%. | ||
next_report_work_ = total_work_; | ||
--next_report_step_; // Since the value we will report at next is not a real | ||
// step, we should not count it as one. | ||
// The easiest thing is to simply decrement the step counter | ||
// here. | ||
} | ||
} | ||
|
||
void progress_reporter::finish() | ||
{ | ||
if(listener_ == nullptr) return; | ||
if(current_work_ < total_work_) listener_->report(1.0); | ||
listener_->finish(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#pragma once | ||
|
||
#include <atomic> | ||
#include <cstddef> | ||
|
||
namespace snail::common { | ||
|
||
class progress_listener | ||
{ | ||
public: | ||
progress_listener(double resolution = 0.01); | ||
|
||
double resolution() const; | ||
|
||
virtual void start() const = 0; | ||
virtual void report(double progress) const = 0; | ||
virtual void finish() const = 0; | ||
|
||
private: | ||
double resolution_; | ||
}; | ||
|
||
class cancellation_token | ||
{ | ||
public: | ||
void cancel(); | ||
bool is_canceled() const; | ||
|
||
private: | ||
std::atomic<bool> cancel_ = false; | ||
}; | ||
|
||
class progress_reporter | ||
{ | ||
public: | ||
using work_type = std::size_t; | ||
|
||
progress_reporter(const progress_listener* listener, | ||
work_type total_work); | ||
|
||
void start(); | ||
void progress(work_type work); | ||
void finish(); | ||
|
||
private: | ||
const progress_listener* listener_; | ||
|
||
const work_type total_work_; | ||
|
||
const double step_work_; | ||
|
||
work_type current_work_; | ||
|
||
unsigned int next_report_step_; | ||
work_type next_report_work_; | ||
}; | ||
|
||
} // namespace snail::common |
Oops, something went wrong.