rust/hwphysics/src/lib.rs
branchhedgeroid
changeset 15510 7030706266df
parent 15383 701ad89a9f2a
child 15762 84c07aa94b61
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rust/hwphysics/src/lib.rs	Fri Dec 06 22:20:53 2019 +0100
@@ -0,0 +1,108 @@
+pub mod collision;
+pub mod common;
+mod data;
+mod grid;
+pub mod physics;
+pub mod time;
+
+use integral_geometry::Size;
+use land2d::Land2D;
+
+use crate::{
+    collision::CollisionProcessor,
+    common::{GearAllocator, GearId, Millis},
+    data::GearDataManager,
+    physics::PhysicsProcessor,
+    time::TimeProcessor,
+};
+
+pub struct World {
+    allocator: GearAllocator,
+    data: GearDataManager,
+    physics: PhysicsProcessor,
+    collision: CollisionProcessor,
+    time: TimeProcessor,
+}
+
+impl World {
+    pub fn new(world_size: Size) -> Self {
+        let mut data = GearDataManager::new();
+        PhysicsProcessor::register_components(&mut data);
+        CollisionProcessor::register_components(&mut data);
+
+        Self {
+            data,
+            allocator: GearAllocator::new(),
+            physics: PhysicsProcessor::new(),
+            collision: CollisionProcessor::new(world_size),
+            time: TimeProcessor::new(),
+        }
+    }
+
+    #[inline]
+    pub fn new_gear(&mut self) -> Option<GearId> {
+        self.allocator.alloc()
+    }
+
+    #[inline]
+    pub fn delete_gear(&mut self, gear_id: GearId) {
+        self.data.remove_all(gear_id);
+        self.collision.remove(gear_id);
+        self.time.cancel(gear_id);
+        self.allocator.free(gear_id)
+    }
+
+    pub fn step(&mut self, time_step: Millis, land: &Land2D<u32>) {
+        let updates = if time_step == Millis::new(1) {
+            self.physics.process_single_tick(&mut self.data)
+        } else {
+            self.physics
+                .process_multiple_ticks(&mut self.data, time_step)
+        };
+        let collisions = self.collision.process(land, &updates);
+        let events = self.time.process(time_step);
+    }
+
+    #[inline]
+    pub fn add_gear_data<T: Clone + 'static>(&mut self, gear_id: GearId, data: &T) {
+        self.data.add(gear_id, data);
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{
+        collision::{CircleBounds, CollisionData},
+        common::Millis,
+        physics::{PositionData, VelocityData},
+        World,
+    };
+    use fpnum::{fp, FPNum, FPPoint};
+    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 = world.new_gear().unwrap();
+
+        world.add_gear_data(gear_id, &PositionData(FPPoint::zero()));
+        world.add_gear_data(gear_id, &VelocityData(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(Millis::new(1), &land);
+    }
+}