-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathevent.rs
More file actions
114 lines (93 loc) · 3.18 KB
/
event.rs
File metadata and controls
114 lines (93 loc) · 3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crossterm::event::{self, Event};
use miette::miette;
use std::time::Duration;
use std::{sync::mpsc, thread};
pub struct EventHandler {
receiver: mpsc::Receiver<Event>,
}
impl EventHandler {
pub fn new(tick_rate: Duration) -> Self {
let (sender, receiver) = mpsc::channel();
thread::spawn(move || {
let mut last_tick = std::time::Instant::now();
loop {
let timeout = tick_rate
.checked_sub(last_tick.elapsed())
.unwrap_or(Duration::from_secs(0));
if event::poll(timeout).unwrap()
&& let Ok(event) = event::read()
&& sender.send(event).is_err()
{
break;
}
if last_tick.elapsed() >= tick_rate {
last_tick = std::time::Instant::now();
}
}
});
Self { receiver }
}
}
pub trait EventHandlerExt {
fn next(&self) -> miette::Result<Option<Event>>;
}
impl EventHandlerExt for EventHandler {
fn next(&self) -> miette::Result<Option<Event>> {
match self.receiver.try_recv() {
Ok(event) => Ok(Some(event)),
Err(mpsc::TryRecvError::Empty) => Ok(None),
Err(mpsc::TryRecvError::Disconnected) => Err(miette!("Event channel disconnected")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_event_handler_creation() {
let handler = EventHandler::new(Duration::from_millis(100));
// Verify that the handler can be created without panicking
assert!(handler.receiver.try_recv().is_err()); // Should be empty initially
}
#[test]
fn test_next_returns_none_when_no_events() {
let handler = EventHandler::new(Duration::from_millis(100));
let result = handler.next().unwrap();
assert!(result.is_none());
}
#[test]
fn test_next_handles_disconnected_channel() {
let (_, receiver) = mpsc::channel();
let handler = EventHandler { receiver };
// Drop the sender to simulate disconnection
drop(handler.receiver);
// Create a new handler with a disconnected receiver
let (sender, receiver) = mpsc::channel();
drop(sender); // Disconnect immediately
let handler = EventHandler { receiver };
let result = handler.next();
assert!(result.is_err());
assert!(
result
.unwrap_err()
.to_string()
.contains("Event channel disconnected")
);
}
#[test]
fn test_event_handler_with_different_tick_rates() {
let fast_handler = EventHandler::new(Duration::from_millis(10));
let slow_handler = EventHandler::new(Duration::from_millis(1000));
// Both should be created successfully
assert!(fast_handler.next().unwrap().is_none());
assert!(slow_handler.next().unwrap().is_none());
}
#[test]
fn test_multiple_next_calls() {
let handler = EventHandler::new(Duration::from_millis(50));
// Multiple calls should not panic
for _ in 0..5 {
let _ = handler.next();
}
}
}