use std::collections::HashMap; use crate::{ config::CHUNK_SIZE, sim::{cell::Cell, chunk::Chunk}, }; pub struct World { pub chunks: Vec, // 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 { 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, sleeping: bool, ) -> () { 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); // this is a temporary hack self.chunks[idx].sleeping = sleeping; } } 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 -50..50 { world.insert(x, y, Chunk::void()); } } world } }