From e6742f59102f2beb305b813d7f0ee1d544bbc3e0 Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Sun, 23 Aug 2026 12:14:19 -0700 Subject: separate data from cells --- src/sim/cell_manager/sim.rs | 101 ++++++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 26 deletions(-) (limited to 'src/sim/cell_manager/sim.rs') diff --git a/src/sim/cell_manager/sim.rs b/src/sim/cell_manager/sim.rs index ffa253b..5e369a9 100644 --- a/src/sim/cell_manager/sim.rs +++ b/src/sim/cell_manager/sim.rs @@ -10,6 +10,7 @@ use crate::{ sim::{ cell::Cell, cell_manager::{chunk::Chunk, manager::CellManager}, + entity::EntityId, }, }; @@ -52,9 +53,10 @@ fn neighbourhood_index(x: i8, y: i8) -> usize { (x + 1 + (y + 1) * 3) as usize } -fn get_cell(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option { +fn internal_get_cell(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option { let dcx = x.div_euclid(CHUNK_SIZE); let dcy = y.div_euclid(CHUNK_SIZE); + // optimized path to save on the rem calls if dcx != 0 || dcy != 0 { // in a different chunk let nc_x = x.rem_euclid(CHUNK_SIZE) as u8; @@ -70,6 +72,56 @@ fn get_cell(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option { } } +fn internal_get_cell_data(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option { + let dcx = x.div_euclid(CHUNK_SIZE); + let dcy = y.div_euclid(CHUNK_SIZE); + if dcx != 0 || dcy != 0 { + // in a different chunk + let nc_x = x.rem_euclid(CHUNK_SIZE) as u8; + let nc_y = y.rem_euclid(CHUNK_SIZE) as u8; + + chunks[neighbourhood_index(dcx as i8, dcy as i8)] + .as_ref() + .map(|chunk| chunk.get_data_at_local_position(nc_x, nc_y)) + .flatten() + } else { + chunks[4] + .as_ref() + .map(|target| target.get_data_at_local_position(x as u8, y as u8)) + .flatten() + } +} + +fn internal_set_cell_data(chunks: &mut [Option<&mut Chunk>; 9], x: i32, y: i32, data: u16) { + let dcx = x.div_euclid(CHUNK_SIZE); + let dcy = y.div_euclid(CHUNK_SIZE); + let nc_x = x.rem_euclid(CHUNK_SIZE) as u8; + let nc_y = y.rem_euclid(CHUNK_SIZE) as u8; + if let Some(chunk) = &mut chunks[neighbourhood_index(dcx as i8, dcy as i8)] { + chunk.set_data_at_local_position(nc_x, nc_y, data); + } +} + +fn internal_get_cell_entity(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option { + let dcx = x.div_euclid(CHUNK_SIZE); + let dcy = y.div_euclid(CHUNK_SIZE); + if dcx != 0 || dcy != 0 { + // in a different chunk + let nc_x = x.rem_euclid(CHUNK_SIZE) as u8; + let nc_y = y.rem_euclid(CHUNK_SIZE) as u8; + + chunks[neighbourhood_index(dcx as i8, dcy as i8)] + .as_ref() + .map(|chunk| chunk.get_entity_at_local_position(nc_x, nc_y)) + .flatten() + } else { + chunks[4] + .as_ref() + .map(|target| target.get_entity_at_local_position(x as u8, y as u8)) + .flatten() + } +} + fn adjacent_chunks(x: u8, y: u8) -> Vec { if x == 0 { if y == 0 { @@ -133,29 +185,14 @@ fn internal_set_cell(chunks: &mut [Option<&mut Chunk>; 9], x: i32, y: i32, cell: let cy = y.div_euclid(CHUNK_SIZE); let lx = x.rem_euclid(CHUNK_SIZE) as u8; let ly = y.rem_euclid(CHUNK_SIZE) as u8; - if cx != 0 || cy != 0 { - // in a different chunk - if let Some(chunk) = &mut chunks[neighbourhood_index(cx as i8, cy as i8)] { - chunk.set_cell_at_local_position(lx, ly, cell); - chunk.needs_texture_update = true; - chunk.sleeping = false; - // if we're at the boundaries of the chunk, wake the adjacent chunk(s) - for idx in adjacent_chunks(lx, ly) { - if let Some(chunk) = chunks[idx].as_mut() { - chunk.sleeping = false; - } - } - } - } else { - if let Some(target) = &mut chunks[4] { - target.set_cell_at_local_position(x as u8, y as u8, cell); - target.needs_texture_update = true; - target.sleeping = false; - // if we're at the boundaries of the chunk, wake the adjacent chunk(s) - for idx in adjacent_chunks(lx, ly) { - if let Some(chunk) = chunks[idx].as_mut() { - chunk.sleeping = false; - } + if let Some(chunk) = &mut chunks[neighbourhood_index(cx as i8, cy as i8)] { + chunk.set_cell_at_local_position(lx, ly, cell); + chunk.needs_texture_update = true; + chunk.sleeping = false; + // if we're at the boundaries of the chunk, wake the adjacent chunk(s) + for idx in adjacent_chunks(lx, ly) { + if let Some(chunk) = chunks[idx].as_mut() { + chunk.sleeping = false; } } } @@ -190,7 +227,7 @@ impl UpdateCtx<'_, '_, '_> { pub fn get_cell(&self, dx: i32, dy: i32) -> Option { let x = self.x + dx; let y = self.y + dy; - get_cell(self.chunks, x, y) + internal_get_cell(self.chunks, x, y) } pub fn set_cell(&mut self, dx: i32, dy: i32, cell: Cell) { @@ -203,6 +240,18 @@ impl UpdateCtx<'_, '_, '_> { internal_set_cell(self.chunks, x, y, cell); } + pub fn get_cell_data(&self, dx: i32, dy: i32) -> Option { + let x = self.x + dx; + let y = self.y + dy; + internal_get_cell_data(self.chunks, x, y) + } + + pub fn set_cell_data(&mut self, dx: i32, dy: i32, data: u16) { + let x = self.x + dx; + let y = self.y + dy; + internal_set_cell_data(self.chunks, x, y, data); + } + pub fn swap_or_settle(&mut self, candidates: &[(i32, i32)]) -> PostUpdateAction { for &(dx, dy) in candidates { if let Some(mut candidate_cell) = self.get_cell(dx, dy) @@ -235,7 +284,7 @@ fn sim_tick_chunk(chunks: &mut [Option<&mut Chunk>; 9], seqno: u64) { (CHUNK_SIZE) - i - 1 }; - let mut cell = get_cell(chunks, x, y).unwrap(); + let mut cell = internal_get_cell(chunks, x, y).unwrap(); let material = cell.material.def(); if let Some(update) = material.sim_update -- cgit v1.3.1