use bevy::prelude::Color; use std::ops::{Index, IndexMut}; pub struct Table { default: T, pub(crate) data: Vec, pub(crate) side: usize, } impl Clone for Table { fn clone(&self) -> Self { Table { default: self.default.clone(), data: self.data.clone(), side: self.side, } } } impl Table { pub fn new(fill: T, side: usize) -> Self { Table { default: fill.clone(), data: vec![fill; side * side], side, } } pub fn get(&self, index: usize) -> &T { &self.data[index] } fn get_dim(&self, x: usize, y: usize) -> &T { self.get(x + y * self.side) } pub fn set(&mut self, index: usize, value: T) { self.data[index] = value; } pub fn set_dim(&mut self, x: usize, y: usize, value: T) { self.set(x + y * self.side, value); } pub fn grow(&mut self) { let new_side = self.side * 2; let mut temp_table = Table::new(self.default.clone(), new_side); for x in 0..self.side { for y in 0..self.side { let new_x = x * 2; let new_y = y * 2; let val = self.get_dim(x, y); temp_table.set_dim(new_x, new_y, val.clone()); temp_table.set_dim(new_x + 1, new_y, val.clone()); temp_table.set_dim(new_x, new_y + 1, val.clone()); temp_table.set_dim(new_x + 1, new_y + 1, val.clone()); } } self.data = temp_table.data; self.side = new_side; } pub fn iter(&self) -> impl Iterator { self.data.iter() } pub fn convert_copy(&self, table: &mut Table, f: impl Fn(T) -> X) { for i in 0..self.data.len() { table.data[i] = f(self[i].clone()) } } pub fn around_line(&self, index: usize) -> Vec<&T> { self.around(index % self.side, index / self.side) } pub fn around(&self, x: usize, y: usize) -> Vec<&T> { let coordinates = vec![ (x as isize, y as isize - 1), (x as isize, y as isize + 1), (x as isize + 1, y as isize), (x as isize - 1, y as isize), ]; coordinates.iter().filter(|(x, y)| { *x >= 0 && *x < self.side as isize && *y >= 0 && *y < self.side as isize }).map(|(x, y)| self.get_dim(*x as usize, *y as usize)).collect::>() } } impl Into> for Table { fn into(self) -> Vec { self.data } } pub trait IntoImage { fn get_image_data(&self) -> Vec; } impl IntoImage for Table { fn get_image_data(&self) -> Vec { let mut data: Vec = vec![0; self.side * self.side * 4]; self.data .iter() .zip((0..self.data.len()).collect::>()) .for_each(|(color, idx)| { let idx = idx * 4; let value = if *color { 255 } else { 0 }; data[idx] = value; data[idx + 1] = value; data[idx + 2] = value; data[idx + 3] = 255; }); data } } impl IntoImage for Table { fn get_image_data(&self) -> Vec { let mut data: Vec = vec![0; self.side * self.side * 4]; self.data .iter() .zip((0..self.data.len()).collect::>()) .for_each(|(color, idx)| { let idx = idx * 4; let color = color.to_linear(); data[idx] = (color.red * 255.0) as u8; data[idx + 1] = (color.green * 255.0) as u8; data[idx + 2] = (color.blue * 255.0) as u8; data[idx + 3] = 255; }); data } } impl Index for Table { type Output = T; fn index(&self, index: usize) -> &Self::Output { self.get(index) } } impl IndexMut for Table { fn index_mut(&mut self, index: usize) -> &mut Self::Output { self.data.index_mut(index) } }