diff options
Diffstat (limited to 'alacritty/src/scheduler.rs')
-rw-r--r-- | alacritty/src/scheduler.rs | 69 |
1 files changed, 37 insertions, 32 deletions
diff --git a/alacritty/src/scheduler.rs b/alacritty/src/scheduler.rs index 5e454141..924f5904 100644 --- a/alacritty/src/scheduler.rs +++ b/alacritty/src/scheduler.rs @@ -3,15 +3,27 @@ use std::collections::VecDeque; use std::time::{Duration, Instant}; -use glutin::event::Event as GlutinEvent; +use glutin::event_loop::EventLoopProxy; +use glutin::window::WindowId; -use crate::event::Event as AlacrittyEvent; - -type Event = GlutinEvent<'static, AlacrittyEvent>; +use crate::event::Event; /// ID uniquely identifying a timer. #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum TimerId { +pub struct TimerId { + topic: Topic, + window_id: WindowId, +} + +impl TimerId { + pub fn new(topic: Topic, window_id: WindowId) -> Self { + Self { topic, window_id } + } +} + +/// Available timer topics. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum Topic { SelectionScrolling, DelayedSearch, BlinkCursor, @@ -21,33 +33,29 @@ pub enum TimerId { pub struct Timer { pub deadline: Instant, pub event: Event, + pub id: TimerId, interval: Option<Duration>, - id: TimerId, } /// Scheduler tracking all pending timers. pub struct Scheduler { timers: VecDeque<Timer>, -} - -impl Default for Scheduler { - fn default() -> Self { - Self { timers: VecDeque::new() } - } + event_proxy: EventLoopProxy<Event>, } impl Scheduler { - pub fn new() -> Self { - Self::default() + pub fn new(event_proxy: EventLoopProxy<Event>) -> Self { + Self { timers: VecDeque::new(), event_proxy } } /// 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> { + pub fn update(&mut self) -> 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. @@ -55,7 +63,7 @@ impl Scheduler { self.schedule(timer.event.clone(), interval, true, timer.id); } - event_queue.push(timer.event); + let _ = self.event_proxy.send_event(timer.event); } } @@ -67,17 +75,11 @@ impl Scheduler { 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; - } - } + let index = self + .timers + .iter() + .position(|timer| timer.deadline > deadline) + .unwrap_or_else(|| self.timers.len()); // Set the automatic event repeat rate. let interval = if repeat { Some(interval) } else { None }; @@ -86,9 +88,9 @@ impl Scheduler { } /// Cancel a scheduled event. - pub fn unschedule(&mut self, id: TimerId) -> Option<Event> { + pub fn unschedule(&mut self, id: TimerId) -> Option<Timer> { let index = self.timers.iter().position(|timer| timer.id == id)?; - self.timers.remove(index).map(|timer| timer.event) + self.timers.remove(index) } /// Check if a timer is already scheduled. @@ -96,8 +98,11 @@ impl Scheduler { self.timers.iter().any(|timer| timer.id == id) } - /// 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) + /// Remove all timers scheduled for a window. + /// + /// This must be called when a window is removed to ensure that timers on intervals do not + /// stick around forever and cause a memory leak. + pub fn unschedule_window(&mut self, window_id: WindowId) { + self.timers.retain(|timer| timer.id.window_id != window_id); } } |