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