diff options
Diffstat (limited to 'src/sim/world.rs')
| -rw-r--r-- | src/sim/world.rs | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/sim/world.rs b/src/sim/world.rs new file mode 100644 index 0000000..3c7b05b --- /dev/null +++ b/src/sim/world.rs @@ -0,0 +1,66 @@ +use std::collections::HashMap; + +use crate::{ + config::CHUNK_SIZE, + sim::{cell::Cell, chunk::Chunk}, +}; + +pub struct World { + pub chunks: Vec<Chunk>, + // TODO FxHashMap? + pub chunk_position_to_chunk_idx: HashMap<(i32, i32), usize>, +} + +impl World { + #[inline] + pub fn split_game_position(x: i32, y: i32) -> ((i32, i32), (u8, u8)) { + ( + ( + // TODO is this cast expensive? + x.div_euclid(CHUNK_SIZE as i32), + y.div_euclid(CHUNK_SIZE as i32), + ), + ( + x.rem_euclid(CHUNK_SIZE as i32) as u8, + y.rem_euclid(CHUNK_SIZE as i32) as u8, + ), + ) + } + + // VERY EXPENSIVE + pub fn get_cell_from_game_position(&self, x: i32, y: i32) -> Option<Cell> { + let ((cx, cy), (dx, dy)) = World::split_game_position(x, y); + self.chunk_position_to_chunk_idx + .get(&(cx, cy)) + .map(|&idx| self.chunks[idx].get_cell_at_local_position(dx, dy)) + } + + // VERY EXPENSIVE + pub fn set_cell_from_game_position(&mut self, x: i32, y: i32, cell: Cell) -> () { + let ((cx, cy), (dx, dy)) = World::split_game_position(x, y); + if let Some(&idx) = self.chunk_position_to_chunk_idx.get(&(cx, cy)) { + self.chunks[idx].set_cell_at_local_position(dx, dy, cell); + } + } + + pub fn insert(&mut self, x: i32, y: i32, chunk: Chunk) -> () { + self.chunk_position_to_chunk_idx + .insert((x, y), self.chunks.len()); + self.chunks.push(chunk); + } + + pub fn from_default_size() -> Self { + let mut world = World { + chunks: Vec::new(), + chunk_position_to_chunk_idx: HashMap::new(), + }; + + for y in -10..10 { + for x in -10..10 { + world.insert(x, y, Chunk::void()); + } + } + + world + } +} |
