<commit_before>//
//  BestEffortUpdater.cpp
//  Clock Signal
//
//  Created by <NAME> on 04/10/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

#include "BestEffortUpdater.hpp"

#include <cmath>

using namespace Concurrency;

void BestEffortUpdater::update() {
	// Perform an update only if one is not currently ongoing.
	if(!update_is_ongoing_.test_and_set()) {
		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_;
			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(delegate_) {
					delegate_->update(this, (int)cycles, has_skipped_);
				}
				has_skipped_ = false;
			} else {
				has_previous_time_point_ = true;
			}

			// Allow furthers updates to occur.
			update_is_ongoing_.clear();
		});
	} else {
		async_task_queue_.enqueue([this]() {
			has_skipped_ = true;
		});
	}
}

void BestEffortUpdater::flush() {
	async_task_queue_.flush();
}

void BestEffortUpdater::set_delegate(Delegate *delegate) {
	async_task_queue_.enqueue([this, delegate]() {
		delegate_ = delegate;
	});
}

void BestEffortUpdater::set_clock_rate(double clock_rate) {
	async_task_queue_.enqueue([this, clock_rate]() {
		this->clock_rate_ = clock_rate;
	});
}<commit_msg>Attempts to ensure good behaviour if dealt an adjustable clock, and `const`s where possible.<commit_after>//
//  BestEffortUpdater.cpp
//  Clock Signal
//
//  Created by <NAME> on 04/10/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

#include "BestEffortUpdater.hpp"

#include <cmath>

using namespace Concurrency;

void BestEffortUpdater::update() {
	// Perform an update only if one is not currently ongoing.
	if(!update_is_ongoing_.test_and_set()) {
		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.
			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. 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, static_cast<int>(std::min(cycles, clock_rate_)), has_skipped_);
					}
					has_skipped_ = false;
				}
			} else {
				has_previous_time_point_ = true;
			}

			// Allow furthers updates to occur.
			update_is_ongoing_.clear();
		});
	} else {
		async_task_queue_.enqueue([this]() {
			has_skipped_ = true;
		});
	}
}

void BestEffortUpdater::flush() {
	async_task_queue_.flush();
}

void BestEffortUpdater::set_delegate(Delegate *const delegate) {
	async_task_queue_.enqueue([this, delegate]() {
		delegate_ = delegate;
	});
}

void BestEffortUpdater::set_clock_rate(const double clock_rate) {
	async_task_queue_.enqueue([this, clock_rate]() {
		this->clock_rate_ = clock_rate;
	});
}
{'fraction_non_alphanumeric': 0.12083024462564863, 'fraction_numerical': 0.00914257474672597, 'mean_word_length': 4.163265306122449, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6866483', 'n_tokens_mistral': 1497, 'n_tokens_neox': 1318, 'n_words': 332}