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    fn idx(&self, pos: Vec2<i32>) -> Option<usize> {
39        if pos.map2(self.size, |e, sz| e >= 0 && e < sz).reduce_and() {
40            Some((pos.y * self.size.x + pos.x) as usize)
41        } else {
42            None
43        }
44    }
45
46    pub fn size(&self) -> Vec2<i32> { self.size }
47
48    pub fn get(&self, pos: Vec2<i32>) -> Option<&T> { self.cells.get(self.idx(pos)?) }
49
50    pub fn get_mut(&mut self, pos: Vec2<i32>) -> Option<&mut T> {
51        let idx = self.idx(pos)?;
52        self.cells.get_mut(idx)
53    }
54
55    pub fn set(&mut self, pos: Vec2<i32>, cell: T) -> Option<T> {
56        let idx = self.idx(pos)?;
57        self.cells.get_mut(idx).map(|c| core::mem::replace(c, cell))
58    }
59
60    pub fn iter(&self) -> impl Iterator<Item = (Vec2<i32>, &T)> + '_ {
61        let w = self.size.x;
62        self.cells
63            .iter()
64            .enumerate()
65            .map(move |(i, cell)| (Vec2::new(i as i32 % w, i as i32 / w), cell))
66    }
67
68    pub fn iter_mut(&mut self) -> impl Iterator<Item = (Vec2<i32>, &mut T)> + '_ {
69        let w = self.size.x;
70        self.cells
71            .iter_mut()
72            .enumerate()
73            .map(move |(i, cell)| (Vec2::new(i as i32 % w, i as i32 / w), cell))
74    }
75
76    pub fn iter_area(
77        &self,
78        pos: Vec2<i32>,
79        size: Vec2<i32>,
80    ) -> impl Iterator<Item = (Vec2<i32>, &T)> + '_ {
81        (0..size.x).flat_map(move |x| {
82            (0..size.y).flat_map(move |y| {
83                Some((
84                    pos + Vec2::new(x, y),
85                    &self.cells[self.idx(pos + Vec2::new(x, y))?],
86                ))
87            })
88        })
89    }
90
91    pub fn raw(&self) -> &[T] { &self.cells }
92}
93
94impl<T> Index<Vec2<i32>> for Grid<T> {
95    type Output = T;
96
97    fn index(&self, index: Vec2<i32>) -> &Self::Output {
98        self.get(index).unwrap_or_else(|| {
99            panic!(
100                "Attempted to index grid of size {:?} with index {:?}",
101                self.size(),
102                index
103            )
104        })
105    }
106}
107
108impl<T> IndexMut<Vec2<i32>> for Grid<T> {
109    fn index_mut(&mut self, index: Vec2<i32>) -> &mut Self::Output {
110        let size = self.size();
111        self.get_mut(index).unwrap_or_else(|| {
112            panic!(
113                "Attempted to index grid of size {:?} with index {:?}",
114                size, index
115            )
116        })
117    }
118}