implement empty gear lookup entries
authoralfadur
Tue, 30 Jul 2019 22:59:06 +0300
changeset 15287 478d5372eb4a
parent 15286 8095853811a6
child 15289 ae8e14d14596
implement empty gear lookup entries
rust/hwphysics/src/collision.rs
rust/hwphysics/src/common.rs
rust/hwphysics/src/physics.rs
rust/hwphysics/src/time.rs
--- a/rust/hwphysics/src/collision.rs	Tue Jul 30 19:53:23 2019 +0300
+++ b/rust/hwphysics/src/collision.rs	Tue Jul 30 22:59:06 2019 +0300
@@ -3,11 +3,10 @@
 use crate::{
     common::{GearData, GearDataProcessor, GearId},
     grid::Grid,
-    physics::PhysicsData,
 };
 
 use fpnum::*;
-use integral_geometry::{GridIndex, Point, Size};
+use integral_geometry::{Point, Size};
 use land2d::Land2D;
 
 pub fn fppoint_round(point: &FPPoint) -> Point {
@@ -151,4 +150,8 @@
     fn remove(&mut self, gear_id: GearId) {
         self.grid.remove(gear_id);
     }
+
+    fn get(&mut self, gear_id: GearId) -> Option<CollisionData> {
+        None
+    }
 }
--- a/rust/hwphysics/src/common.rs	Tue Jul 30 19:53:23 2019 +0300
+++ b/rust/hwphysics/src/common.rs	Tue Jul 30 22:59:06 2019 +0300
@@ -1,4 +1,4 @@
-use fpnum::{fp, FPNum};
+use fpnum::FPNum;
 use std::{
     collections::BinaryHeap,
     num::NonZeroU16,
@@ -40,6 +40,7 @@
 pub trait GearDataProcessor<T: GearData> {
     fn add(&mut self, gear_id: GearId, gear_data: T);
     fn remove(&mut self, gear_id: GearId);
+    fn get(&mut self, gear_id: GearId) -> Option<T>;
 }
 
 pub trait GearDataAggregator<T: GearData> {
@@ -75,13 +76,34 @@
 
 #[derive(Clone, Copy, Default)]
 pub struct LookupEntry<T> {
-    pub index: u16,
-    pub value: T,
+    index: Option<NonZeroU16>,
+    value: T,
 }
 
 impl<T> LookupEntry<T> {
-    pub fn new(index: u16, value: T) -> Self {
-        Self { index, value }
+    #[inline]
+    pub fn index(&self) -> u16 {
+        self.index.map(|i| i.get()).unwrap_or(0) - 1
+    }
+
+    #[inline]
+    pub fn set_index(&mut self, index: u16) {
+        self.index = unsafe { Some(NonZeroU16::new_unchecked(index.saturating_add(1))) };
+    }
+
+    #[inline]
+    pub fn value(&self) -> &T {
+        &self.value
+    }
+
+    #[inline]
+    pub fn value_mut(&mut self) -> &mut T {
+        &mut self.value
+    }
+
+    #[inline]
+    pub fn set_value(&mut self, value: T) {
+        self.value = value;
     }
 }
 
@@ -98,14 +120,31 @@
 }
 
 impl<T> GearDataLookup<T> {
-    pub fn get(&self, gear_id: GearId) -> &LookupEntry<T> {
+    pub fn add(&mut self, gear_id: GearId, index: u16, value: T) {
         // All possible Gear IDs are valid indices
-        unsafe { self.lookup.get_unchecked(gear_id.get() as usize - 1) }
+        let entry = unsafe { self.lookup.get_unchecked_mut(gear_id.get() as usize - 1) };
+        entry.set_index(index);
+        entry.set_value(value);
     }
 
-    pub fn get_mut(&mut self, gear_id: GearId) -> &mut LookupEntry<T> {
+    pub fn get(&self, gear_id: GearId) -> Option<&LookupEntry<T>> {
         // All possible Gear IDs are valid indices
-        unsafe { self.lookup.get_unchecked_mut(gear_id.get() as usize - 1) }
+        let entry = unsafe { self.lookup.get_unchecked(gear_id.get() as usize - 1) };
+        if let Some(index) = entry.index {
+            Some(entry)
+        } else {
+            None
+        }
+    }
+
+    pub fn get_mut(&mut self, gear_id: GearId) -> Option<&mut LookupEntry<T>> {
+        // All possible Gear IDs are valid indices
+        let entry = unsafe { self.lookup.get_unchecked_mut(gear_id.get() as usize - 1) };
+        if let Some(index) = entry.index {
+            Some(entry)
+        } else {
+            None
+        }
     }
 }
 
@@ -113,12 +152,12 @@
     type Output = LookupEntry<T>;
 
     fn index(&self, index: GearId) -> &Self::Output {
-        self.get(index)
+        self.get(index).unwrap()
     }
 }
 
 impl<T> IndexMut<GearId> for GearDataLookup<T> {
     fn index_mut(&mut self, index: GearId) -> &mut Self::Output {
-        self.get_mut(index)
+        self.get_mut(index).unwrap()
     }
 }
--- a/rust/hwphysics/src/physics.rs	Tue Jul 30 19:53:23 2019 +0300
+++ b/rust/hwphysics/src/physics.rs	Tue Jul 30 22:59:06 2019 +0300
@@ -1,6 +1,5 @@
-use crate::common::{GearData, GearDataLookup, GearDataProcessor, GearId, LookupEntry, Millis};
+use crate::common::{GearData, GearDataLookup, GearDataProcessor, GearId, Millis};
 use fpnum::*;
-use integral_geometry::{GridIndex, Point, Size};
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 pub struct PhysicsData {
@@ -164,19 +163,40 @@
             self.static_physics.push(gear_id, gear_data)
         };
 
-        self.gear_lookup[gear_id] = LookupEntry::new(index, is_dynamic);
+        self.gear_lookup.add(gear_id, index, is_dynamic);
     }
 
     fn remove(&mut self, gear_id: GearId) {
-        let location = self.gear_lookup[gear_id];
-        let relocated_gear_id = if location.value {
-            self.dynamic_physics.remove(location.index as usize)
+        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 {
-            self.static_physics.remove(location.index as usize)
-        };
-
-        if let Some(id) = relocated_gear_id {
-            self.gear_lookup[id].index = location.index;
+            None
         }
     }
 }
--- a/rust/hwphysics/src/time.rs	Tue Jul 30 19:53:23 2019 +0300
+++ b/rust/hwphysics/src/time.rs	Tue Jul 30 22:59:06 2019 +0300
@@ -1,4 +1,4 @@
-use crate::common::{GearDataProcessor, GearId, Millis};
+use crate::common::{GearId, Millis};
 use std::{
     cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
     collections::BinaryHeap,