use crate::{Duration, EventKind, Linux, LinuxResult, TermLinux, TermPollPolicy, is};
impl TermLinux {
#[inline]
pub fn poll_event(&mut self) -> LinuxResult<Option<EventKind>> {
self.poll_event_immediate_impl()
}
#[inline]
pub fn poll_event_with(&mut self, policy: TermPollPolicy) -> LinuxResult<Option<EventKind>> {
match policy {
TermPollPolicy::Pending => self.poll_event_pending(),
TermPollPolicy::Immediate => self.poll_event(),
TermPollPolicy::Timeout(timeout) => self.poll_event_timeout(timeout),
TermPollPolicy::Blocking => self.wait_event().map(Some),
}
}
#[inline]
pub fn poll_event_pending(&mut self) -> LinuxResult<Option<EventKind>> {
loop {
is! { let Some(ev) = self.poll_buffered_event(), return Ok(Some(ev)) }
is! { self.input_buf.refill_from_stdin()? == 0, return Ok(None) }
}
}
#[inline]
fn poll_event_immediate_impl(&mut self) -> LinuxResult<Option<EventKind>> {
loop {
is! { let Some(ev) = self.poll_buffered_event(), return Ok(Some(ev)) }
is! { self.input_buf.refill_from_stdin()? == 0, return Ok(self.parser.flush_escape()) }
}
}
#[inline]
pub fn poll_event_timeout(&mut self, timeout: Duration) -> LinuxResult<Option<EventKind>> {
loop {
is! { let Some(ev) = self.poll_buffered_event(), return Ok(Some(ev)) }
is! { self.input_buf.refill_from_stdin()? != 0, continue }
is! { !self.parser.is_pending_escape(), return Ok(None) }
Linux::sleep(timeout)?;
is! { self.input_buf.refill_from_stdin()? != 0, continue }
return Ok(self.parser.flush_escape());
}
}
#[inline]
pub fn wait_event(&mut self) -> LinuxResult<EventKind> {
loop {
is! { let Some(ev) = self.poll_event()?, return Ok(ev) }
let byte = Linux::get_byte()?;
is! { let Some(ev) = self.parser.feed(byte), return Ok(ev) }
}
}
#[inline]
fn poll_buffered_event(&mut self) -> Option<EventKind> {
while let Some(byte) = self.input_buf.pop_front() {
is! { let Some(ev) = self.parser.feed(byte), return Some(ev) }
}
None
}
}