--- 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<u32>) {
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<T>(&mut self, gear_id: GearId, data: T)
+ where T: GearData,
+ Self: GearDataAggregator<T>
+ {
+ 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);
+ }
}