diff options
Diffstat (limited to 'alacritty/src/scheduler.rs')
-rw-r--r-- | alacritty/src/scheduler.rs | 102 |
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, +} |