2020-11-25 14:59:28 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use std::ops::{Index, IndexMut};
|
2019-08-24 13:23:42 +00:00
|
|
|
use vek::*;
|
|
|
|
|
2020-11-25 14:59:28 +00:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2019-08-24 13:23:42 +00:00
|
|
|
pub struct Grid<T> {
|
|
|
|
cells: Vec<T>,
|
2020-12-05 18:30:07 +00:00
|
|
|
size: Vec2<i32>, // TODO: use u32
|
2019-08-24 13:23:42 +00:00
|
|
|
}
|
|
|
|
|
2020-02-07 22:19:25 +00:00
|
|
|
impl<T> Grid<T> {
|
2020-11-25 14:59:28 +00:00
|
|
|
pub fn from_raw(size: Vec2<i32>, raw: impl Into<Vec<T>>) -> Self {
|
|
|
|
let cells = raw.into();
|
|
|
|
assert_eq!(size.product() as usize, cells.len());
|
|
|
|
Self { cells, size }
|
|
|
|
}
|
|
|
|
|
2020-02-07 22:19:25 +00:00
|
|
|
pub fn populate_from(size: Vec2<i32>, mut f: impl FnMut(Vec2<i32>) -> T) -> Self {
|
|
|
|
Self {
|
|
|
|
cells: (0..size.y)
|
2021-12-21 20:19:23 +00:00
|
|
|
.flat_map(|y| (0..size.x).map(move |x| Vec2::new(x, y)))
|
2020-02-07 22:19:25 +00:00
|
|
|
.map(&mut f)
|
|
|
|
.collect(),
|
|
|
|
size,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-16 01:40:09 +00:00
|
|
|
pub fn new(size: Vec2<i32>, default_cell: T) -> Self
|
2020-02-07 22:19:25 +00:00
|
|
|
where
|
|
|
|
T: Clone,
|
|
|
|
{
|
2019-08-24 13:23:42 +00:00
|
|
|
Self {
|
|
|
|
cells: vec![default_cell; size.product() as usize],
|
|
|
|
size,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-24 22:57:55 +00:00
|
|
|
fn idx(&self, pos: Vec2<i32>) -> Option<usize> {
|
|
|
|
if pos.map2(self.size, |e, sz| e >= 0 && e < sz).reduce_and() {
|
|
|
|
Some((pos.y * self.size.x + pos.x) as usize)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2019-08-24 13:23:42 +00:00
|
|
|
}
|
|
|
|
|
2020-02-01 20:39:39 +00:00
|
|
|
pub fn size(&self) -> Vec2<i32> { self.size }
|
2019-08-24 13:23:42 +00:00
|
|
|
|
2020-02-01 20:39:39 +00:00
|
|
|
pub fn get(&self, pos: Vec2<i32>) -> Option<&T> { self.cells.get(self.idx(pos)?) }
|
2019-08-24 13:23:42 +00:00
|
|
|
|
|
|
|
pub fn get_mut(&mut self, pos: Vec2<i32>) -> Option<&mut T> {
|
2019-08-24 22:57:55 +00:00
|
|
|
let idx = self.idx(pos)?;
|
2019-08-24 13:23:42 +00:00
|
|
|
self.cells.get_mut(idx)
|
|
|
|
}
|
|
|
|
|
2021-05-11 17:53:10 +00:00
|
|
|
pub fn set(&mut self, pos: Vec2<i32>, cell: T) -> Option<T> {
|
2019-08-24 22:57:55 +00:00
|
|
|
let idx = self.idx(pos)?;
|
2021-05-11 17:53:10 +00:00
|
|
|
self.cells.get_mut(idx).map(|c| core::mem::replace(c, cell))
|
2019-08-24 13:23:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn iter(&self) -> impl Iterator<Item = (Vec2<i32>, &T)> + '_ {
|
2019-08-28 18:32:44 +00:00
|
|
|
let w = self.size.x;
|
|
|
|
self.cells
|
|
|
|
.iter()
|
|
|
|
.enumerate()
|
|
|
|
.map(move |(i, cell)| (Vec2::new(i as i32 % w, i as i32 / w), cell))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn iter_mut(&mut self) -> impl Iterator<Item = (Vec2<i32>, &mut T)> + '_ {
|
|
|
|
let w = self.size.x;
|
|
|
|
self.cells
|
|
|
|
.iter_mut()
|
|
|
|
.enumerate()
|
|
|
|
.map(move |(i, cell)| (Vec2::new(i as i32 % w, i as i32 / w), cell))
|
2019-08-24 22:57:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn iter_area(
|
|
|
|
&self,
|
|
|
|
pos: Vec2<i32>,
|
|
|
|
size: Vec2<i32>,
|
|
|
|
) -> impl Iterator<Item = Option<(Vec2<i32>, &T)>> + '_ {
|
2021-12-21 20:19:23 +00:00
|
|
|
(0..size.x).flat_map(move |x| {
|
|
|
|
(0..size.y).map(move |y| {
|
|
|
|
Some((
|
|
|
|
pos + Vec2::new(x, y),
|
|
|
|
&self.cells[self.idx(pos + Vec2::new(x, y))?],
|
|
|
|
))
|
2019-08-24 13:23:42 +00:00
|
|
|
})
|
2021-12-21 20:19:23 +00:00
|
|
|
})
|
2019-08-24 13:23:42 +00:00
|
|
|
}
|
2020-11-25 14:59:28 +00:00
|
|
|
|
|
|
|
pub fn raw(&self) -> &[T] { &self.cells }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Index<Vec2<i32>> for Grid<T> {
|
|
|
|
type Output = T;
|
|
|
|
|
|
|
|
fn index(&self, index: Vec2<i32>) -> &Self::Output {
|
|
|
|
self.get(index).unwrap_or_else(|| {
|
|
|
|
panic!(
|
|
|
|
"Attempted to index grid of size {:?} with index {:?}",
|
|
|
|
self.size(),
|
|
|
|
index
|
|
|
|
)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> IndexMut<Vec2<i32>> for Grid<T> {
|
|
|
|
fn index_mut(&mut self, index: Vec2<i32>) -> &mut Self::Output {
|
|
|
|
let size = self.size();
|
|
|
|
self.get_mut(index).unwrap_or_else(|| {
|
|
|
|
panic!(
|
|
|
|
"Attempted to index grid of size {:?} with index {:?}",
|
|
|
|
size, index
|
|
|
|
)
|
|
|
|
})
|
|
|
|
}
|
2019-08-24 13:23:42 +00:00
|
|
|
}
|