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 --- Cargo.lock | 10 ++++++++++ Cargo.toml | 1 + src/main.rs | 44 ++++++++++++++++++++++++++++++++------------ 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0eafa82..0d52afd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,6 +25,15 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +[[package]] +name = "nonblock" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51c7a4f22e5f2e2bd805d6ab56f1ae87eb1815673e1b452048896fb687a8a3d4" +dependencies = [ + "libc", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -35,6 +44,7 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" name = "puzzle" version = "0.1.0" dependencies = [ + "nonblock", "rand", "termios", ] diff --git a/Cargo.toml b/Cargo.toml index 3be4420..624495f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,4 @@ edition = "2021" [dependencies] rand = "0.8.5" termios = "0.3.3" +nonblock = "0.2.0" 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