Skip to content

Commit 0bc73ce

Browse files
Merge branch 'master' into try_read
2 parents 578463b + 2ba0160 commit 0bc73ce

File tree

12 files changed

+105
-132
lines changed

12 files changed

+105
-132
lines changed

src/cursor/sys/unix.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use std::{
44
};
55

66
use crate::{
7-
event::{filter::CursorPositionFilter, poll_internal, read_internal, InternalEvent},
7+
event::{
8+
filter::CursorPositionFilter,
9+
internal::{self, InternalEvent},
10+
},
811
terminal::{disable_raw_mode, enable_raw_mode, sys::is_raw_mode_enabled},
912
};
1013

@@ -36,10 +39,10 @@ fn read_position_raw() -> io::Result<(u16, u16)> {
3639
stdout.flush()?;
3740

3841
loop {
39-
match poll_internal(Some(Duration::from_millis(2000)), &CursorPositionFilter) {
42+
match internal::poll(Some(Duration::from_millis(2000)), &CursorPositionFilter) {
4043
Ok(true) => {
4144
if let Ok(InternalEvent::CursorPosition(x, y)) =
42-
read_internal(&CursorPositionFilter)
45+
internal::read(&CursorPositionFilter)
4346
{
4447
return Ok((x, y));
4548
}

src/event.rs

Lines changed: 5 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
//! them (`event-*`).
120120
121121
pub(crate) mod filter;
122+
pub(crate) mod internal;
122123
pub(crate) mod read;
123124
pub(crate) mod source;
124125
#[cfg(feature = "event-stream")]
@@ -131,37 +132,13 @@ use derive_more::derive::IsVariant;
131132
#[cfg(feature = "event-stream")]
132133
pub use stream::EventStream;
133134

134-
use crate::event::{
135-
filter::{EventFilter, Filter},
136-
read::InternalEventReader,
137-
timeout::PollTimeout,
138-
};
139-
use crate::{csi, Command};
140-
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
135+
use crate::{csi, event::filter::EventFilter, Command};
141136
use std::fmt::{self, Display};
142137
use std::time::Duration;
143138

144139
use bitflags::bitflags;
145140
use std::hash::{Hash, Hasher};
146141

147-
/// Static instance of `InternalEventReader`.
148-
/// This needs to be static because there can be one event reader.
149-
static INTERNAL_EVENT_READER: Mutex<Option<InternalEventReader>> = parking_lot::const_mutex(None);
150-
151-
pub(crate) fn lock_internal_event_reader() -> MappedMutexGuard<'static, InternalEventReader> {
152-
MutexGuard::map(INTERNAL_EVENT_READER.lock(), |reader| {
153-
reader.get_or_insert_with(InternalEventReader::default)
154-
})
155-
}
156-
fn try_lock_internal_event_reader_for(
157-
duration: Duration,
158-
) -> Option<MappedMutexGuard<'static, InternalEventReader>> {
159-
Some(MutexGuard::map(
160-
INTERNAL_EVENT_READER.try_lock_for(duration)?,
161-
|reader| reader.get_or_insert_with(InternalEventReader::default),
162-
))
163-
}
164-
165142
/// Checks if there is an [`Event`](enum.Event.html) available.
166143
///
167144
/// Returns `Ok(true)` if an [`Event`](enum.Event.html) is available otherwise it returns `Ok(false)`.
@@ -202,7 +179,7 @@ fn try_lock_internal_event_reader_for(
202179
/// }
203180
/// ```
204181
pub fn poll(timeout: Duration) -> std::io::Result<bool> {
205-
poll_internal(Some(timeout), &EventFilter)
182+
internal::poll(Some(timeout), &EventFilter)
206183
}
207184

208185
/// Reads a single [`Event`](enum.Event.html).
@@ -247,78 +224,13 @@ pub fn poll(timeout: Duration) -> std::io::Result<bool> {
247224
/// }
248225
/// ```
249226
pub fn read() -> std::io::Result<Event> {
250-
match read_internal(&EventFilter)? {
251-
InternalEvent::Event(event) => Ok(event),
227+
match internal::read(&EventFilter)? {
228+
internal::InternalEvent::Event(event) => Ok(event),
252229
#[cfg(unix)]
253230
_ => unreachable!(),
254231
}
255232
}
256233

257-
/// Attempts to read a single [`Event`](enum.Event.html) without blocking the thread.
258-
/// If no event is found, `None` is returned.
259-
///
260-
/// # Examples
261-
///
262-
/// ```no_run
263-
/// use crossterm::event::{try_read, poll};
264-
/// use std::{io, time::Duration};
265-
///
266-
/// fn print_all_events() -> io::Result<bool> {
267-
/// loop {
268-
/// if poll(Duration::from_millis(100))? {
269-
/// // Fetch *all* available events at once
270-
/// while let Some(event) = try_read() {
271-
/// // ...
272-
/// }
273-
/// }
274-
/// }
275-
/// }
276-
/// ```
277-
pub fn try_read() -> Option<Event> {
278-
match try_read_internal(&EventFilter) {
279-
Some(InternalEvent::Event(event)) => Some(event),
280-
None => None,
281-
#[cfg(unix)]
282-
_ => unreachable!(),
283-
}
284-
}
285-
286-
/// Polls to check if there are any `InternalEvent`s that can be read within the given duration.
287-
pub(crate) fn poll_internal<F>(timeout: Option<Duration>, filter: &F) -> std::io::Result<bool>
288-
where
289-
F: Filter,
290-
{
291-
let (mut reader, timeout) = if let Some(timeout) = timeout {
292-
let poll_timeout = PollTimeout::new(Some(timeout));
293-
if let Some(reader) = try_lock_internal_event_reader_for(timeout) {
294-
(reader, poll_timeout.leftover())
295-
} else {
296-
return Ok(false);
297-
}
298-
} else {
299-
(lock_internal_event_reader(), None)
300-
};
301-
reader.poll(timeout, filter)
302-
}
303-
304-
/// Reads a single `InternalEvent`.
305-
pub(crate) fn read_internal<F>(filter: &F) -> std::io::Result<InternalEvent>
306-
where
307-
F: Filter,
308-
{
309-
let mut reader = lock_internal_event_reader();
310-
reader.read(filter)
311-
}
312-
313-
/// Reads a single `InternalEvent`. Non-blocking.
314-
pub(crate) fn try_read_internal<F>(filter: &F) -> Option<InternalEvent>
315-
where
316-
F: Filter,
317-
{
318-
let mut reader = lock_internal_event_reader();
319-
reader.try_read(filter)
320-
}
321-
322234
bitflags! {
323235
/// Represents special flags that tell compatible terminals to add extra information to keyboard events.
324236
///
@@ -1505,25 +1417,6 @@ impl Display for KeyCode {
15051417
}
15061418
}
15071419

1508-
/// An internal event.
1509-
///
1510-
/// Encapsulates publicly available `Event` with additional internal
1511-
/// events that shouldn't be publicly available to the crate users.
1512-
#[derive(Debug, PartialOrd, PartialEq, Hash, Clone, Eq)]
1513-
pub(crate) enum InternalEvent {
1514-
/// An event.
1515-
Event(Event),
1516-
/// A cursor position (`col`, `row`).
1517-
#[cfg(unix)]
1518-
CursorPosition(u16, u16),
1519-
/// The progressive keyboard enhancement flags enabled by the terminal.
1520-
#[cfg(unix)]
1521-
KeyboardEnhancementFlags(KeyboardEnhancementFlags),
1522-
/// Attributes and architectural class of the terminal.
1523-
#[cfg(unix)]
1524-
PrimaryDeviceAttributes,
1525-
}
1526-
15271420
#[cfg(test)]
15281421
mod tests {
15291422
use std::collections::hash_map::DefaultHasher;

src/event/filter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::event::InternalEvent;
1+
use crate::event::internal::InternalEvent;
22

33
/// Interface for filtering an `InternalEvent`.
44
pub(crate) trait Filter: Send + Sync + 'static {

src/event/internal.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use std::time::Duration;
2+
3+
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
4+
5+
#[cfg(unix)]
6+
use crate::event::KeyboardEnhancementFlags;
7+
use crate::event::{filter::Filter, read::InternalEventReader, timeout::PollTimeout, Event};
8+
9+
/// Static instance of `InternalEventReader`.
10+
/// This needs to be static because there can be one event reader.
11+
static EVENT_READER: Mutex<Option<InternalEventReader>> = parking_lot::const_mutex(None);
12+
13+
pub(crate) fn lock_event_reader() -> MappedMutexGuard<'static, InternalEventReader> {
14+
MutexGuard::map(EVENT_READER.lock(), |reader| {
15+
reader.get_or_insert_with(InternalEventReader::default)
16+
})
17+
}
18+
19+
fn try_lock_event_reader_for(
20+
duration: Duration,
21+
) -> Option<MappedMutexGuard<'static, InternalEventReader>> {
22+
Some(MutexGuard::map(
23+
EVENT_READER.try_lock_for(duration)?,
24+
|reader| reader.get_or_insert_with(InternalEventReader::default),
25+
))
26+
}
27+
28+
/// Polls to check if there are any `InternalEvent`s that can be read within the given duration.
29+
pub(crate) fn poll<F>(timeout: Option<Duration>, filter: &F) -> std::io::Result<bool>
30+
where
31+
F: Filter,
32+
{
33+
let (mut reader, timeout) = if let Some(timeout) = timeout {
34+
let poll_timeout = PollTimeout::new(Some(timeout));
35+
if let Some(reader) = try_lock_event_reader_for(timeout) {
36+
(reader, poll_timeout.leftover())
37+
} else {
38+
return Ok(false);
39+
}
40+
} else {
41+
(lock_event_reader(), None)
42+
};
43+
reader.poll(timeout, filter)
44+
}
45+
46+
/// Reads a single `InternalEvent`.
47+
pub(crate) fn read<F>(filter: &F) -> std::io::Result<InternalEvent>
48+
where
49+
F: Filter,
50+
{
51+
let mut reader = lock_event_reader();
52+
reader.read(filter)
53+
}
54+
55+
/// An internal event.
56+
///
57+
/// Encapsulates publicly available `Event` with additional internal
58+
/// events that shouldn't be publicly available to the crate users.
59+
#[derive(Debug, PartialOrd, PartialEq, Hash, Clone, Eq)]
60+
pub(crate) enum InternalEvent {
61+
/// An event.
62+
Event(Event),
63+
/// A cursor position (`col`, `row`).
64+
#[cfg(unix)]
65+
CursorPosition(u16, u16),
66+
/// The progressive keyboard enhancement flags enabled by the terminal.
67+
#[cfg(unix)]
68+
KeyboardEnhancementFlags(KeyboardEnhancementFlags),
69+
/// Attributes and architectural class of the terminal.
70+
#[cfg(unix)]
71+
PrimaryDeviceAttributes,
72+
}

src/event/read.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use crate::event::source::unix::UnixInternalEventSource;
66
use crate::event::source::windows::WindowsEventSource;
77
#[cfg(feature = "event-stream")]
88
use crate::event::sys::Waker;
9-
use crate::event::{filter::Filter, source::EventSource, timeout::PollTimeout, InternalEvent};
9+
use crate::event::{
10+
filter::Filter, internal::InternalEvent, source::EventSource, timeout::PollTimeout,
11+
};
1012

1113
/// Can be used to read `InternalEvent`s.
1214
pub(crate) struct InternalEventReader {

src/event/source.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::{io, time::Duration};
22

3+
use super::internal::InternalEvent;
34
#[cfg(feature = "event-stream")]
45
use super::sys::Waker;
5-
use super::InternalEvent;
66

77
#[cfg(unix)]
88
pub(crate) mod unix;

src/event/source/unix/mio.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use signal_hook_mio::v1_0::Signals;
66
#[cfg(feature = "event-stream")]
77
use crate::event::sys::Waker;
88
use crate::event::{
9-
source::EventSource, sys::unix::parse::parse_event, timeout::PollTimeout, Event, InternalEvent,
9+
internal::InternalEvent, source::EventSource, sys::unix::parse::parse_event,
10+
timeout::PollTimeout, Event,
1011
};
1112
use crate::terminal::sys::file_descriptor::{tty_fd, FileDesc};
1213

src/event/source/unix/tty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use filedescriptor::{poll, pollfd, POLLIN};
1313

1414
#[cfg(feature = "event-stream")]
1515
use crate::event::sys::Waker;
16-
use crate::event::{source::EventSource, sys::unix::parse::parse_event, InternalEvent};
16+
use crate::event::{internal::InternalEvent, source::EventSource, sys::unix::parse::parse_event};
1717
use crate::terminal::sys::file_descriptor::{tty_fd, FileDesc};
1818

1919
/// Holds a prototypical Waker and a receiver we can wait on when doing select().

src/event/source/windows.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ use crate::event::{
1010
#[cfg(feature = "event-stream")]
1111
use crate::event::sys::Waker;
1212
use crate::event::{
13+
internal::InternalEvent,
1314
source::EventSource,
1415
sys::windows::parse::{handle_key_event, handle_mouse_event},
1516
timeout::PollTimeout,
16-
InternalEvent,
1717
};
1818

1919
pub(crate) struct WindowsEventSource {

src/event/stream.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ use std::{
1414
use futures_core::stream::Stream;
1515

1616
use crate::event::{
17-
filter::EventFilter, lock_internal_event_reader, poll_internal, read_internal, sys::Waker,
18-
Event, InternalEvent,
17+
filter::EventFilter,
18+
internal::{self, InternalEvent},
19+
sys::Waker,
20+
Event,
1921
};
2022

2123
/// A stream of `Result<Event>`.
@@ -44,7 +46,7 @@ impl Default for EventStream {
4446
thread::spawn(move || {
4547
while let Ok(task) = receiver.recv() {
4648
loop {
47-
if let Ok(true) = poll_internal(None, &EventFilter) {
49+
if let Ok(true) = internal::poll(None, &EventFilter) {
4850
break;
4951
}
5052

@@ -59,7 +61,7 @@ impl Default for EventStream {
5961
});
6062

6163
EventStream {
62-
poll_internal_waker: lock_internal_event_reader().waker(),
64+
poll_internal_waker: internal::lock_event_reader().waker(),
6365
stream_wake_task_executed: Arc::new(AtomicBool::new(false)),
6466
stream_wake_task_should_shutdown: Arc::new(AtomicBool::new(false)),
6567
task_sender,
@@ -102,8 +104,8 @@ impl Stream for EventStream {
102104
type Item = io::Result<Event>;
103105

104106
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
105-
let result = match poll_internal(Some(Duration::from_secs(0)), &EventFilter) {
106-
Ok(true) => match read_internal(&EventFilter) {
107+
let result = match internal::poll(Some(Duration::from_secs(0)), &EventFilter) {
108+
Ok(true) => match internal::read(&EventFilter) {
107109
Ok(InternalEvent::Event(event)) => Poll::Ready(Some(Ok(event))),
108110
Err(e) => Poll::Ready(Some(Err(e))),
109111
#[cfg(unix)]

0 commit comments

Comments
 (0)