rust/hwphysics/src/data.rs
changeset 15387 90a79670de52
parent 15381 52844baced17
child 15392 b387a51705ac
equal deleted inserted replaced
15386:2805681aca54 15387:90a79670de52
     8     slice,
     8     slice,
     9 };
     9 };
    10 
    10 
    11 pub trait TypeTuple: Sized {
    11 pub trait TypeTuple: Sized {
    12     fn get_types(types: &mut Vec<TypeId>);
    12     fn get_types(types: &mut Vec<TypeId>);
    13     unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: F);
    13     unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, f: F);
    14 }
    14 }
    15 
    15 
    16 macro_rules! type_tuple_impl {
    16 macro_rules! type_tuple_impl {
    17     ($($n: literal: $t: ident),+) => {
    17     ($($n: literal: $t: ident),+) => {
    18         impl<$($t: 'static),+> TypeTuple for ($(&$t),+,) {
    18         impl<$($t: 'static),+> TypeTuple for ($(&$t),+,) {
   164             block_index,
   164             block_index,
   165         }
   165         }
   166     }
   166     }
   167 }
   167 }
   168 
   168 
       
   169 #[derive(Copy, Clone, Eq, PartialEq, Debug)]
       
   170 struct BlockMask {
       
   171     type_mask: u64,
       
   172     tag_mask: u64,
       
   173 }
       
   174 
       
   175 impl BlockMask {
       
   176     #[inline]
       
   177     fn new(type_mask: u64, tag_mask: u64) -> Self {
       
   178         Self {
       
   179             type_mask,
       
   180             tag_mask,
       
   181         }
       
   182     }
       
   183 
       
   184     #[inline]
       
   185     fn with_type(&self, type_bit: u64) -> Self {
       
   186         Self::new(self.type_mask | type_bit, self.tag_mask)
       
   187     }
       
   188 
       
   189     #[inline]
       
   190     fn with_tag(&self, tag_bit: u64) -> Self {
       
   191         Self::new(self.type_mask, self.tag_mask | tag_bit)
       
   192     }
       
   193 }
       
   194 
   169 pub struct GearDataManager {
   195 pub struct GearDataManager {
   170     types: Vec<TypeId>,
   196     types: Vec<TypeId>,
       
   197     tags: Vec<TypeId>,
   171     blocks: Vec<DataBlock>,
   198     blocks: Vec<DataBlock>,
   172     block_masks: Vec<u64>,
   199     block_masks: Vec<BlockMask>,
   173     element_sizes: Box<[u16; 64]>,
   200     element_sizes: Box<[u16; 64]>,
   174     lookup: Box<[LookupEntry]>,
   201     lookup: Box<[LookupEntry]>,
   175 }
   202 }
   176 
   203 
   177 impl GearDataManager {
   204 impl GearDataManager {
   178     pub fn new() -> Self {
   205     pub fn new() -> Self {
   179         Self {
   206         Self {
   180             types: vec![],
   207             types: Vec::with_capacity(64),
       
   208             tags: Vec::with_capacity(64),
   181             blocks: vec![],
   209             blocks: vec![],
   182             block_masks: vec![],
   210             block_masks: vec![],
   183             element_sizes: Box::new([0; 64]),
   211             element_sizes: Box::new([0; 64]),
   184             lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(),
   212             lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(),
   185         }
   213         }
   189     fn get_type_index<T: 'static>(&self) -> Option<usize> {
   217     fn get_type_index<T: 'static>(&self) -> Option<usize> {
   190         let type_id = TypeId::of::<T>();
   218         let type_id = TypeId::of::<T>();
   191         self.types.iter().position(|id| *id == type_id)
   219         self.types.iter().position(|id| *id == type_id)
   192     }
   220     }
   193 
   221 
       
   222     #[inline]
       
   223     fn get_tag_index<T: 'static>(&self) -> Option<usize> {
       
   224         let type_id = TypeId::of::<T>();
       
   225         self.tags.iter().position(|id| *id == type_id)
       
   226     }
       
   227 
   194     fn move_between_blocks(&mut self, src_block_index: u16, src_index: u16, dest_block_index: u16) {
   228     fn move_between_blocks(&mut self, src_block_index: u16, src_index: u16, dest_block_index: u16) {
   195         debug_assert!(src_block_index != dest_block_index);
   229         debug_assert!(src_block_index != dest_block_index);
   196         let src_mask = self.block_masks[src_block_index as usize];
   230         let src_mask = self.block_masks[src_block_index as usize];
   197         let dest_mask = self.block_masks[dest_block_index as usize];
   231         let dest_mask = self.block_masks[dest_block_index as usize];
   198         debug_assert!(src_mask & dest_mask == src_mask);
   232         debug_assert!(src_mask.type_mask & dest_mask.type_mask == src_mask.type_mask);
   199 
   233 
   200         let src_block = &self.blocks[src_block_index as usize];
   234         let src_block = &self.blocks[src_block_index as usize];
   201         let dest_block = &self.blocks[dest_block_index as usize];
   235         let dest_block = &self.blocks[dest_block_index as usize];
   202         debug_assert!(src_index < src_block.elements_count);
   236         debug_assert!(src_index < src_block.elements_count);
   203         debug_assert!(!dest_block.is_full());
   237         debug_assert!(!dest_block.is_full());
   204 
   238 
   205         let dest_index = dest_block.elements_count;
   239         let dest_index = dest_block.elements_count;
   206         for i in 0..self.types.len() {
   240         for i in 0..self.types.len() {
   207             if src_mask & (1 << i as u64) != 0 {
   241             if src_mask.type_mask & (1 << i as u64) != 0 {
   208                 let size = self.element_sizes[i];
   242                 let size = self.element_sizes[i];
   209                 let src_ptr = src_block.component_blocks[i].unwrap().as_ptr();
   243                 let src_ptr = src_block.component_blocks[i].unwrap().as_ptr();
   210                 let dest_ptr = dest_block.component_blocks[i].unwrap().as_ptr();
   244                 let dest_ptr = dest_block.component_blocks[i].unwrap().as_ptr();
   211                 unsafe {
   245                 unsafe {
   212                     copy_nonoverlapping(
   246                     copy_nonoverlapping(
   246         self.lookup[gear_id.get() as usize - 1] = LookupEntry::new(dest_block_index, dest_index);
   280         self.lookup[gear_id.get() as usize - 1] = LookupEntry::new(dest_block_index, dest_index);
   247         dest_block.elements_count += 1;
   281         dest_block.elements_count += 1;
   248     }
   282     }
   249 
   283 
   250     fn add_to_block<T: Clone>(&mut self, gear_id: GearId, block_index: u16, value: &T) {
   284     fn add_to_block<T: Clone>(&mut self, gear_id: GearId, block_index: u16, value: &T) {
   251         debug_assert!(self.block_masks[block_index as usize].count_ones() == 1);
   285         debug_assert!(
       
   286             self.block_masks[block_index as usize]
       
   287                 .type_mask
       
   288                 .count_ones()
       
   289                 == 1
       
   290         );
   252 
   291 
   253         let block = &mut self.blocks[block_index as usize];
   292         let block = &mut self.blocks[block_index as usize];
   254         debug_assert!(block.elements_count < block.max_elements);
   293         debug_assert!(block.elements_count < block.max_elements);
   255 
   294 
   256         unsafe {
   295         unsafe {
   297         }
   336         }
   298         block.elements_count -= 1;
   337         block.elements_count -= 1;
   299     }
   338     }
   300 
   339 
   301     #[inline]
   340     #[inline]
   302     fn ensure_block(&mut self, mask: u64) -> u16 {
   341     fn ensure_block(&mut self, mask: BlockMask) -> u16 {
   303         if let Some(index) = self
   342         if let Some(index) = self
   304             .block_masks
   343             .block_masks
   305             .iter()
   344             .iter()
   306             .enumerate()
   345             .enumerate()
   307             .position(|(i, m)| *m == mask && !self.blocks[i].is_full())
   346             .position(|(i, m)| *m == mask && !self.blocks[i].is_full())
   308         {
   347         {
   309             index as u16
   348             index as u16
   310         } else {
   349         } else {
   311             self.blocks.push(DataBlock::new(
   350             self.blocks.push(DataBlock::new(
   312                 mask,
   351                 mask.type_mask,
   313                 &self.element_sizes[0..self.types.len()],
   352                 &self.element_sizes[0..self.types.len()],
   314             ));
   353             ));
   315             self.block_masks.push(mask);
   354             self.block_masks.push(mask);
   316             (self.blocks.len() - 1) as u16
   355             (self.blocks.len() - 1) as u16
   317         }
   356         }
   322             let type_bit = 1 << type_index as u64;
   361             let type_bit = 1 << type_index as u64;
   323             let entry = self.lookup[gear_id.get() as usize - 1];
   362             let entry = self.lookup[gear_id.get() as usize - 1];
   324 
   363 
   325             if let Some(index) = entry.index {
   364             if let Some(index) = entry.index {
   326                 let mask = self.block_masks[entry.block_index as usize];
   365                 let mask = self.block_masks[entry.block_index as usize];
   327                 let new_mask = mask | type_bit;
   366                 let new_mask = mask.with_type(type_bit);
   328 
   367 
   329                 if new_mask != mask {
   368                 if new_mask != mask {
   330                     let dest_block_index = self.ensure_block(new_mask);
   369                     let dest_block_index = self.ensure_block(new_mask);
   331                     self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index);
   370                     self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index);
   332                 }
   371                 }
   333             } else {
   372             } else {
   334                 let dest_block_index = self.ensure_block(type_bit);
   373                 let dest_block_index = self.ensure_block(BlockMask::new(type_bit, 0));
   335                 self.add_to_block(gear_id, dest_block_index, value);
   374                 self.add_to_block(gear_id, dest_block_index, value);
   336             }
   375             }
   337         } else {
   376         } else {
   338             panic!("Unregistered type")
   377             panic!("Unregistered type")
       
   378         }
       
   379     }
       
   380 
       
   381     pub fn add_tag<T: 'static>(&mut self, gear_id: GearId) {
       
   382         if let Some(tag_index) = self.get_tag_index::<T>() {
       
   383             let tag_bit = 1 << tag_index as u64;
       
   384             let entry = self.lookup[gear_id.get() as usize - 1];
       
   385 
       
   386             if let Some(index) = entry.index {
       
   387                 let mask = self.block_masks[entry.block_index as usize];
       
   388                 let new_mask = mask.with_tag(tag_bit);
       
   389 
       
   390                 if new_mask != mask {
       
   391                     let dest_block_index = self.ensure_block(new_mask);
       
   392                     self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index);
       
   393                 }
       
   394             } else {
       
   395                 panic!("Cannot tag a gear with no data")
       
   396             }
       
   397         } else {
       
   398             panic!("Unregistered tag")
   339         }
   399         }
   340     }
   400     }
   341 
   401 
   342     pub fn remove<T: 'static>(&mut self, gear_id: GearId) {
   402     pub fn remove<T: 'static>(&mut self, gear_id: GearId) {
   343         if let Some(type_index) = self.get_type_index::<T>() {
   403         if let Some(type_index) = self.get_type_index::<T>() {
   344             let entry = self.lookup[gear_id.get() as usize - 1];
   404             let entry = self.lookup[gear_id.get() as usize - 1];
   345             if let Some(index) = entry.index {
   405             if let Some(index) = entry.index {
   346                 let dest_mask =
   406                 let mut dest_mask = self.block_masks[entry.block_index as usize];
   347                     self.block_masks[entry.block_index as usize] & !(1 << type_index as u64);
   407                 dest_mask.type_mask &= !(1 << type_index as u64);
   348 
   408 
   349                 if dest_mask == 0 {
   409                 if dest_mask.type_mask == 0 {
   350                     self.remove_all(gear_id)
   410                     self.remove_from_block(entry.block_index, index.get() - 1);
   351                 } else {
   411                 } else {
   352                     let dest_block_index = self.ensure_block(dest_mask);
   412                     let dest_block_index = self.ensure_block(dest_mask);
   353                     self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index);
   413                     self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index);
   354                 }
   414                 }
   355             }
   415             }
   365         }
   425         }
   366     }
   426     }
   367 
   427 
   368     pub fn register<T: 'static>(&mut self) {
   428     pub fn register<T: 'static>(&mut self) {
   369         debug_assert!(!std::mem::needs_drop::<T>());
   429         debug_assert!(!std::mem::needs_drop::<T>());
   370         debug_assert!(self.types.len() <= 64);
       
   371         debug_assert!(size_of::<T>() <= u16::max_value() as usize);
   430         debug_assert!(size_of::<T>() <= u16::max_value() as usize);
   372 
   431 
   373         let id = TypeId::of::<T>();
   432         let id = TypeId::of::<T>();
   374         if !self.types.contains(&id) {
   433         if size_of::<T>() == 0 {
   375             self.element_sizes[self.types.len()] = size_of::<T>() as u16;
   434             if !self.tags.contains(&id) {
   376             self.types.push(id);
   435                 debug_assert!(self.tags.len() <= 64);
   377         }
   436                 self.tags.push(id)
   378     }
   437             }
   379 
   438         } else {
       
   439             if !self.types.contains(&id) {
       
   440                 debug_assert!(self.types.len() <= 64);
       
   441                 self.element_sizes[self.types.len()] = size_of::<T>() as u16;
       
   442                 self.types.push(id);
       
   443             }
       
   444         }
       
   445     }
       
   446 
       
   447     #[inline]
   380     pub fn iter<T: TypeTuple + 'static, F: FnMut(T)>(&mut self, mut f: F) {
   448     pub fn iter<T: TypeTuple + 'static, F: FnMut(T)>(&mut self, mut f: F) {
   381         self.iter_id(|_, x| f(x));
   449         self.iter_id(|_, x| f(x));
   382     }
   450     }
   383 
   451 
   384     pub fn iter_id<T: TypeTuple + 'static, F: FnMut(GearId, T)>(&mut self, mut f: F) {
   452     pub fn iter_id<T: TypeTuple + 'static, F: FnMut(GearId, T)>(&mut self, mut f: F) {
   399             }
   467             }
   400         }
   468         }
   401         let mut slices = vec![null_mut(); arg_types.len() + 1];
   469         let mut slices = vec![null_mut(); arg_types.len() + 1];
   402 
   470 
   403         for (block_index, mask) in self.block_masks.iter().enumerate() {
   471         for (block_index, mask) in self.block_masks.iter().enumerate() {
   404             if mask & selector == selector {
   472             if mask.type_mask & selector == selector {
   405                 let block = &mut self.blocks[block_index];
   473                 let block = &mut self.blocks[block_index];
   406                 slices[0] = block.data.as_mut_ptr();
   474                 slices[0] = block.data.as_mut_ptr();
   407 
   475 
   408                 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() {
   476                 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() {
   409                     slices[arg_index as usize + 1] = block.component_blocks[type_index as usize]
   477                     slices[arg_index as usize + 1] = block.component_blocks[type_index as usize]