29 pub struct World { |
35 pub struct World { |
30 physics: PhysicsProcessor, |
36 physics: PhysicsProcessor, |
31 collision: CollisionProcessor, |
37 collision: CollisionProcessor, |
32 } |
38 } |
33 |
39 |
|
40 macro_rules! processor_map { |
|
41 ( $data_type: ident => $field: ident ) => { |
|
42 impl GearDataAggregator<$data_type> for World { |
|
43 fn find_processor(&mut self) -> &mut GearDataProcessor<$data_type> { |
|
44 &mut self.$field |
|
45 } |
|
46 } |
|
47 } |
|
48 } |
|
49 |
|
50 processor_map!(PhysicsData => physics); |
|
51 processor_map!(CollisionData => collision); |
|
52 |
34 impl World { |
53 impl World { |
|
54 pub fn new(world_size: Size) -> Self { |
|
55 Self { |
|
56 physics: PhysicsProcessor::new(), |
|
57 collision: CollisionProcessor::new(world_size) |
|
58 } |
|
59 } |
|
60 |
35 pub fn step(&mut self, time_step: FPNum, land: &Land2D<u32>) { |
61 pub fn step(&mut self, time_step: FPNum, land: &Land2D<u32>) { |
36 let updates = self.physics.process(time_step); |
62 let updates = self.physics.process(time_step); |
37 self.collision.process(land, &updates); |
63 self.collision.process(land, &updates); |
38 } |
64 } |
39 |
65 |
40 pub fn add_gear(&mut self, data: JoinedData) { |
66 pub fn add_gear_data<T>(&mut self, gear_id: GearId, data: T) |
41 self.physics.push(data.gear_id, data.physics); |
67 where T: GearData, |
42 self.collision.push(data.gear_id, data.physics, data.collision); |
68 Self: GearDataAggregator<T> |
|
69 { |
|
70 self.find_processor().add(gear_id, data); |
43 } |
71 } |
44 } |
72 } |
45 |
73 |
46 #[cfg(test)] |
74 #[cfg(test)] |
47 mod tests { |
75 mod tests { |
|
76 use crate::{ |
|
77 World, |
|
78 physics::PhysicsData, |
|
79 collision::{CollisionData, CircleBounds} |
|
80 }; |
|
81 use fpnum::{FPNum, FPPoint, fp}; |
|
82 use integral_geometry::Size; |
|
83 use land2d::Land2D; |
48 |
84 |
|
85 #[test] |
|
86 fn data_flow() { |
|
87 let world_size = Size::new(2048, 2048); |
|
88 |
|
89 let mut world = World::new(world_size); |
|
90 let gear_id = 46631; |
|
91 |
|
92 world.add_gear_data(gear_id, PhysicsData { |
|
93 position: FPPoint::zero(), |
|
94 velocity: FPPoint::unit_y() |
|
95 }); |
|
96 |
|
97 world.add_gear_data(gear_id, CollisionData { |
|
98 bounds: CircleBounds { |
|
99 center: FPPoint::zero(), |
|
100 radius: fp!(10) |
|
101 } |
|
102 }); |
|
103 |
|
104 let land = Land2D::new(Size::new(world_size.width - 2, world_size.height - 2), 0); |
|
105 |
|
106 world.step(fp!(1), &land); |
|
107 } |
49 } |
108 } |