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 #[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}