Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 32 additions & 17 deletions barkeep/barkeep.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,10 @@ class AsyncDisplayer {
/// End the display.
virtual void done() {
if (not running()) { return; } // noop if already done() before
done_ = true;
{
std::lock_guard lock(done_m_);
done_ = true;
}
done_cv_.notify_all();
join();
}
Expand Down Expand Up @@ -614,29 +617,42 @@ class Speedometer {
using Time = std::chrono::time_point<Clock>;

double progress_increment_sum_ = 0; // (weighted) sum of progress increments
Duration duration_increment_sum_{}; // (weighted) sum of duration increments
Duration duration_increment_sum_{}; // (weighted) sum of inter-increment gaps

Time last_start_time_;
ValueType last_progress_;
Time last_increment_time_;
ValueType last_progress_{};

public:
double speed() {
Time now = Clock::now();
Duration dur = now - last_start_time_;
last_start_time_ = now;

ValueType progress_copy =
progress_provider_.load(); // to avoid progress_ changing below
SignedType progress_increment =
SignedType(progress_copy) - SignedType(last_progress_);
last_progress_ = progress_copy;

progress_increment_sum_ =
(1 - discount_) * progress_increment_sum_ + progress_increment;
duration_increment_sum_ = (1 - discount_) * duration_increment_sum_ + dur;
return duration_increment_sum_.count() == 0
? 0
: progress_increment_sum_ / duration_increment_sum_.count();

if (progress_increment != 0) {
Duration gap = now - last_increment_time_;
progress_increment_sum_ =
(1 - discount_) * progress_increment_sum_ + progress_increment;
duration_increment_sum_ = (1 - discount_) * duration_increment_sum_ + gap;
last_progress_ = progress_copy;
last_increment_time_ = now;
}

if (duration_increment_sum_.count() == 0) { return 0; }
double base_speed =
progress_increment_sum_ / duration_increment_sum_.count();

// If we've been waiting longer than the EWMA inter-increment gap implies,
// the true speed must be at most 1/current_wait in magnitude, otherwise
// we would have already seen another increment. Clamp accordingly so the
// reported speed decays when increments stop.
Duration current_wait = now - last_increment_time_;
if (std::abs(base_speed) * current_wait.count() > 1.0) {
return std::copysign(1.0 / current_wait.count(), base_speed);
}
return base_speed;
}

/// Write speed to given output stream. Speed is a double (written with
Expand All @@ -659,10 +675,10 @@ class Speedometer {
*out << s;
}

/// Start computing the speed based on the amount of change in progress.
/// Start computing the speed based on time between progress increments.
void start() {
last_progress_ = progress_provider_.load();
last_start_time_ = Clock::now();
last_increment_time_ = Clock::now();
}

/// Constructor.
Expand Down Expand Up @@ -1189,7 +1205,6 @@ class CompositeDisplay : public BaseDisplay {
display->displayer_->out(&front->out());
}
displayer_->parent(this);
// show();
}

~CompositeDisplay() {
Expand Down
2 changes: 1 addition & 1 deletion tests/demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const static std::string reset = "\033[0m";
const static std::string bold = "\033[1m";
const static std::string dim = "\033[2m";

std::vector<std::optional<double>> speeds{std::nullopt, 0, 0.1, 1};
std::vector<std::optional<double>> speeds{std::nullopt, 0, 0.1};

class Demo {
private:
Expand Down
Loading