rust/hwphysics/src/data.rs
changeset 15829 d5e6c8c92d87
parent 15426 a027e60d7820
child 15941 8035f7452b48
--- a/rust/hwphysics/src/data.rs	Thu Jan 27 03:51:13 2022 +0300
+++ b/rust/hwphysics/src/data.rs	Fri Jan 28 02:33:44 2022 +0300
@@ -242,7 +242,7 @@
             block_masks: vec![],
             element_sizes: Box::new([0; 64]),
             element_alignments: Box::new([0; 64]),
-            lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(),
+            lookup: vec![LookupEntry::default(); u16::MAX as usize].into_boxed_slice(),
         }
     }
 
@@ -486,7 +486,7 @@
 
     pub fn register<T: 'static>(&mut self) {
         debug_assert!(!std::mem::needs_drop::<T>());
-        debug_assert!(size_of::<T>() <= u16::max_value() as usize);
+        debug_assert!(size_of::<T>() <= u16::MAX as usize);
 
         let id = TypeId::of::<T>();
         if size_of::<T>() == 0 {
@@ -533,6 +533,19 @@
         }
     }
 
+    pub fn get<T: 'static>(&self, gear_id: GearId) -> Option<&T> {
+        let entry = self.lookup[gear_id.get() as usize - 1];
+        match (entry.index, self.get_type_index::<T>()) {
+            (Some(index), Some(type_index)) => {
+                let block = &self.blocks[entry.block_index as usize];
+                block.component_blocks[type_index].map(|ptr| unsafe {
+                    &*(ptr.as_ptr() as *const T).add(index.get() as usize - 1)
+                })
+            }
+            _ => None,
+        }
+    }
+
     pub fn iter<T: TypeIter + 'static>(&mut self) -> DataIterator<T> {
         let mut arg_types = Vec::with_capacity(64);
         T::get_types(&mut arg_types);
@@ -614,6 +627,25 @@
     struct Tag;
 
     #[test]
+    fn direct_access() {
+        let mut manager = GearDataManager::new();
+        manager.register::<Datum>();
+        for i in 1..=5 {
+            manager.add(GearId::new(i as u16).unwrap(), &Datum { value: i * i });
+        }
+
+        for i in 1..=5 {
+            assert_eq!(
+                manager
+                    .get::<Datum>(GearId::new(i as u16).unwrap())
+                    .unwrap()
+                    .value,
+                i * i
+            );
+        }
+    }
+
+    #[test]
     fn single_component_iteration() {
         let mut manager = GearDataManager::new();
         manager.register::<Datum>();