rust/hwphysics/src/data.rs
changeset 15359 dff37ac61dcf
parent 15310 0076bf602969
child 15361 277acc9f9fcf
equal deleted inserted replaced
15358:35c331f9308e 15359:dff37ac61dcf
     1 use std::any::{Any, TypeId};
     1 use super::common::GearId;
     2 
     2 use std::{
     3 const BLOCK_SIZE: usize = 8192;
     3     any::TypeId,
     4 
     4     mem::{size_of, MaybeUninit},
     5 pub trait TypeTuple {
     5     num::NonZeroU16,
     6     type Storage: Default;
     6     ptr::NonNull,
     7 
     7     slice,
       
     8 };
       
     9 
       
    10 pub trait TypeTuple: Sized {
     8     fn len() -> usize;
    11     fn len() -> usize;
     9     fn get_types(dest: &mut Vec<TypeId>);
    12     fn get_types(dest: &mut Vec<TypeId>);
    10 }
    13     unsafe fn iter<F>(slices: &[NonNull<u8>], count: usize, f: F)
    11 
    14     where
    12 //TODO macroise this template for tuples up to sufficient size
    15         F: Fn(Self);
    13 impl<T: 'static> TypeTuple for (T,) {
    16 }
    14     type Storage = (Vec<T>,);
    17 
    15 
    18 impl<T: 'static> TypeTuple for (&T,) {
    16     #[inline]
       
    17     fn len() -> usize {
    19     fn len() -> usize {
    18         1
    20         1
    19     }
    21     }
    20 
    22 
    21     #[inline]
       
    22     fn get_types(dest: &mut Vec<TypeId>) {
    23     fn get_types(dest: &mut Vec<TypeId>) {
    23         dest.push(TypeId::of::<T>());
    24         dest.push(TypeId::of::<T>());
    24     }
    25     }
    25 }
    26 
    26 
    27     unsafe fn iter<F>(slices: &[NonNull<u8>], count: usize, f: F)
    27 pub struct GearDataCollection<T: TypeTuple> {
    28     where
    28     len: usize,
    29         F: Fn(Self),
    29     blocks: T::Storage,
    30     {
    30 }
    31         let slice1 = slice::from_raw_parts(slices[0].as_ptr() as *const T, count);
    31 
    32         for i in 0..count {
    32 impl<T: TypeTuple> GearDataCollection<T> {
    33             f((slice1.get_unchecked(i),));
    33     fn new() -> Self {
    34         }
       
    35     }
       
    36 }
       
    37 
       
    38 const BLOCK_SIZE: usize = 32768;
       
    39 
       
    40 struct DataBlock {
       
    41     max_elements: u16,
       
    42     elements_count: u16,
       
    43     data: Box<[u8; BLOCK_SIZE]>,
       
    44     blocks: [Option<NonNull<u8>>; 64],
       
    45 }
       
    46 
       
    47 impl Unpin for DataBlock {}
       
    48 
       
    49 impl DataBlock {
       
    50     fn new(mask: u64, element_sizes: &[u16; 64]) -> Self {
       
    51         let total_size: u16 = element_sizes
       
    52             .iter()
       
    53             .enumerate()
       
    54             .filter(|(i, _)| mask & (164 << *i as u64) != 0)
       
    55             .map(|(_, size)| *size)
       
    56             .sum();
       
    57         let max_elements = (BLOCK_SIZE / total_size as usize) as u16;
       
    58 
       
    59         let mut data: Box<[u8; BLOCK_SIZE]> =
       
    60             Box::new(unsafe { std::mem::MaybeUninit::uninit().assume_init() });
       
    61         let mut blocks = [None; 64];
       
    62         let mut offset = 0;
       
    63 
       
    64         for i in 0..64 {
       
    65             if mask & (164 << i) != 0 {
       
    66                 blocks[i] = Some(NonNull::new(data[offset..].as_mut_ptr()).unwrap());
       
    67                 offset += element_sizes[i] as usize * max_elements as usize;
       
    68             }
       
    69         }
    34         Self {
    70         Self {
    35             len: 0,
    71             elements_count: 0,
    36             blocks: T::Storage::default(),
    72             max_elements,
    37         }
    73             data,
    38     }
    74             blocks,
    39 
    75         }
    40     fn iter<F: Fn(T)>(&self, f: F) {}
    76     }
    41 }
    77 
    42 
    78     fn is_full(&self) -> bool {
    43 pub struct GearDataGroup {
    79         self.elements_count == self.max_elements
    44     group_selector: u64,
    80     }
    45     data: Box<dyn Any + 'static>,
    81 }
    46 }
    82 
    47 
    83 #[derive(Clone, Copy, Debug, Default)]
    48 impl GearDataGroup {
    84 pub struct LookupEntry {
    49     fn iter() {}
    85     index: Option<NonZeroU16>,
       
    86     block_index: u16,
    50 }
    87 }
    51 
    88 
    52 pub struct GearDataManager {
    89 pub struct GearDataManager {
    53     types: Vec<TypeId>,
    90     types: Vec<TypeId>,
    54     groups: Vec<GearDataGroup>,
    91     blocks: Vec<DataBlock>,
       
    92     block_masks: Vec<u64>,
       
    93     element_sizes: Box<[u16; 64]>,
       
    94     lookup: Box<[LookupEntry]>,
    55 }
    95 }
    56 
    96 
    57 impl GearDataManager {
    97 impl GearDataManager {
    58     pub fn new() -> Self {
    98     pub fn new() -> Self {
    59         Self {
    99         Self {
    60             types: vec![],
   100             types: vec![],
    61             groups: vec![],
   101             blocks: vec![],
       
   102             block_masks: vec![],
       
   103             element_sizes: Box::new([0; 64]),
       
   104             lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(),
       
   105         }
       
   106     }
       
   107 
       
   108     #[inline]
       
   109     fn get_type_index<T: 'static>(&self) -> Option<usize> {
       
   110         let type_id = TypeId::of::<T>();
       
   111         self.types.iter().position(|id| *id == type_id)
       
   112     }
       
   113 
       
   114     fn move_between_blocks(&mut self, from_block_index: u16, from_index: u16, to_block_index: u16) {
       
   115         let source_mask = self.block_masks[from_block_index as usize];
       
   116         let destination_mask = self.block_masks[to_block_index as usize];
       
   117         debug_assert!(source_mask & destination_mask == source_mask);
       
   118 
       
   119         let source = &self.blocks[from_block_index as usize];
       
   120         let destination = &self.blocks[to_block_index as usize];
       
   121         for i in 0..64 {
       
   122             unimplemented!()
       
   123         }
       
   124     }
       
   125 
       
   126     fn add_to_block<T>(&mut self, block_index: u16, value: &T) {
       
   127         unimplemented!()
       
   128     }
       
   129 
       
   130     fn remove_from_block(&mut self, block_index: u16, index: u16) {
       
   131         unimplemented!()
       
   132     }
       
   133 
       
   134     #[inline]
       
   135     fn ensure_group(&mut self, mask: u64) -> u16 {
       
   136         if let Some(index) = self
       
   137             .block_masks
       
   138             .iter()
       
   139             .enumerate()
       
   140             .position(|(i, m)| *m == mask && !self.blocks[i].is_full())
       
   141         {
       
   142             index as u16
       
   143         } else {
       
   144             self.blocks.push(DataBlock::new(mask, &self.element_sizes));
       
   145             (self.blocks.len() - 1) as u16
       
   146         }
       
   147     }
       
   148 
       
   149     pub fn add<T: Clone + 'static>(&mut self, gear_id: GearId, value: &T) {
       
   150         if let Some(type_index) = self.get_type_index::<T>() {
       
   151             let type_bit = 1u64 << type_index as u64;
       
   152             let entry = self.lookup[gear_id.get() as usize - 1];
       
   153 
       
   154             if let Some(index) = entry.index {
       
   155                 let mask = self.block_masks[entry.block_index as usize];
       
   156                 let new_mask = mask | type_bit;
       
   157 
       
   158                 if new_mask != mask {
       
   159                     let dest_block_index = self.ensure_group(new_mask);
       
   160                     self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index);
       
   161                 }
       
   162             } else {
       
   163                 let dest_block_index = self.ensure_group(type_bit);
       
   164                 self.add_to_block(dest_block_index, value);
       
   165             }
       
   166         } else {
       
   167             panic!("Unregistered type")
       
   168         }
       
   169     }
       
   170 
       
   171     pub fn remove<T: 'static>(&mut self, gear_id: GearId) {
       
   172         if let Some(type_index) = self.get_type_index::<T>() {
       
   173             let entry = self.lookup[gear_id.get() as usize - 1];
       
   174             if let Some(index) = entry.index {
       
   175                 self.remove_from_block(entry.block_index, index.get() - 1);
       
   176             }
    62         }
   177         }
    63     }
   178     }
    64 
   179 
    65     pub fn register<T: 'static>(&mut self) {
   180     pub fn register<T: 'static>(&mut self) {
       
   181         assert!(!std::mem::needs_drop::<T>());
    66         assert!(self.types.len() <= 64);
   182         assert!(self.types.len() <= 64);
       
   183         assert!(size_of::<T>() <= u16::max_value() as usize);
       
   184 
    67         let id = TypeId::of::<T>();
   185         let id = TypeId::of::<T>();
    68         if !self.types.contains(&id) {
   186         if !self.types.contains(&id) {
       
   187             self.element_sizes[self.types.len()] = size_of::<T>() as u16;
    69             self.types.push(id);
   188             self.types.push(id);
    70         }
   189         }
    71     }
   190     }
    72 
   191 
    73     fn create_selector(&self, types: &[TypeId]) -> u64 {
   192     fn create_selector(&self, types: &[TypeId]) -> u64 {
    74         let mut selector = 0u64;
   193         let mut selector = 0u64;
    75         for (i, typ) in self.types.iter().enumerate() {
   194         for (i, typ) in self.types.iter().enumerate() {
    76             if types.contains(&typ) {
   195             if types.contains(&typ) {
    77                 selector |= 1 << (i as u64)
   196                 selector |= 1u64 << (i as u64)
    78             }
   197             }
    79         }
   198         }
    80         selector
   199         selector
    81     }
   200     }
    82 
   201 
    83     pub fn iter<T: TypeTuple + 'static, F: Fn(T) + Copy>(&self, f: F) {
   202     pub fn iter<T: TypeTuple + 'static, F: Fn(T) + Copy>(&self, f: F) {
    84         let mut types = vec![];
   203         let mut types = vec![];
    85         T::get_types(&mut types);
   204         T::get_types(&mut types);
       
   205         let types_count = types.len();
       
   206 
    86         let selector = self.create_selector(&types);
   207         let selector = self.create_selector(&types);
    87         for group in &self.groups {
   208         for (block_index, mask) in self.block_masks.iter().enumerate() {
    88             if group.group_selector & selector == selector {
   209             if mask & selector == selector {
    89                 group
   210                 let block = &self.blocks[block_index];
    90                     .data
   211                 for element_index in 0..block.max_elements {
    91                     .downcast_ref::<GearDataCollection<T>>()
   212                     unimplemented!()
    92                     .unwrap()
   213                 }
    93                     .iter(f);
   214             }
    94             }
   215         }
    95         }
   216     }
    96     }
   217 }
    97 }
   218 
       
   219 #[cfg(test)]
       
   220 mod test {
       
   221     use super::GearDataManager;
       
   222 
       
   223     struct Datum {
       
   224         value: u32,
       
   225     }
       
   226 
       
   227     #[test]
       
   228     fn iteration() {
       
   229         let mut manager = GearDataManager::new();
       
   230         manager.register::<Datum>();
       
   231         manager.iter(|d: (&Datum,)| {});
       
   232     }
       
   233 }