use super::Anthilus;
use crate::{
logging::log,
state::{
Message,
input::{Input, exit_raw_mode, raw_mode, set_stdin_nonblocking},
},
};
use std::{
io::{Write, stdout},
time::{Duration, Instant},
};
impl Anthilus {
pub fn event_loop(&mut self) {
log("Anthilus::event_loop(): Starting event loop");
raw_mode();
let mut info = RuntimeInfo::new();
set_stdin_nonblocking();
print!("\x1b[?25l\x1b[?1049h");
loop {
print!("\x1b[H\x1b[2J\x1b[3J");
if let Some(text) = self.render() {
print!("{text}");
} else {
break;
}
let _ = stdout().flush();
let input = match loop {
if let Ok(event) = Input::get() {
break Some(event);
} else if let Some(event) = repopulate_check(&mut info) {
self.update(event);
break None;
}
} {
Some(event) => event,
None => continue,
};
let event = Message::Input(input);
self.update(event);
}
print!("\x1b[?1049l\x1b[?25h");
log("State<T>::event_loop(): Ending event loop");
exit_raw_mode();
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct RuntimeInfo {
last_instant: Instant,
}
impl RuntimeInfo {
fn new() -> Self {
Self {
last_instant: Instant::now(),
}
}
pub fn elapsed(&self) -> Duration {
self.last_instant.elapsed()
}
pub fn reset_clock(&mut self) {
self.last_instant = Instant::now();
}
}
pub fn repopulate_check(info: &mut RuntimeInfo) -> Option<Message> {
if info.elapsed().as_secs_f64() > 0.25 {
info.reset_clock();
Some(Message::Repopulate)
} else {
None
}
}