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>, }
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}