simple_game_utils/tiles/
units.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
4pub struct MapSize {
5    pub w: u32,
6    pub h: u32,
7}
8
9#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Hash)]
10pub struct MapPosition {
11    pub x: u32,
12    pub y: u32,
13}
14
15impl MapSize {
16    #[inline]
17    pub const fn new(w: u32, h: u32) -> Self {
18        Self { w, h }
19    }
20}
21
22impl MapPosition {
23    #[inline]
24    pub const fn new(x: u32, y: u32) -> Self {
25        Self { x, y }
26    }
27
28    #[inline]
29    pub const fn from_idx(i: usize, using: MapSize) -> MapPosition {
30        MapPosition {
31            x: i as u32 % using.w,
32            y: i as u32 / using.w,
33        }
34    }
35}
36
37impl MapSize {
38    #[inline]
39    pub const fn count(&self) -> u32 {
40        self.w * self.h
41    }
42}
43
44impl MapPosition {
45    #[inline]
46    pub const fn to_idx(&self, using: MapSize) -> usize {
47        (self.x + self.y * using.w) as usize
48    }
49}
50
51macro_rules! from_num {
52    ($num:ty) => {
53        impl From<($num, $num)> for MapPosition {
54            #[inline]
55            fn from(value: ($num, $num)) -> Self {
56                MapPosition {
57                    x: value.0 as u32,
58                    y: value.1 as u32,
59                }
60            }
61        }
62        impl From<($num, $num)> for MapSize {
63            #[inline]
64            fn from(value: ($num, $num)) -> Self {
65                MapSize {
66                    w: value.0 as u32,
67                    h: value.1 as u32,
68                }
69            }
70        }
71    };
72}
73
74from_num!(u64);
75from_num!(u32);
76from_num!(u16);
77from_num!(u8);
78from_num!(usize);
79
80#[cfg(test)]
81mod test {
82    use super::*;
83
84    #[test]
85    fn macros() {
86        let _u64s: MapSize = (12_u64, 12_u64).into();
87        let _u64p: MapPosition = (12_u64, 12_u64).into();
88
89        assert_eq!(MapSize::new(12, 12), _u64s);
90        assert_eq!(MapPosition::new(12, 12), _u64p);
91    }
92
93    #[test]
94    fn indexing() {
95        let size1 = MapSize::new(4, 4);
96        let size2 = MapSize::new(8, 4);
97
98        let pos1 = MapPosition::new(1, 1);
99
100        assert_eq!(pos1.to_idx(size1), 5);
101        assert_eq!(pos1.to_idx(size2), 9);
102        assert_eq!(MapPosition::from_idx(15, size1), MapPosition::new(3, 3));
103        assert_eq!(MapPosition::from_idx(15, size2), MapPosition::new(7, 1));
104    }
105}