veloren_common/
grid.rs

1use serde::{Deserialize, Serialize};
2use std::ops::{Index, IndexMut};
3use vek::*;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Grid<T> {
7    cells: Vec<T>,
8    size: Vec2<i32>, // TODO: use u32
9}
10
11impl<T> Grid<T> {
12    pub fn from_raw(size: Vec2<i32>, raw: impl Into<Vec<T>>) -> Self {
13        let cells = raw.into();
14        assert_eq!(size.product() as usize, cells.len());
15        Self { cells, size }
16    }
17
18    pub fn populate_from(size: Vec2<i32>, mut f: impl FnMut(Vec2<i32>) -> T) -> Self {
19        Self {
20            cells: (0..size.y)
21                .flat_map(|y| (0..size.x).map(move |x| Vec2::new(x, y)))
22                .map(&mut f)
23                .collect(),
24            size,
25        }
26    }
27
28    pub fn new(size: Vec2<i32>, default_cell: T) -> Self
29    where
30        T: Clone,
31    {
32        Self {
33            cells: vec![default_cell; size.product() as usize],
34            size,
35        }
36    }
37
38    #[inline]
39    fn idx(&self, pos: Vec2<i32>) -> Option<usize> {
40        if pos.map2(self.size, |e, sz| e >= 0 && e < sz).reduce_and() {
41            Some((pos.y * self.size.x + pos.x) as usize)
42        } else {
43            None
44        }
45    }
46
47    #[inline]
48    pub fn size(&self) -> Vec2<i32> { self.size }
49
50    #[inline]
51    pub fn get(&self, pos: Vec2<i32>) -> Option<&T> { self.cells.get(self.idx(pos)?) }
52
53    #[inline]
54    pub fn get_mut(&mut self, pos: Vec2<i32>) -> Option<&mut T> {
55        let idx = self.idx(pos)?;
56        self.cells.get_mut(idx)
57    }
58
59    #[inline]
60    pub fn set(&mut self, pos: Vec2<i32>, cell: T) -> Option<T> {
61        let idx = self.idx(pos)?;
62        self.cells.get_mut(idx).map(|c| core::mem::replace(c, cell))
63    }
64
65    #[inline]
66    pub fn iter(&self) -> impl Iterator<Item = (Vec2<i32>, &T)> + '_ {
67        let w = self.size.x;
68        self.cells
69            .iter()
70            .enumerate()
71            .map(move |(i, cell)| (Vec2::new(i as i32 % w, i as i32 / w), cell))
72    }
73
74    #[inline]
75    pub fn iter_mut(&mut self) -> impl Iterator<Item = (Vec2<i32>, &mut T)> + '_ {
76        let w = self.size.x;
77        self.cells
78            .iter_mut()
79            .enumerate()
80            .map(move |(i, cell)| (Vec2::new(i as i32 % w, i as i32 / w), cell))
81    }
82
83    #[inline]
84    pub fn iter_area(
85        &self,
86        pos: Vec2<i32>,
87        size: Vec2<i32>,
88    ) -> impl Iterator<Item = (Vec2<i32>, &T)> + '_ {
89        (0..size.x).flat_map(move |x| {
90            (0..size.y).flat_map(move |y| {
91                Some((
92                    pos + Vec2::new(x, y),
93                    &self.cells[self.idx(pos + Vec2::new(x, y))?],
94                ))
95            })
96        })
97    }
98
99    #[inline]
100    pub fn raw(&self) -> &[T] { &self.cells }
101
102    #[inline]
103    pub fn raw_mut(&mut self) -> &mut [T] { &mut self.cells }
104}
105
106impl<T> Index<Vec2<i32>> for Grid<T> {
107    type Output = T;
108
109    #[inline]
110    fn index(&self, index: Vec2<i32>) -> &Self::Output {
111        self.get(index).unwrap_or_else(|| {
112            panic!(
113                "Attempted to index grid of size {:?} with index {:?}",
114                self.size(),
115                index
116            )
117        })
118    }
119}
120
121impl<T> IndexMut<Vec2<i32>> for Grid<T> {
122    #[inline]
123    fn index_mut(&mut self, index: Vec2<i32>) -> &mut Self::Output {
124        let size = self.size();
125        self.get_mut(index).unwrap_or_else(|| {
126            panic!(
127                "Attempted to index grid of size {:?} with index {:?}",
128                size, index
129            )
130        })
131    }
132}