--- a/rust/hwphysics/src/data.rs Thu Jan 27 03:51:13 2022 +0300
+++ b/rust/hwphysics/src/data.rs Fri Jan 28 02:33:44 2022 +0300
@@ -242,7 +242,7 @@
block_masks: vec![],
element_sizes: Box::new([0; 64]),
element_alignments: Box::new([0; 64]),
- lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(),
+ lookup: vec![LookupEntry::default(); u16::MAX as usize].into_boxed_slice(),
}
}
@@ -486,7 +486,7 @@
pub fn register<T: 'static>(&mut self) {
debug_assert!(!std::mem::needs_drop::<T>());
- debug_assert!(size_of::<T>() <= u16::max_value() as usize);
+ debug_assert!(size_of::<T>() <= u16::MAX as usize);
let id = TypeId::of::<T>();
if size_of::<T>() == 0 {
@@ -533,6 +533,19 @@
}
}
+ pub fn get<T: 'static>(&self, gear_id: GearId) -> Option<&T> {
+ let entry = self.lookup[gear_id.get() as usize - 1];
+ match (entry.index, self.get_type_index::<T>()) {
+ (Some(index), Some(type_index)) => {
+ let block = &self.blocks[entry.block_index as usize];
+ block.component_blocks[type_index].map(|ptr| unsafe {
+ &*(ptr.as_ptr() as *const T).add(index.get() as usize - 1)
+ })
+ }
+ _ => None,
+ }
+ }
+
pub fn iter<T: TypeIter + 'static>(&mut self) -> DataIterator<T> {
let mut arg_types = Vec::with_capacity(64);
T::get_types(&mut arg_types);
@@ -614,6 +627,25 @@
struct Tag;
#[test]
+ fn direct_access() {
+ let mut manager = GearDataManager::new();
+ manager.register::<Datum>();
+ for i in 1..=5 {
+ manager.add(GearId::new(i as u16).unwrap(), &Datum { value: i * i });
+ }
+
+ for i in 1..=5 {
+ assert_eq!(
+ manager
+ .get::<Datum>(GearId::new(i as u16).unwrap())
+ .unwrap()
+ .value,
+ i * i
+ );
+ }
+ }
+
+ #[test]
fn single_component_iteration() {
let mut manager = GearDataManager::new();
manager.register::<Datum>();
--- a/rust/hwphysics/src/lib.rs Thu Jan 27 03:51:13 2022 +0300
+++ b/rust/hwphysics/src/lib.rs Fri Jan 28 02:33:44 2022 +0300
@@ -6,7 +6,10 @@
use integral_geometry::PotSize;
use land2d::Land2D;
+use std::any::{Any, TypeId};
+use crate::collision::CollisionData;
+use crate::physics::VelocityData;
use crate::{
collision::CollisionProcessor,
common::{GearAllocator, GearId, Millis},
@@ -52,9 +55,20 @@
let collisions = self.collision.process(land, &updates);
}
- #[inline]
pub fn add_gear_data<T: Clone + 'static>(&mut self, gear_id: GearId, data: &T) {
self.data.add(gear_id, data);
+ if TypeId::of::<T>() == TypeId::of::<VelocityData>() {
+ self.collision.remove(gear_id);
+ }
+ }
+
+ pub fn remove_gear_data<T: Clone + 'static>(&mut self, gear_id: GearId) {
+ self.data.remove::<T>(gear_id);
+ if TypeId::of::<T>() == TypeId::of::<VelocityData>() {
+ if let Some(collision_data) = self.data.get::<CollisionData>(gear_id) {
+ self.collision.add(gear_id, *collision_data);
+ }
+ }
}
#[inline]
@@ -72,12 +86,12 @@
World,
};
use fpnum::{fp, FPNum, FPPoint};
- use integral_geometry::PotSize;
+ use integral_geometry::{PotSize, Size};
use land2d::Land2D;
#[test]
fn data_flow() {
- let world_size = PotSize::new(2048, 2048).unwrap;
+ let world_size = PotSize::new(2048, 2048).unwrap();
let mut world = World::new(world_size);
let gear_id = world.new_gear().unwrap();
@@ -95,7 +109,10 @@
},
);
- let land = Land2D::new(Size::new(world_size.width - 2, world_size.height - 2), 0);
+ let land = Land2D::new(
+ Size::new(world_size.width() - 2, world_size.height() - 2),
+ 0,
+ );
world.step(Millis::new(1), &land);
}