aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/scheduler.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/scheduler.rs')
-rw-r--r--alacritty/src/scheduler.rs102
1 files changed, 102 insertions, 0 deletions
diff --git a/alacritty/src/scheduler.rs b/alacritty/src/scheduler.rs
new file mode 100644
index 00000000..a6559acc
--- /dev/null
+++ b/alacritty/src/scheduler.rs
@@ -0,0 +1,102 @@
+//! Scheduler for emitting events at a specific time in the future.
+
+use std::collections::VecDeque;
+use std::time::{Duration, Instant};
+
+use glutin::event::Event as GlutinEvent;
+
+use crate::event::Event as AlacrittyEvent;
+
+type Event = GlutinEvent<'static, AlacrittyEvent>;
+
+/// Scheduler tracking all pending timers.
+pub struct Scheduler {
+ timers: VecDeque<Timer>,
+}
+
+impl Default for Scheduler {
+ fn default() -> Self {
+ Self { timers: VecDeque::new() }
+ }
+}
+
+impl Scheduler {
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ /// Process all pending timers.
+ ///
+ /// If there are still timers pending after all ready events have been processed, the closest
+ /// pending deadline will be returned.
+ pub fn update(&mut self, event_queue: &mut Vec<Event>) -> Option<Instant> {
+ let now = Instant::now();
+ while !self.timers.is_empty() && self.timers[0].deadline <= now {
+ if let Some(timer) = self.timers.pop_front() {
+ // Automatically repeat the event.
+ if let Some(interval) = timer.interval {
+ self.schedule(timer.event.clone(), interval, true, timer.id);
+ }
+
+ event_queue.push(timer.event);
+ }
+ }
+
+ self.timers.get(0).map(|timer| timer.deadline)
+ }
+
+ /// Schedule a new event.
+ pub fn schedule(
+ &mut self,
+ event: Event,
+ interval: Duration,
+ repeat: bool,
+ timer_id: TimerId,
+ ) {
+ let deadline = Instant::now() + interval;
+
+ // Get insert position in the schedule.
+ let mut index = self.timers.len();
+ loop {
+ if index == 0 {
+ break;
+ }
+ index -= 1;
+
+ if self.timers[index].deadline < deadline {
+ break;
+ }
+ }
+
+ // Set the automatic event repeat rate.
+ let interval = if repeat { Some(interval) } else { None };
+
+ self.timers.insert(index, Timer { interval, deadline, event, id: timer_id });
+ }
+
+ /// Cancel a scheduled event.
+ pub fn unschedule(&mut self, id: TimerId) -> Option<Event> {
+ let index = self.timers.iter().position(|timer| timer.id == id)?;
+ self.timers.remove(index).map(|timer| timer.event)
+ }
+
+ /// Access a staged event by ID.
+ pub fn get_mut(&mut self, id: TimerId) -> Option<&mut Timer> {
+ self.timers.iter_mut().find(|timer| timer.id == id)
+ }
+}
+
+/// ID uniquely identifying a timer.
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum TimerId {
+ SelectionScrolling,
+}
+
+/// Event scheduled to be emitted at a specific time.
+pub struct Timer {
+ pub deadline: Instant,
+ pub event: Event,
+
+ interval: Option<Duration>,
+ id: TimerId,
+}