1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-22 12:33:29 +00:00

Attempts to ensure good behaviour if dealt an adjustable clock, and consts where possible.

This commit is contained in:
Thomas Harte 2017-10-05 18:23:56 -04:00
parent 95c82f5b36
commit d37ec9e5b0

View File

@ -18,21 +18,24 @@ void BestEffortUpdater::update() {
async_task_queue_.enqueue([this]() { async_task_queue_.enqueue([this]() {
// Get time now using the highest-resolution clock provided by the implementation, and determine // Get time now using the highest-resolution clock provided by the implementation, and determine
// the duration since the last time this section was entered. // the duration since the last time this section was entered.
std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now(); const std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now();
auto elapsed = now - previous_time_point_; const auto elapsed = now - previous_time_point_;
previous_time_point_ = now; previous_time_point_ = now;
if(has_previous_time_point_) { if(has_previous_time_point_) {
// If the duration is valid, convert it to integer cycles, maintaining a rolling error and call the delegate // If the duration is valid, convert it to integer cycles, maintaining a rolling error and call the delegate
// if there is one. // if there is one. Proceed only if the number of cycles is positive, and cap it to the per-second maximum —
int64_t duration = std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed).count(); // it's possible this is an adjustable clock so be ready to swallow unexpected adjustments.
double cycles = ((static_cast<double>(duration) * clock_rate_) / 1e9) + error_; const int64_t duration = std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed).count();
error_ = fmod(cycles, 1.0); if(duration > 0) {
double cycles = ((static_cast<double>(duration) * clock_rate_) / 1e9) + error_;
error_ = fmod(cycles, 1.0);
if(delegate_) { if(delegate_) {
delegate_->update(this, (int)cycles, has_skipped_); delegate_->update(this, static_cast<int>(std::min(cycles, clock_rate_)), has_skipped_);
}
has_skipped_ = false;
} }
has_skipped_ = false;
} else { } else {
has_previous_time_point_ = true; has_previous_time_point_ = true;
} }
@ -51,13 +54,13 @@ void BestEffortUpdater::flush() {
async_task_queue_.flush(); async_task_queue_.flush();
} }
void BestEffortUpdater::set_delegate(Delegate *delegate) { void BestEffortUpdater::set_delegate(Delegate *const delegate) {
async_task_queue_.enqueue([this, delegate]() { async_task_queue_.enqueue([this, delegate]() {
delegate_ = delegate; delegate_ = delegate;
}); });
} }
void BestEffortUpdater::set_clock_rate(double clock_rate) { void BestEffortUpdater::set_clock_rate(const double clock_rate) {
async_task_queue_.enqueue([this, clock_rate]() { async_task_queue_.enqueue([this, clock_rate]() {
this->clock_rate_ = clock_rate; this->clock_rate_ = clock_rate;
}); });