From 0ee91f6d77571260580c6e37153a847fac8fb72f Mon Sep 17 00:00:00 2001 From: Oxore Date: Sun, 30 Jul 2023 19:41:13 +0300 Subject: Impl event loop using nonblock read and sleep --- src/main.rs | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 245c2b1..fc8c0a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ extern crate termios; use rand::Rng; -use std::io::Read; +use std::time::Duration; +use nonblock::NonBlockingReader; const FIELD_COLS: usize = 10; const FIELD_ROWS_VISIBLE: usize = 20; @@ -18,6 +19,12 @@ const CELLS_S: [i8; FIGURE_SIZE] = [0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, const CELLS_T: [i8; FIGURE_SIZE] = [0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0]; const CELLS_Z: [i8; FIGURE_SIZE] = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0]; +enum StepResult { + StateChanged, + Quit, + Noop, +} + #[derive(Clone)] #[derive(Debug)] enum FigureKind { @@ -165,11 +172,13 @@ impl Game { self.x = 0; self.y = 0; } - fn step(&mut self, fd: &mut std::io::Stdin) -> Option<()> { - let mut r: [u8;1]=[0]; - fd.read(&mut r[..]).unwrap(); - match r[0] as char { - 'q' => return None, + fn step(&mut self, c_optional: Option) -> StepResult { + if let None = c_optional { + return StepResult::Noop; + } + let c = c_optional.unwrap(); + match c { + 'q' => return StepResult::Quit, ' ' => { if !self.field.has_collision(&self.figure, self.x, self.y) { self.place() @@ -212,7 +221,7 @@ impl Game { } _ => {}, } - Some(()) + StepResult::StateChanged } } @@ -266,12 +275,23 @@ fn main() { clear_screen(); let mut game = Game::default(); display_game(&game); - let mut stdin = std::io::stdin(); - loop { - if let None = game.step(&mut stdin) { - break; + let mut noblock_stdin = NonBlockingReader::from_fd(std::io::stdin()).unwrap(); + 'outer: while !noblock_stdin.is_eof() { + let mut buf = String::new(); + noblock_stdin.read_available_to_string(&mut buf).unwrap(); + let mut changed = false; + for c in buf.bytes() { + let result = game.step(Some(c as char)); + match result { + StepResult::StateChanged => changed = true, + StepResult::Noop => {}, + StepResult::Quit => break 'outer, + } + } + if changed { + display_game(&game); } - display_game(&game); + std::thread::sleep(Duration::from_millis(1)); } termios::tcsetattr(0, termios::TCSADRAIN, &termios_state_initial).unwrap(); } -- cgit v1.2.3