rust/hwphysics/src/physics.rs
changeset 15401 6e3e5be8b2e2
parent 15303 478d5372eb4a
child 15402 52844baced17
--- a/rust/hwphysics/src/physics.rs	Wed Aug 28 22:53:40 2019 +0300
+++ b/rust/hwphysics/src/physics.rs	Wed Aug 28 23:06:34 2019 +0300
@@ -1,97 +1,18 @@
-use crate::common::{GearData, GearDataLookup, GearDataProcessor, GearId, Millis};
+use crate::{
+    common::{GearId, Millis},
+    data::GearDataManager,
+};
 use fpnum::*;
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct PhysicsData {
-    pub position: FPPoint,
-    pub velocity: FPPoint,
-}
-
-impl GearData for PhysicsData {}
-
-impl PhysicsData {
-    pub fn new(position: FPPoint, velocity: FPPoint) -> Self {
-        Self { position, velocity }
-    }
-}
-
-pub struct DynamicPhysicsCollection {
-    gear_ids: Vec<GearId>,
-    positions: Vec<FPPoint>,
-    velocities: Vec<FPPoint>,
-}
-
-impl DynamicPhysicsCollection {
-    fn new() -> Self {
-        Self {
-            gear_ids: Vec::new(),
-            positions: Vec::new(),
-            velocities: Vec::new(),
-        }
-    }
-
-    fn len(&self) -> usize {
-        self.gear_ids.len()
-    }
-
-    fn push(&mut self, gear_id: GearId, physics: PhysicsData) -> u16 {
-        self.gear_ids.push(gear_id);
-        self.positions.push(physics.position);
-        self.velocities.push(physics.velocity);
-
-        (self.gear_ids.len() - 1) as u16
-    }
+#[repr(transparent)]
+pub struct PositionData(pub FPPoint);
 
-    fn remove(&mut self, index: usize) -> Option<GearId> {
-        self.gear_ids.swap_remove(index);
-        self.positions.swap_remove(index);
-        self.velocities.swap_remove(index);
-
-        self.gear_ids.get(index).cloned()
-    }
-
-    fn iter_pos_update(&mut self) -> impl Iterator<Item = (GearId, (&mut FPPoint, &FPPoint))> {
-        self.gear_ids
-            .iter()
-            .cloned()
-            .zip(self.positions.iter_mut().zip(self.velocities.iter()))
-    }
-}
-
-pub struct StaticPhysicsCollection {
-    gear_ids: Vec<GearId>,
-    positions: Vec<FPPoint>,
-}
-
-impl StaticPhysicsCollection {
-    fn new() -> Self {
-        Self {
-            gear_ids: Vec::new(),
-            positions: Vec::new(),
-        }
-    }
-
-    fn push(&mut self, gear_id: GearId, physics: PhysicsData) -> u16 {
-        self.gear_ids.push(gear_id);
-        self.positions.push(physics.position);
-
-        (self.gear_ids.len() - 1) as u16
-    }
-
-    fn remove(&mut self, index: usize) -> Option<GearId> {
-        self.gear_ids.swap_remove(index);
-        self.positions.swap_remove(index);
-
-        self.gear_ids.get(index).cloned()
-    }
-}
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[repr(transparent)]
+pub struct VelocityData(pub FPPoint);
 
 pub struct PhysicsProcessor {
-    gear_lookup: GearDataLookup<bool>,
-    dynamic_physics: DynamicPhysicsCollection,
-    static_physics: StaticPhysicsCollection,
-
-    physics_cleanup: Vec<GearId>,
     position_updates: PositionUpdates,
 }
 
@@ -128,75 +49,31 @@
 }
 
 impl PhysicsProcessor {
+    pub fn register_components(data: &mut GearDataManager) {
+        data.register::<PositionData>();
+        data.register::<VelocityData>();
+    }
+
     pub fn new() -> Self {
         Self {
-            gear_lookup: GearDataLookup::new(),
-            dynamic_physics: DynamicPhysicsCollection::new(),
-            static_physics: StaticPhysicsCollection::new(),
-            physics_cleanup: Vec::new(),
-            position_updates: PositionUpdates::new(0),
+            position_updates: PositionUpdates::new(64),
         }
     }
 
-    pub fn process(&mut self, time_step: Millis) -> &PositionUpdates {
+    pub fn process(&mut self, data: &mut GearDataManager, time_step: Millis) -> &PositionUpdates {
         let fp_step = time_step.to_fixed();
         self.position_updates.clear();
-        for (gear_id, (pos, vel)) in self.dynamic_physics.iter_pos_update() {
-            let old_pos = *pos;
-            *pos += *vel * fp_step;
-            if !vel.is_zero() {
-                self.position_updates.push(gear_id, &old_pos, pos)
-            } else {
-                self.physics_cleanup.push(gear_id)
-            }
-        }
+
+        data.iter_id(
+            |gear_id, (pos, vel): (&mut PositionData, &mut VelocityData)| {
+                if !vel.0.is_zero() {
+                    let old_pos = pos.0;
+                    pos.0 += vel.0 * fp_step;
+                    self.position_updates.push(gear_id, &old_pos, &pos.0)
+                }
+            },
+        );
+
         &self.position_updates
     }
 }
-
-impl GearDataProcessor<PhysicsData> for PhysicsProcessor {
-    fn add(&mut self, gear_id: GearId, gear_data: PhysicsData) {
-        let is_dynamic = !gear_data.velocity.is_zero();
-        let index = if is_dynamic {
-            self.dynamic_physics.push(gear_id, gear_data)
-        } else {
-            self.static_physics.push(gear_id, gear_data)
-        };
-
-        self.gear_lookup.add(gear_id, index, is_dynamic);
-    }
-
-    fn remove(&mut self, gear_id: GearId) {
-        if let Some(entry) = self.gear_lookup.get(gear_id) {
-            let relocated_gear_id = if *entry.value() {
-                self.dynamic_physics.remove(entry.index() as usize)
-            } else {
-                self.static_physics.remove(entry.index() as usize)
-            };
-
-            if let Some(id) = relocated_gear_id {
-                let index = entry.index();
-                self.gear_lookup[id].set_index(index);
-            }
-        }
-    }
-
-    fn get(&mut self, gear_id: GearId) -> Option<PhysicsData> {
-        if let Some(entry) = self.gear_lookup.get(gear_id) {
-            let data = if *entry.value() {
-                PhysicsData {
-                    position: self.dynamic_physics.positions[entry.index() as usize],
-                    velocity: self.dynamic_physics.velocities[entry.index() as usize],
-                }
-            } else {
-                PhysicsData {
-                    position: self.static_physics.positions[entry.index() as usize],
-                    velocity: FPPoint::zero(),
-                }
-            };
-            Some(data)
-        } else {
-            None
-        }
-    }
-}