diff -r a4c17cfaa4c9 -r abbb74b9cb62 rust/hwphysics/src/lib.rs --- a/rust/hwphysics/src/lib.rs Fri Nov 09 01:05:34 2018 +0300 +++ b/rust/hwphysics/src/lib.rs Fri Nov 09 03:36:21 2018 +0300 @@ -4,10 +4,16 @@ mod collision; use fpnum::FPNum; +use integral_geometry::Size; use land2d::Land2D; use crate::{ - common::GearId, + common::{ + GearId, + GearData, + GearDataAggregator, + GearDataProcessor + }, physics::{ PhysicsProcessor, PhysicsData @@ -31,19 +37,72 @@ collision: CollisionProcessor, } +macro_rules! processor_map { + ( $data_type: ident => $field: ident ) => { + impl GearDataAggregator<$data_type> for World { + fn find_processor(&mut self) -> &mut GearDataProcessor<$data_type> { + &mut self.$field + } + } + } +} + +processor_map!(PhysicsData => physics); +processor_map!(CollisionData => collision); + impl World { + pub fn new(world_size: Size) -> Self { + Self { + physics: PhysicsProcessor::new(), + collision: CollisionProcessor::new(world_size) + } + } + pub fn step(&mut self, time_step: FPNum, land: &Land2D) { let updates = self.physics.process(time_step); self.collision.process(land, &updates); } - pub fn add_gear(&mut self, data: JoinedData) { - self.physics.push(data.gear_id, data.physics); - self.collision.push(data.gear_id, data.physics, data.collision); + pub fn add_gear_data(&mut self, gear_id: GearId, data: T) + where T: GearData, + Self: GearDataAggregator + { + self.find_processor().add(gear_id, data); } } #[cfg(test)] mod tests { + use crate::{ + World, + physics::PhysicsData, + collision::{CollisionData, CircleBounds} + }; + use fpnum::{FPNum, FPPoint, fp}; + use integral_geometry::Size; + use land2d::Land2D; + #[test] + fn data_flow() { + let world_size = Size::new(2048, 2048); + + let mut world = World::new(world_size); + let gear_id = 46631; + + world.add_gear_data(gear_id, PhysicsData { + position: FPPoint::zero(), + velocity: FPPoint::unit_y() + }); + + world.add_gear_data(gear_id, CollisionData { + bounds: CircleBounds { + center: FPPoint::zero(), + radius: fp!(10) + } + }); + + let land = Land2D::new(Size::new(world_size.width - 2, world_size.height - 2), 0); + + world.step(fp!(1), &land); + } }