summaryrefslogtreecommitdiff
path: root/src/sim/cell_manager/sim.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/cell_manager/sim.rs')
-rw-r--r--src/sim/cell_manager/sim.rs101
1 files changed, 75 insertions, 26 deletions
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<Cell> {
+fn internal_get_cell(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option<Cell> {
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<Cell> {
}
}
+fn internal_get_cell_data(chunks: &[Option<&mut Chunk>; 9], x: i32, y: i32) -> Option<u16> {
+ 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<EntityId> {
+ 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<usize> {
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<Cell> {
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<u16> {
+ 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