mirror of
https://github.com/TomHarte/CLK.git
synced 2025-11-01 11:16:16 +00:00
Reformat ClockReceiver.
This commit is contained in:
@@ -15,78 +15,79 @@
|
||||
Provides the logic to insert into and traverse a list of future scheduled items.
|
||||
*/
|
||||
template <typename TimeUnit> class DeferredQueue {
|
||||
public:
|
||||
/*!
|
||||
Schedules @c action to occur in @c delay units of time.
|
||||
*/
|
||||
void defer(TimeUnit delay, const std::function<void(void)> &action) {
|
||||
// Apply immediately if there's no delay (or a negative delay).
|
||||
if(delay <= TimeUnit(0)) {
|
||||
action();
|
||||
return;
|
||||
public:
|
||||
/*!
|
||||
Schedules @c action to occur in @c delay units of time.
|
||||
*/
|
||||
void defer(TimeUnit delay, const std::function<void(void)> &action) {
|
||||
// Apply immediately if there's no delay (or a negative delay).
|
||||
if(delay <= TimeUnit(0)) {
|
||||
action();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!pending_actions_.empty()) {
|
||||
// Otherwise enqueue, having subtracted the delay for any preceding events,
|
||||
// and subtracting from the subsequent, if any.
|
||||
auto insertion_point = pending_actions_.begin();
|
||||
while(insertion_point != pending_actions_.end() && insertion_point->delay < delay) {
|
||||
delay -= insertion_point->delay;
|
||||
++insertion_point;
|
||||
}
|
||||
if(insertion_point != pending_actions_.end()) {
|
||||
insertion_point->delay -= delay;
|
||||
}
|
||||
|
||||
if(!pending_actions_.empty()) {
|
||||
// Otherwise enqueue, having subtracted the delay for any preceding events,
|
||||
// and subtracting from the subsequent, if any.
|
||||
auto insertion_point = pending_actions_.begin();
|
||||
while(insertion_point != pending_actions_.end() && insertion_point->delay < delay) {
|
||||
delay -= insertion_point->delay;
|
||||
++insertion_point;
|
||||
}
|
||||
if(insertion_point != pending_actions_.end()) {
|
||||
insertion_point->delay -= delay;
|
||||
}
|
||||
pending_actions_.emplace(insertion_point, delay, action);
|
||||
} else {
|
||||
pending_actions_.emplace_back(delay, action);
|
||||
}
|
||||
}
|
||||
|
||||
pending_actions_.emplace(insertion_point, delay, action);
|
||||
/*!
|
||||
@returns The amount of time until the next enqueued action will occur,
|
||||
or TimeUnit(-1) if the queue is empty.
|
||||
*/
|
||||
TimeUnit time_until_next_action() const {
|
||||
if(pending_actions_.empty()) return TimeUnit(-1);
|
||||
return pending_actions_.front().delay;
|
||||
}
|
||||
|
||||
/*!
|
||||
Advances the queue the specified amount of time, performing any actions it reaches.
|
||||
*/
|
||||
void advance(TimeUnit time) {
|
||||
auto erase_iterator = pending_actions_.begin();
|
||||
while(erase_iterator != pending_actions_.end()) {
|
||||
erase_iterator->delay -= time;
|
||||
if(erase_iterator->delay <= TimeUnit(0)) {
|
||||
time = -erase_iterator->delay;
|
||||
erase_iterator->action();
|
||||
++erase_iterator;
|
||||
} else {
|
||||
pending_actions_.emplace_back(delay, action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@returns The amount of time until the next enqueued action will occur,
|
||||
or TimeUnit(-1) if the queue is empty.
|
||||
*/
|
||||
TimeUnit time_until_next_action() const {
|
||||
if(pending_actions_.empty()) return TimeUnit(-1);
|
||||
return pending_actions_.front().delay;
|
||||
if(erase_iterator != pending_actions_.begin()) {
|
||||
pending_actions_.erase(pending_actions_.begin(), erase_iterator);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Advances the queue the specified amount of time, performing any actions it reaches.
|
||||
*/
|
||||
void advance(TimeUnit time) {
|
||||
auto erase_iterator = pending_actions_.begin();
|
||||
while(erase_iterator != pending_actions_.end()) {
|
||||
erase_iterator->delay -= time;
|
||||
if(erase_iterator->delay <= TimeUnit(0)) {
|
||||
time = -erase_iterator->delay;
|
||||
erase_iterator->action();
|
||||
++erase_iterator;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(erase_iterator != pending_actions_.begin()) {
|
||||
pending_actions_.erase(pending_actions_.begin(), erase_iterator);
|
||||
}
|
||||
}
|
||||
/// @returns @c true if no actions are enqueued; @c false otherwise.
|
||||
bool empty() const {
|
||||
return pending_actions_.empty();
|
||||
}
|
||||
|
||||
/// @returns @c true if no actions are enqueued; @c false otherwise.
|
||||
bool empty() const {
|
||||
return pending_actions_.empty();
|
||||
}
|
||||
private:
|
||||
// The list of deferred actions.
|
||||
struct DeferredAction {
|
||||
TimeUnit delay;
|
||||
std::function<void(void)> action;
|
||||
|
||||
private:
|
||||
// The list of deferred actions.
|
||||
struct DeferredAction {
|
||||
TimeUnit delay;
|
||||
std::function<void(void)> action;
|
||||
|
||||
DeferredAction(TimeUnit delay, const std::function<void(void)> &action) : delay(delay), action(std::move(action)) {}
|
||||
};
|
||||
std::vector<DeferredAction> pending_actions_;
|
||||
DeferredAction(TimeUnit delay, const std::function<void(void)> &action) :
|
||||
delay(delay), action(std::move(action)) {}
|
||||
};
|
||||
std::vector<DeferredAction> pending_actions_;
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -117,8 +118,6 @@ template <typename TimeUnit> class DeferredQueuePerformer: public DeferredQueue<
|
||||
|
||||
DeferredQueue<TimeUnit>::advance(length);
|
||||
target_(length);
|
||||
|
||||
// TODO: optimise this to avoid the multiple std::vector deletes. Find a neat way to expose that solution, maybe?
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user