• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Xevion / Pac-Man / 17503409222

05 Sep 2025 08:10PM UTC coverage: 31.217% (-0.01%) from 31.228%
17503409222

push

github

Xevion
refactor: reorganize game.rs new() into separate functions

0 of 120 new or added lines in 1 file covered. (0.0%)

49 existing lines in 3 files now uncovered.

1067 of 3418 relevant lines covered (31.22%)

795.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.77
/src/texture/sprite.rs
1
use anyhow::Result;
2
use glam::U16Vec2;
3
use sdl2::pixels::Color;
4
use sdl2::rect::Rect;
5
use sdl2::render::{Canvas, RenderTarget, Texture};
6
use std::collections::HashMap;
7

8
use crate::error::TextureError;
9

10
/// Atlas frame mapping data loaded from JSON metadata files.
11
#[derive(Clone, Debug)]
12
pub struct AtlasMapper {
13
    /// Mapping from sprite name to frame bounds within the atlas texture
14
    pub frames: HashMap<String, MapperFrame>,
15
}
16

17
#[derive(Copy, Clone, Debug)]
18
pub struct MapperFrame {
19
    pub pos: U16Vec2,
20
    pub size: U16Vec2,
21
}
22

23
/// A single tile within a sprite atlas, defined by its position and size.
24
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
25
pub struct AtlasTile {
26
    pub pos: U16Vec2,
27
    pub size: U16Vec2,
28
    pub color: Option<Color>,
29
}
30

31
impl AtlasTile {
32
    pub fn render<C: RenderTarget>(
×
33
        &self,
×
34
        canvas: &mut Canvas<C>,
×
35
        atlas: &mut SpriteAtlas,
×
36
        dest: Rect,
×
37
    ) -> Result<(), TextureError> {
×
38
        let color = self.color.unwrap_or(atlas.default_color.unwrap_or(Color::WHITE));
×
39
        self.render_with_color(canvas, atlas, dest, color)?;
×
40
        Ok(())
×
UNCOV
41
    }
×
42

43
    pub fn render_with_color<C: RenderTarget>(
42✔
44
        &self,
42✔
45
        canvas: &mut Canvas<C>,
42✔
46
        atlas: &mut SpriteAtlas,
42✔
47
        dest: Rect,
42✔
48
        color: Color,
42✔
49
    ) -> Result<(), TextureError> {
42✔
50
        let src = Rect::new(self.pos.x as i32, self.pos.y as i32, self.size.x as u32, self.size.y as u32);
42✔
51

42✔
52
        if atlas.last_modulation != Some(color) {
42✔
53
            atlas.texture.set_color_mod(color.r, color.g, color.b);
1✔
54
            atlas.last_modulation = Some(color);
1✔
55
        }
41✔
56

57
        canvas.copy(&atlas.texture, src, dest).map_err(TextureError::RenderFailed)?;
42✔
58
        Ok(())
42✔
59
    }
42✔
60

61
    /// Creates a new atlas tile.
62
    #[allow(dead_code)]
63
    pub fn new(pos: U16Vec2, size: U16Vec2, color: Option<Color>) -> Self {
1✔
64
        Self { pos, size, color }
1✔
65
    }
1✔
66

67
    /// Sets the color of the tile.
68
    #[allow(dead_code)]
69
    pub fn with_color(mut self, color: Color) -> Self {
1✔
70
        self.color = Some(color);
1✔
71
        self
1✔
72
    }
1✔
73
}
74

75
/// High-performance sprite atlas providing fast texture region lookups and rendering.
76
///
77
/// Combines a single large texture with metadata mapping to enable efficient
78
/// sprite rendering without texture switching. Caches color modulation state
79
/// to minimize redundant SDL2 calls and supports both named sprite lookups
80
/// and optional default color modulation configuration.
81
pub struct SpriteAtlas {
82
    /// The combined texture containing all sprite frames
83
    texture: Texture,
84
    /// Mapping from sprite names to their pixel coordinates within the texture
85
    tiles: HashMap<String, MapperFrame>,
86
    default_color: Option<Color>,
87
    /// Cached color modulation state to avoid redundant SDL2 calls
88
    last_modulation: Option<Color>,
89
}
90

91
impl SpriteAtlas {
92
    pub fn new(texture: Texture, mapper: AtlasMapper) -> Self {
2✔
93
        let tiles = mapper.frames.into_iter().collect();
2✔
94

2✔
95
        Self {
2✔
96
            texture,
2✔
97
            tiles,
2✔
98
            default_color: None,
2✔
99
            last_modulation: None,
2✔
100
        }
2✔
101
    }
2✔
102

103
    /// Retrieves a sprite tile by name from the atlas with fast HashMap lookup.
104
    ///
105
    /// Returns an `AtlasTile` containing the texture coordinates and dimensions
106
    /// for the named sprite, or `None` if the sprite name is not found in the
107
    /// atlas. The returned tile can be used for immediate rendering or stored
108
    /// for repeated use in animations and entity sprites.
109
    pub fn get_tile(&self, name: &str) -> Result<AtlasTile, TextureError> {
80✔
110
        let frame = self
80✔
111
            .tiles
80✔
112
            .get(name)
80✔
113
            .ok_or_else(|| TextureError::AtlasTileNotFound(name.to_string()))?;
80✔
114
        Ok(AtlasTile {
80✔
115
            pos: frame.pos,
80✔
116
            size: frame.size,
80✔
117
            color: self.default_color,
80✔
118
        })
80✔
119
    }
80✔
120

121
    #[allow(dead_code)]
122
    pub fn set_color(&mut self, color: Color) {
×
UNCOV
123
        self.default_color = Some(color);
×
UNCOV
124
    }
×
125

126
    #[allow(dead_code)]
127
    pub fn texture(&self) -> &Texture {
×
128
        &self.texture
×
UNCOV
129
    }
×
130

131
    /// Returns the number of tiles in the atlas.
132
    #[allow(dead_code)]
133
    pub fn tiles_count(&self) -> usize {
×
134
        self.tiles.len()
×
UNCOV
135
    }
×
136

137
    /// Returns true if the atlas has a tile with the given name.
138
    #[allow(dead_code)]
139
    pub fn has_tile(&self, name: &str) -> bool {
×
140
        self.tiles.contains_key(name)
×
UNCOV
141
    }
×
142

143
    /// Returns the default color of the atlas.
144
    #[allow(dead_code)]
UNCOV
145
    pub fn default_color(&self) -> Option<Color> {
×
UNCOV
146
        self.default_color
×
UNCOV
147
    }
×
148
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc