# HG changeset patch # User alfadur # Date 1564083084 -10800 # Node ID 42b710b0f883d76c597de5a286ec361db660580a # Parent bfd185ad03e7602e7e31cc7f9108d0b59772a588 add gear allocator diff -r bfd185ad03e7 -r 42b710b0f883 rust/hwphysics/src/collision.rs --- a/rust/hwphysics/src/collision.rs Thu Jul 25 21:59:20 2019 +0300 +++ b/rust/hwphysics/src/collision.rs Thu Jul 25 22:31:24 2019 +0300 @@ -147,4 +147,8 @@ fn add(&mut self, gear_id: GearId, gear_data: CollisionData) { self.grid.insert_static(gear_id, &gear_data.bounds); } + + fn remove(&mut self, gear_id: GearId) { + self.grid.remove(gear_id); + } } diff -r bfd185ad03e7 -r 42b710b0f883 rust/hwphysics/src/common.rs --- a/rust/hwphysics/src/common.rs Thu Jul 25 21:59:20 2019 +0300 +++ b/rust/hwphysics/src/common.rs Thu Jul 25 22:31:24 2019 +0300 @@ -1,10 +1,40 @@ -pub type GearId = std::num::NonZeroU16; +use std::{collections::BinaryHeap, num::NonZeroU16}; + +pub type GearId = NonZeroU16; pub trait GearData {} pub trait GearDataProcessor { fn add(&mut self, gear_id: GearId, gear_data: T); + fn remove(&mut self, gear_id: GearId); } pub trait GearDataAggregator { fn find_processor(&mut self) -> &mut GearDataProcessor; } + +pub struct GearAllocator { + max_id: u16, + free_ids: BinaryHeap, +} + +impl GearAllocator { + pub fn new() -> Self { + Self { + max_id: 0, + free_ids: BinaryHeap::with_capacity(1024), + } + } + + pub fn alloc(&mut self) -> Option { + self.free_ids.pop().or_else(|| { + self.max_id.checked_add(1).and_then(|new_max_id| { + self.max_id = new_max_id; + NonZeroU16::new(new_max_id) + }) + }) + } + + pub fn free(&mut self, gear_id: GearId) { + self.free_ids.push(gear_id) + } +} diff -r bfd185ad03e7 -r 42b710b0f883 rust/hwphysics/src/grid.rs --- a/rust/hwphysics/src/grid.rs Thu Jul 25 21:59:20 2019 +0300 +++ b/rust/hwphysics/src/grid.rs Thu Jul 25 22:31:24 2019 +0300 @@ -71,6 +71,8 @@ bin.dynamic_entries.push(*bounds); } + pub fn remove(&mut self, gear_id: GearId) {} + pub fn update_position( &mut self, gear_id: GearId, diff -r bfd185ad03e7 -r 42b710b0f883 rust/hwphysics/src/lib.rs --- a/rust/hwphysics/src/lib.rs Thu Jul 25 21:59:20 2019 +0300 +++ b/rust/hwphysics/src/lib.rs Thu Jul 25 22:31:24 2019 +0300 @@ -10,7 +10,7 @@ use crate::{ collision::{CollisionData, CollisionProcessor, ContactData}, - common::{GearData, GearDataAggregator, GearDataProcessor, GearId}, + common::{GearAllocator, GearData, GearDataAggregator, GearDataProcessor, GearId}, physics::{PhysicsData, PhysicsProcessor}, time::TimeProcessor, }; @@ -23,6 +23,7 @@ } pub struct World { + allocator: GearAllocator, physics: PhysicsProcessor, collision: CollisionProcessor, time: TimeProcessor, @@ -44,12 +45,26 @@ impl World { pub fn new(world_size: Size) -> Self { Self { + allocator: GearAllocator::new(), physics: PhysicsProcessor::new(), collision: CollisionProcessor::new(world_size), time: TimeProcessor::new(), } } + #[inline] + pub fn new_gear(&mut self) -> Option { + self.allocator.alloc() + } + + #[inline] + pub fn delete_gear(&mut self, gear_id: GearId) { + self.physics.remove(gear_id); + self.collision.remove(gear_id); + self.time.cancel(gear_id); + self.allocator.free(gear_id) + } + pub fn step(&mut self, time_step: FPNum, land: &Land2D) { let updates = self.physics.process(time_step); let collision = self.collision.process(land, &updates); diff -r bfd185ad03e7 -r 42b710b0f883 rust/hwphysics/src/physics.rs --- a/rust/hwphysics/src/physics.rs Thu Jul 25 21:59:20 2019 +0300 +++ b/rust/hwphysics/src/physics.rs Thu Jul 25 22:31:24 2019 +0300 @@ -35,12 +35,20 @@ self.gear_ids.len() } - fn push(&mut self, id: GearId, physics: PhysicsData) { - self.gear_ids.push(id); + fn push(&mut self, gear_id: GearId, physics: PhysicsData) { + self.gear_ids.push(gear_id); self.positions.push(physics.position); self.velocities.push(physics.velocity); } + fn remove(&mut self, gear_id: GearId) { + if let Some(index) = self.gear_ids.iter().position(|id| *id == gear_id) { + self.gear_ids.swap_remove(index); + self.positions.swap_remove(index); + self.velocities.swap_remove(index); + } + } + fn iter_pos_update(&mut self) -> impl Iterator { self.gear_ids .iter() @@ -66,6 +74,13 @@ self.gear_ids.push(gear_id); self.positions.push(physics.position); } + + fn remove(&mut self, gear_id: GearId) { + if let Some(index) = self.gear_ids.iter().position(|id| *id == gear_id) { + self.gear_ids.swap_remove(index); + self.positions.swap_remove(index); + } + } } pub struct PhysicsProcessor { @@ -149,4 +164,9 @@ self.dynamic_physics.push(gear_id, gear_data); } } + + fn remove(&mut self, gear_id: GearId) { + self.static_physics.remove(gear_id); + self.dynamic_physics.remove(gear_id) + } } diff -r bfd185ad03e7 -r 42b710b0f883 rust/hwphysics/src/time.rs --- a/rust/hwphysics/src/time.rs Thu Jul 25 21:59:20 2019 +0300 +++ b/rust/hwphysics/src/time.rs Thu Jul 25 22:31:24 2019 +0300 @@ -79,6 +79,8 @@ event_id } + pub fn cancel(&mut self, gear_id: GearId) {} + pub fn process(&mut self, time_step: FPNum) -> &OccurredEvents { self.timeouts.clear(); self.current_time += time_step; diff -r bfd185ad03e7 -r 42b710b0f883 rust/lib-hedgewars-engine/src/world.rs --- a/rust/lib-hedgewars-engine/src/world.rs Thu Jul 25 21:59:20 2019 +0300 +++ b/rust/lib-hedgewars-engine/src/world.rs Thu Jul 25 22:31:24 2019 +0300 @@ -28,7 +28,6 @@ map_renderer: Option, gear_renderer: Option, camera: Camera, - last_gear_id: GearId, } impl World { @@ -40,7 +39,6 @@ map_renderer: None, gear_renderer: None, camera: Camera::new(), - last_gear_id: std::num::NonZeroU16::new(1).unwrap(), } } @@ -128,15 +126,9 @@ } } - fn get_unused_gear_id(&mut self) -> GearId { - let id = self.last_gear_id; - self.last_gear_id = std::num::NonZeroU16::new(self.last_gear_id.get() + 1).unwrap(); - id - } - fn create_gear(&mut self, position: Point) { - let id = self.get_unused_gear_id(); if let Some(ref mut state) = self.game_state { + let id = state.physics.new_gear().unwrap(); let fp_position = FPPoint::new(position.x.into(), position.y.into()); state.physics.add_gear_data( id,