summaryrefslogtreecommitdiff
path: root/alacritty/src/scheduler.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/scheduler.rs')
-rw-r--r--alacritty/src/scheduler.rs69
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);
}
}