refactor: remove all unused/broken tests, remove many now unused types/functions

This commit is contained in:
2025-08-15 09:24:42 -05:00
parent 242da2e263
commit 3388d77ec5
18 changed files with 92 additions and 890 deletions

View File

@@ -17,7 +17,7 @@ pub struct App {
pub game: Game,
last_tick: Instant,
focused: bool,
cursor_pos: Vec2,
_cursor_pos: Vec2,
}
impl App {
@@ -46,7 +46,7 @@ impl App {
.build()
.map_err(|e| GameError::Sdl(e.to_string()))?;
let mut canvas = Box::leak(Box::new(
let canvas = Box::leak(Box::new(
window
.into_canvas()
.accelerated()
@@ -74,7 +74,7 @@ impl App {
game,
focused: true,
last_tick: Instant::now(),
cursor_pos: Vec2::ZERO,
_cursor_pos: Vec2::ZERO,
})
}

View File

@@ -5,4 +5,3 @@ pub mod graph;
pub mod item;
pub mod pacman;
pub mod r#trait;
pub mod traversal;

View File

@@ -1,159 +0,0 @@
use crate::ecs::components::Position;
use crate::error::GameResult;
use super::direction::Direction;
use super::graph::{Edge, Graph};
/// Manages an entity's movement through the graph.
///
/// A `Traverser` encapsulates the state of an entity's position and direction,
/// providing a way to advance along the graph's paths based on a given distance.
/// It also handles direction changes, buffering the next intended direction.
pub struct Traverser {
/// The current position of the traverser in the graph.
pub position: Position,
/// The current direction of movement.
pub direction: Direction,
/// Buffered direction change with remaining frame count for timing.
///
/// The `u8` value represents the number of frames remaining before
/// the buffered direction expires. This allows for responsive controls
/// by storing direction changes for a limited time.
pub next_direction: Option<(Direction, u8)>,
}
impl Traverser {
/// Sets the next direction for the traverser to take.
///
/// The direction is buffered and will be applied at the next opportunity,
/// typically when the traverser reaches a new node. This allows for responsive
/// controls, as the new direction is stored for a limited time.
pub fn set_next_direction(&mut self, new_direction: Direction) {
if self.direction != new_direction {
self.next_direction = Some((new_direction, 30));
}
}
/// Advances the traverser along the graph by a specified distance.
///
/// This method updates the traverser's position based on its current state
/// and the distance to travel.
///
/// - If at a node, it checks for a buffered direction to start moving.
/// - If between nodes, it moves along the current edge.
/// - If it reaches a node, it attempts to transition to a new edge based on
/// the buffered direction or by continuing straight.
/// - If no valid move is possible, it stops at the node.
///
/// Returns an error if the movement is invalid (e.g., trying to move in an impossible direction).
pub fn advance<F>(&mut self, graph: &Graph, distance: f32, can_traverse: &F) -> GameResult<()>
where
F: Fn(Edge) -> bool,
{
// Decrement the remaining frames for the next direction
if let Some((direction, remaining)) = self.next_direction {
if remaining > 0 {
self.next_direction = Some((direction, remaining - 1));
} else {
self.next_direction = None;
}
}
match self.position {
Position::AtNode(node_id) => {
// We're not moving, but a buffered direction is available.
if let Some((next_direction, _)) = self.next_direction {
if let Some(edge) = graph.find_edge_in_direction(node_id, next_direction) {
if can_traverse(edge) {
// Start moving in that direction
self.position = Position::BetweenNodes {
from: node_id,
to: edge.target,
traversed: distance.max(0.0),
};
self.direction = next_direction;
} else {
return Err(crate::error::GameError::Entity(crate::error::EntityError::InvalidMovement(
format!(
"Cannot traverse edge from {} to {} in direction {:?}",
node_id, edge.target, next_direction
),
)));
}
} else {
return Err(crate::error::GameError::Entity(crate::error::EntityError::InvalidMovement(
format!("No edge found in direction {:?} from node {}", next_direction, node_id),
)));
}
self.next_direction = None; // Consume the buffered direction regardless of whether we started moving with it
}
}
Position::BetweenNodes { from, to, traversed } => {
// There is no point in any of the next logic if we don't travel at all
if distance <= 0.0 {
return Ok(());
}
let edge = graph.find_edge(from, to).ok_or_else(|| {
crate::error::GameError::Entity(crate::error::EntityError::InvalidMovement(format!(
"Inconsistent state: Traverser is on a non-existent edge from {} to {}.",
from, to
)))
})?;
let new_traversed = traversed + distance;
if new_traversed < edge.distance {
// Still on the same edge, just update the distance.
self.position = Position::BetweenNodes {
from,
to,
traversed: new_traversed,
};
} else {
let overflow = new_traversed - edge.distance;
let mut moved = false;
// If we buffered a direction, try to find an edge in that direction
if let Some((next_dir, _)) = self.next_direction {
if let Some(edge) = graph.find_edge_in_direction(to, next_dir) {
if can_traverse(edge) {
self.position = Position::BetweenNodes {
from: to,
to: edge.target,
traversed: overflow,
};
self.direction = next_dir; // Remember our new direction
self.next_direction = None; // Consume the buffered direction
moved = true;
}
}
}
// If we didn't move, try to continue in the current direction
if !moved {
if let Some(edge) = graph.find_edge_in_direction(to, self.direction) {
if can_traverse(edge) {
self.position = Position::BetweenNodes {
from: to,
to: edge.target,
traversed: overflow,
};
} else {
self.position = Position::AtNode(to);
self.next_direction = None;
}
} else {
self.position = Position::AtNode(to);
self.next_direction = None;
}
}
}
}
}
Ok(())
}
}

View File

@@ -1,8 +1,5 @@
use sdl2::rect::Rect;
use sdl2::render::{Canvas, RenderTarget};
use crate::error::{AnimatedTextureError, GameError, GameResult, TextureError};
use crate::texture::sprite::{AtlasTile, SpriteAtlas};
use crate::texture::sprite::AtlasTile;
#[derive(Debug, Clone)]
pub struct AnimatedTexture {
@@ -40,12 +37,6 @@ impl AnimatedTexture {
&self.tiles[self.current_frame]
}
pub fn render<T: RenderTarget>(&self, canvas: &mut Canvas<T>, atlas: &mut SpriteAtlas, dest: Rect) -> GameResult<()> {
let mut tile = *self.current_tile();
tile.render(canvas, atlas, dest)?;
Ok(())
}
/// Returns the current frame index.
#[allow(dead_code)]
pub fn current_frame(&self) -> usize {

View File

@@ -1,80 +0,0 @@
use sdl2::rect::Rect;
use sdl2::render::{Canvas, RenderTarget};
use crate::entity::direction::Direction;
use crate::error::GameResult;
use crate::texture::animated::AnimatedTexture;
use crate::texture::sprite::SpriteAtlas;
#[derive(Clone)]
pub struct DirectionalAnimatedTexture {
textures: [Option<AnimatedTexture>; 4],
stopped_textures: [Option<AnimatedTexture>; 4],
}
impl DirectionalAnimatedTexture {
pub fn new(textures: [Option<AnimatedTexture>; 4], stopped_textures: [Option<AnimatedTexture>; 4]) -> Self {
Self {
textures,
stopped_textures,
}
}
pub fn tick(&mut self, dt: f32) {
for texture in self.textures.iter_mut().flatten() {
texture.tick(dt);
}
}
pub fn render<T: RenderTarget>(
&self,
canvas: &mut Canvas<T>,
atlas: &mut SpriteAtlas,
dest: Rect,
direction: Direction,
) -> GameResult<()> {
if let Some(texture) = &self.textures[direction.as_usize()] {
texture.render(canvas, atlas, dest)
} else {
Ok(())
}
}
pub fn render_stopped<T: RenderTarget>(
&self,
canvas: &mut Canvas<T>,
atlas: &mut SpriteAtlas,
dest: Rect,
direction: Direction,
) -> GameResult<()> {
if let Some(texture) = &self.stopped_textures[direction.as_usize()] {
texture.render(canvas, atlas, dest)
} else {
Ok(())
}
}
/// Returns true if the texture has a direction.
#[allow(dead_code)]
pub fn has_direction(&self, direction: Direction) -> bool {
self.textures[direction.as_usize()].is_some()
}
/// Returns true if the texture has a stopped direction.
#[allow(dead_code)]
pub fn has_stopped_direction(&self, direction: Direction) -> bool {
self.stopped_textures[direction.as_usize()].is_some()
}
/// Returns the number of textures.
#[allow(dead_code)]
pub fn texture_count(&self) -> usize {
self.textures.iter().filter(|t| t.is_some()).count()
}
/// Returns the number of stopped textures.
#[allow(dead_code)]
pub fn stopped_texture_count(&self) -> usize {
self.stopped_textures.iter().filter(|t| t.is_some()).count()
}
}

View File

@@ -1,5 +1,4 @@
pub mod animated;
pub mod blinking;
pub mod directional;
pub mod sprite;
pub mod text;

View File

@@ -8,33 +8,6 @@ use std::collections::HashMap;
use crate::error::TextureError;
/// A simple sprite for stationary items like pellets and energizers.
#[derive(Clone, Debug)]
pub struct Sprite {
pub atlas_tile: AtlasTile,
}
impl Sprite {
pub fn new(atlas_tile: AtlasTile) -> Self {
Self { atlas_tile }
}
pub fn render<C: RenderTarget>(
&self,
canvas: &mut Canvas<C>,
atlas: &mut SpriteAtlas,
position: glam::Vec2,
) -> Result<(), TextureError> {
let dest = crate::helpers::centered_with_size(
glam::IVec2::new(position.x as i32, position.y as i32),
glam::UVec2::new(self.atlas_tile.size.x as u32, self.atlas_tile.size.y as u32),
);
let mut tile = self.atlas_tile;
tile.render(canvas, atlas, dest)?;
Ok(())
}
}
#[derive(Clone, Debug, Deserialize)]
pub struct AtlasMapper {
pub frames: HashMap<String, MapperFrame>,