diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2026-08-23 12:57:20 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2026-08-23 12:57:20 -0700 |
| commit | c2d6115403b244f05ccd45ba9edc16b050cf3772 (patch) | |
| tree | 046ebf581d9c237423565190c4e063ef2aba96c6 /src/sim | |
| parent | 35f1bc48629456ee66cfb4643ca69b0811f02167 (diff) | |
refactor writing entities
Diffstat (limited to 'src/sim')
| -rw-r--r-- | src/sim/sim_manager/mod.rs | 64 | ||||
| -rw-r--r-- | src/sim/sim_manager/utils.rs | 78 |
2 files changed, 75 insertions, 67 deletions
diff --git a/src/sim/sim_manager/mod.rs b/src/sim/sim_manager/mod.rs index 97f542b..74c21fa 100644 --- a/src/sim/sim_manager/mod.rs +++ b/src/sim/sim_manager/mod.rs @@ -1,18 +1,16 @@ use std::time::Instant; use fxhash::FxHashMap; -use glam::IVec2; use crate::{ Config, config::{PHYSICS_DELTA_TIME, PHYSICS_FPS, SIM_FPS}, sim::{ - cell::Cell, cell_manager::manager::CellManager, entity::{Entity, EntityDef, EntityId}, particle_manager::ParticleManager, rb_manager::RbManager, - sim_manager::utils::write_entity_to_world, + sim_manager::utils::{read_back_entities_from_world, write_entities_to_world}, }, }; @@ -95,17 +93,12 @@ impl SimManager { fn cell_update(&mut self, config: &Config, delta_time: f32) { // before we tick, write all the entities into the sim world - // TODO optimize - let entity_ids: Vec<EntityId> = self.entities.keys().copied().collect(); - let mut cells_written_by_entity: Vec<(EntityId, Vec<(u8, u8, i32, i32)>)> = Vec::new(); - - for entity_id in entity_ids { - let cells_written = write_entity_to_world(self, entity_id, self.cell_manager.seqno); - cells_written_by_entity.push((entity_id, cells_written)); - } + let cells_written_by_entity = write_entities_to_world(self); + // tick self.cell_manager.tick(config.use_threading); + // update entities let entity_ids: Vec<EntityId> = self.entities.keys().cloned().collect(); for id in entity_ids { let entity = self.entities.get_mut(&id); @@ -117,6 +110,7 @@ impl SimManager { if let Some(entity) = entity && let Some(result) = entity.update(&mut ctx, delta_time) { + // process entity update results for d in result.deferred_destructions { self.destroy_entity(d); } @@ -124,53 +118,7 @@ impl SimManager { } // after we tick, remove the written entity cells and update the entities - // TODO optimize - for (entity_id, cells_written) in cells_written_by_entity { - if let Some(entity) = self.entities.get_mut(&entity_id) { - let entity_cells = entity.data.cells.as_mut().unwrap(); - let mut should_update_entity = false; - - for (lx, ly, x, y) in cells_written { - // update the entity - // TODO optimize - let new_local_cell = - self.cell_manager.get_cell_from_game_position(x, y).unwrap(); - if !new_local_cell.entity_integrated() { - // this means that the entity changed in some way, so we should recompute its shape - // TODO wait N frames to debounce this - should_update_entity = true; - } - // we do this unconditionally because it's cheaper than checking if it actually needs to be updated - // and because we don't have a good way to track changes to cell state - entity_cells.set_cell_at_local_position( - IVec2::new(lx as i32, ly as i32), - new_local_cell, - ); - - // update the world - // TODO optimize - self.cell_manager - .set_cell_from_game_position(x, y, Cell::void(), false); - } - - if should_update_entity { - if let Some(new_collider) = entity.compute_collider() { - self.rb_manager - .physics_manager - .world - .remove_collider(entity.data.collider_h.unwrap()); - - let new_handle = self - .rb_manager - .physics_manager - .world - .insert_collider(new_collider, Some(entity.data.rb_h.unwrap())); - - entity.data.collider_h = Some(new_handle); - } - } - } - } + read_back_entities_from_world(self, cells_written_by_entity); } fn physics_update(&mut self, delta_time: f32) { diff --git a/src/sim/sim_manager/utils.rs b/src/sim/sim_manager/utils.rs index 13d7891..413e709 100644 --- a/src/sim/sim_manager/utils.rs +++ b/src/sim/sim_manager/utils.rs @@ -2,16 +2,10 @@ use glam::IVec2; use crate::{ content::materials::MaterialId, - sim::{entity::EntityId, sim_manager::SimManager}, + sim::{cell::Cell, entity::EntityId, sim_manager::SimManager}, }; -pub fn write_entity_to_world( - sim: &mut SimManager, - entity_id: EntityId, - // make sure these cells will be simulated - seqno: u64, - // (entity_x, entity_y, cell_x, cell_y) -) -> Vec<(u8, u8, i32, i32)> { +fn write_entity_to_world(sim: &mut SimManager, entity_id: EntityId) -> Vec<(u8, u8, i32, i32)> { let mut cells_written: Vec<(u8, u8, i32, i32)> = Vec::new(); if let Some(entity) = sim.entities.get(&entity_id) && let Some(cells) = &entity.data.cells @@ -57,7 +51,7 @@ pub fn write_entity_to_world( continue; } - cell.match_parity(seqno); + cell.match_parity(sim.cell_manager.seqno); // TODO: OPTIMIZE!! sim.cell_manager @@ -69,3 +63,69 @@ pub fn write_entity_to_world( } cells_written } + +pub fn write_entities_to_world( + sim: &mut SimManager, + // (entity_x, entity_y, cell_x, cell_y) +) -> Vec<(EntityId, Vec<(u8, u8, i32, i32)>)> { + // TODO optimize + let entity_ids: Vec<EntityId> = sim.entities.keys().copied().collect(); + let mut cells_written_by_entity: Vec<(EntityId, Vec<(u8, u8, i32, i32)>)> = Vec::new(); + + for entity_id in entity_ids { + let cells_written = write_entity_to_world(sim, entity_id); + cells_written_by_entity.push((entity_id, cells_written)); + } + + cells_written_by_entity +} + +// TODO optimize +pub fn read_back_entities_from_world( + sim: &mut SimManager, + cells_written_by_entity: Vec<(EntityId, Vec<(u8, u8, i32, i32)>)>, +) { + for (entity_id, cells_written) in cells_written_by_entity { + if let Some(entity) = sim.entities.get_mut(&entity_id) { + let entity_cells = entity.data.cells.as_mut().unwrap(); + let mut should_update_entity = false; + + for (lx, ly, x, y) in cells_written { + // update the entity + // TODO optimize + let new_local_cell = sim.cell_manager.get_cell_from_game_position(x, y).unwrap(); + if !new_local_cell.entity_integrated() { + // this means that the entity changed in some way, so we should recompute its shape + // TODO wait N frames to debounce this + should_update_entity = true; + } + // we do this unconditionally because it's cheaper than checking if it actually needs to be updated + // and because we don't have a good way to track changes to cell state + entity_cells + .set_cell_at_local_position(IVec2::new(lx as i32, ly as i32), new_local_cell); + + // update the world + // TODO optimize + sim.cell_manager + .set_cell_from_game_position(x, y, Cell::void(), false); + } + + if should_update_entity { + if let Some(new_collider) = entity.compute_collider() { + sim.rb_manager + .physics_manager + .world + .remove_collider(entity.data.collider_h.unwrap()); + + let new_handle = sim + .rb_manager + .physics_manager + .world + .insert_collider(new_collider, Some(entity.data.rb_h.unwrap())); + + entity.data.collider_h = Some(new_handle); + } + } + } + } +} |
