From 06841fd0d72a7d74836ddbcdcf92bc66e2ab2cd8 Mon Sep 17 00:00:00 2001 From: Xevion Date: Wed, 23 Jul 2025 17:38:24 -0500 Subject: [PATCH] refactor: resolve clippy warnings, resolve shared reference with once_cell --- Cargo.lock | 5 ++-- Cargo.toml | 1 + src/audio.rs | 9 +++---- src/debug.rs | 9 ++----- src/edible.rs | 2 +- src/game.rs | 3 +-- src/helper.rs | 11 +++----- src/main.rs | 6 ++--- src/map.rs | 69 ++++++++++++++++++++------------------------------- 9 files changed, 44 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 896e0c5..2ec2150 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -150,9 +150,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "overload" @@ -166,6 +166,7 @@ version = "0.1.0" dependencies = [ "lazy_static", "libc", + "once_cell", "pathfinding", "rand", "sdl2", diff --git a/Cargo.toml b/Cargo.toml index 32fe497..ca1d382 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ sdl2 = { version = "0.38.0", features = ["image", "ttf"] } spin_sleep = "1.3.2" rand = "0.9.2" pathfinding = "4.14" +once_cell = "1.21.3" [target.'cfg(target_os = "windows")'.dependencies.winapi] version = "0.3" diff --git a/src/audio.rs b/src/audio.rs index 76770a7..649aa21 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -34,7 +34,7 @@ impl Audio { // set channel volume for i in 0..channels { - mixer::Channel(i as i32).set_volume(32); + mixer::Channel(i).set_volume(32); } let mixer_context = mixer::init(InitFlag::OGG).expect("Failed to initialize SDL2_mixer"); @@ -44,11 +44,8 @@ impl Audio { .enumerate() .map(|(i, data)| { let rwops = RWops::from_bytes(data) - .expect(&format!("Failed to create RWops for sound {}", i + 1)); - rwops.load_wav().expect(&format!( - "Failed to load sound {} from embedded data", - i + 1 - )) + .unwrap_or_else(|_| panic!("Failed to create RWops for sound {}", i + 1)); + rwops.load_wav().unwrap_or_else(|_| panic!("Failed to load sound {} from embedded data", i + 1)) }) .collect(); diff --git a/src/debug.rs b/src/debug.rs index f3816f2..c65b857 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -17,16 +17,11 @@ pub enum DebugMode { pub struct DebugRenderer; impl DebugRenderer { - pub fn draw_cell(canvas: &mut Canvas, map: &Map, cell: (u32, u32), color: Color) { + pub fn draw_cell(canvas: &mut Canvas, _map: &Map, cell: (u32, u32), color: Color) { let position = Map::cell_to_pixel(cell); canvas.set_draw_color(color); canvas - .draw_rect(sdl2::rect::Rect::new( - position.0 as i32, - position.1 as i32, - 24, - 24, - )) + .draw_rect(sdl2::rect::Rect::new(position.0, position.1, 24, 24)) .expect("Could not draw rectangle"); } diff --git a/src/edible.rs b/src/edible.rs index a778395..9e7ec54 100644 --- a/src/edible.rs +++ b/src/edible.rs @@ -55,7 +55,7 @@ pub fn reconstruct_edibles<'a>( map: Rc>, pellet_sprite: Rc>, power_pellet_sprite: Rc>, - fruit_sprite: Rc>, + _fruit_sprite: Rc>, ) -> Vec> { let mut edibles = Vec::new(); for x in 0..BOARD_WIDTH { diff --git a/src/game.rs b/src/game.rs index 04bb6b1..5bb0cdd 100644 --- a/src/game.rs +++ b/src/game.rs @@ -180,7 +180,6 @@ impl<'a> Game<'a> { // Reset game if keycode == Keycode::R { self.reset(); - return; } } @@ -343,7 +342,7 @@ impl<'a> Game<'a> { // Render the score and high score self.render_text( - &format!("{}UP HIGH SCORE ", lives), + &format!("{lives}UP HIGH SCORE "), (24 * lives_offset + x_offset, y_offset), Color::WHITE, ); diff --git a/src/helper.rs b/src/helper.rs index 3a5bc15..960ec8e 100644 --- a/src/helper.rs +++ b/src/helper.rs @@ -13,16 +13,11 @@ pub fn is_adjacent(a: (u32, u32), b: (u32, u32), diagonal: bool) -> bool { let (ax, ay) = a; let (bx, by) = b; - - // Calculate absolute differences between coordinates - let dx = if ax > bx { ax - bx } else { bx - ax }; - let dy = if ay > by { ay - by } else { by - ay }; - + let dx = ax.abs_diff(bx); + let dy = ay.abs_diff(by); if diagonal { - // For diagonal adjacency: both differences must be ≤ 1 and at least one > 0 - dx <= 1 && dy <= 1 && (dx + dy) > 0 + dx <= 1 && dy <= 1 && (dx != 0 || dy != 0) } else { - // For orthogonal adjacency: exactly one difference must be 1, the other 0 (dx == 1 && dy == 0) || (dx == 0 && dy == 1) } } diff --git a/src/main.rs b/src/main.rs index e70dd06..b71de0e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ use tracing_subscriber::layer::SubscriberExt; #[cfg(windows)] use winapi::{ - shared::{ntdef::NULL, windef::HWND}, + shared::ntdef::NULL, um::{ fileapi::{CreateFileA, OPEN_EXISTING}, handleapi::INVALID_HANDLE_VALUE, @@ -29,13 +29,13 @@ use winapi::{ /// terminal, this function does nothing. #[cfg(windows)] unsafe fn attach_console() { - if GetConsoleWindow() != std::ptr::null_mut() as HWND { + if !std::ptr::eq(GetConsoleWindow(), std::ptr::null_mut()) { return; } if AttachConsole(winapi::um::wincon::ATTACH_PARENT_PROCESS) != 0 { let handle = CreateFileA( - "CONOUT$\0".as_ptr() as *const i8, + c"CONOUT$".as_ptr(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, std::ptr::null_mut(), diff --git a/src/map.rs b/src/map.rs index 3e7ae86..07c08b6 100644 --- a/src/map.rs +++ b/src/map.rs @@ -3,6 +3,7 @@ use rand::seq::IteratorRandom; use crate::constants::{MapTile, BOARD_OFFSET, CELL_SIZE}; use crate::constants::{BOARD_HEIGHT, BOARD_WIDTH}; +use once_cell::sync::OnceCell; use std::collections::{HashSet, VecDeque}; use std::ops::Add; @@ -66,20 +67,8 @@ impl Map { pub fn new(raw_board: [&str; BOARD_HEIGHT as usize]) -> Map { let mut map = [[MapTile::Empty; BOARD_HEIGHT as usize]; BOARD_WIDTH as usize]; - for y in 0..BOARD_HEIGHT as usize { - let line = raw_board[y]; - - for x in 0..BOARD_WIDTH as usize { - if x >= line.len() { - break; - } - - let i = (y * (BOARD_WIDTH as usize) + x) as usize; - let character = line - .chars() - .nth(x as usize) - .unwrap_or_else(|| panic!("Could not get character at {} = ({}, {})", i, x, y)); - + for (y, line) in raw_board.iter().enumerate().take(BOARD_HEIGHT as usize) { + for (x, character) in line.chars().enumerate().take(BOARD_WIDTH as usize) { let tile = match character { '#' => MapTile::Wall, '.' => MapTile::Pellet, @@ -90,25 +79,29 @@ impl Map { MapTile::StartingPosition(c.to_digit(10).unwrap() as u8) } '=' => MapTile::Empty, - _ => panic!("Unknown character in board: {}", character), + _ => panic!("Unknown character in board: {character}"), }; - - map[x as usize][y as usize] = tile; + map[x][y] = tile; } } Map { current: map, - default: map.clone(), + default: map, } } /// Resets the map to its original state. pub fn reset(&mut self) { // Restore the map to its original state - for x in 0..BOARD_WIDTH as usize { - for y in 0..BOARD_HEIGHT as usize { - self.current[x][y] = self.default[x][y]; + for (x, col) in self + .current + .iter_mut() + .enumerate() + .take(BOARD_WIDTH as usize) + { + for (y, cell) in col.iter_mut().enumerate().take(BOARD_HEIGHT as usize) { + *cell = self.default[x][y]; } } } @@ -163,19 +156,19 @@ impl Map { /// This is computed once using a flood fill from a random pellet, and then cached. pub fn get_valid_playable_positions(&mut self) -> &Vec { use MapTile::*; - static mut CACHE: Option> = None; - // SAFETY: This is only mutated once, and only in this function. - unsafe { - if let Some(ref cached) = CACHE { - return cached; - } + static CACHE: OnceCell> = OnceCell::new(); + if let Some(cached) = CACHE.get() { + return cached; } // Find a random starting pellet let mut pellet_positions = vec![]; - for x in 0..BOARD_WIDTH as u32 { - for y in 0..BOARD_HEIGHT as u32 { - match self.current[x as usize][y as usize] { - Pellet | PowerPellet => pellet_positions.push(Position { x, y }), + for (x, col) in self.current.iter().enumerate().take(BOARD_WIDTH as usize) { + for (y, &cell) in col.iter().enumerate().take(BOARD_HEIGHT as usize) { + match cell { + Pellet | PowerPellet => pellet_positions.push(Position { + x: x as u32, + y: y as u32, + }), _ => {} } } @@ -191,15 +184,12 @@ impl Map { queue.push_back(start); while let Some(pos) = queue.pop_front() { - // Mark visited, skip if already visited if !visited.insert(pos) { continue; } - // Check if the current tile is valid match self.current[pos.x as usize][pos.y as usize] { Empty | Pellet | PowerPellet => { - // Valid, continue flood for offset in [ SignedPosition { x: -1, y: 0 }, SignedPosition { x: 1, y: 0 }, @@ -207,7 +197,7 @@ impl Map { SignedPosition { x: 0, y: 1 }, ] { let neighbor = pos + offset; - if neighbor.x < BOARD_WIDTH as u32 && neighbor.y < BOARD_HEIGHT as u32 { + if neighbor.x < BOARD_WIDTH && neighbor.y < BOARD_HEIGHT { let neighbor_tile = self.current[neighbor.x as usize][neighbor.y as usize]; if matches!(neighbor_tile, Empty | Pellet | PowerPellet) { @@ -216,16 +206,11 @@ impl Map { } } } - StartingPosition(_) | Wall | Tunnel => { - // Not valid, do not continue - } + StartingPosition(_) | Wall | Tunnel => {} } } let mut result: Vec = visited.into_iter().collect(); result.sort_unstable(); - unsafe { - CACHE = Some(result); - CACHE.as_ref().unwrap() - } + CACHE.get_or_init(|| result) } }