rust/hwphysics/src/data.rs
changeset 15426 a027e60d7820
parent 15395 a87b5e16b863
child 15829 d5e6c8c92d87
equal deleted inserted replaced
15425:a6699f4a3d16 15426:a027e60d7820
     1 use super::common::GearId;
     1 use super::common::GearId;
     2 use std::{
     2 use std::{
     3     any::TypeId,
     3     any::TypeId,
     4     fmt::{Debug, Error, Formatter},
     4     fmt::{Debug, Error, Formatter},
     5     marker::PhantomData,
     5     marker::PhantomData,
     6     mem::{size_of, MaybeUninit},
     6     mem::{align_of, size_of, MaybeUninit},
     7     num::NonZeroU16,
     7     num::NonZeroU16,
     8     ptr::{copy_nonoverlapping, null_mut, NonNull},
     8     ptr::{copy_nonoverlapping, null_mut, NonNull},
     9     slice,
     9     slice,
    10 };
    10 };
    11 
    11 
   115         write!(f, "}}\n")
   115         write!(f, "}}\n")
   116     }
   116     }
   117 }
   117 }
   118 
   118 
   119 impl DataBlock {
   119 impl DataBlock {
   120     fn new(mask: u64, element_sizes: &[u16]) -> Self {
   120     fn new(mask: u64, element_sizes: &[u16], element_alignments: &[u8]) -> Self {
       
   121         let total_padding: usize = element_alignments.iter().map(|x| *x as usize).sum();
   121         let total_size: u16 = element_sizes
   122         let total_size: u16 = element_sizes
   122             .iter()
   123             .iter()
   123             .enumerate()
   124             .enumerate()
   124             .filter(|(i, _)| mask & (1 << *i as u64) != 0)
   125             .filter(|(i, _)| mask & (1 << *i as u64) != 0)
   125             .map(|(_, size)| *size)
   126             .map(|(_, size)| *size)
   126             .sum();
   127             .sum();
   127         let max_elements = (BLOCK_SIZE / (total_size as usize + size_of::<GearId>())) as u16;
   128         let max_elements =
   128 
   129             ((BLOCK_SIZE - total_padding) / (total_size as usize + size_of::<GearId>())) as u16;
       
   130 
       
   131         //ensure the block memory is aligned to GearId
       
   132         let tmp_data: Box<[GearId; BLOCK_SIZE / size_of::<GearId>()]> =
       
   133             Box::new(unsafe { MaybeUninit::uninit().assume_init() });
   129         let mut data: Box<[u8; BLOCK_SIZE]> =
   134         let mut data: Box<[u8; BLOCK_SIZE]> =
   130             Box::new(unsafe { MaybeUninit::uninit().assume_init() });
   135             unsafe { Box::from_raw(Box::into_raw(tmp_data) as *mut [u8; BLOCK_SIZE]) };
       
   136 
   131         let mut blocks = [None; 64];
   137         let mut blocks = [None; 64];
   132         let mut offset = size_of::<GearId>() * max_elements as usize;
   138         let mut address = unsafe {
       
   139             data.as_mut_ptr()
       
   140                 .add(size_of::<GearId>() * max_elements as usize)
       
   141         };
   133 
   142 
   134         for i in 0..element_sizes.len() {
   143         for i in 0..element_sizes.len() {
   135             if mask & (1 << i as u64) != 0 {
   144             if mask & (1 << i as u64) != 0 {
   136                 blocks[i] = Some(NonNull::new(data[offset..].as_mut_ptr()).unwrap());
   145                 unsafe {
   137                 offset += element_sizes[i] as usize * max_elements as usize;
   146                     address = address.add(address.align_offset(element_alignments[i] as usize));
   138             }
   147                     blocks[i] = Some(NonNull::new_unchecked(address));
   139         }
   148                     address = address.add(element_sizes[i] as usize * max_elements as usize)
       
   149                 };
       
   150             }
       
   151         }
       
   152 
   140         Self {
   153         Self {
   141             elements_count: 0,
   154             elements_count: 0,
   142             max_elements,
   155             max_elements,
   143             data,
   156             data,
   144             component_blocks: blocks,
   157             component_blocks: blocks,
   214     types: Vec<TypeId>,
   227     types: Vec<TypeId>,
   215     tags: Vec<TypeId>,
   228     tags: Vec<TypeId>,
   216     blocks: Vec<DataBlock>,
   229     blocks: Vec<DataBlock>,
   217     block_masks: Vec<BlockMask>,
   230     block_masks: Vec<BlockMask>,
   218     element_sizes: Box<[u16; 64]>,
   231     element_sizes: Box<[u16; 64]>,
       
   232     element_alignments: Box<[u8; 64]>,
   219     lookup: Box<[LookupEntry]>,
   233     lookup: Box<[LookupEntry]>,
   220 }
   234 }
   221 
   235 
   222 impl GearDataManager {
   236 impl GearDataManager {
   223     pub fn new() -> Self {
   237     pub fn new() -> Self {
   225             types: Vec::with_capacity(64),
   239             types: Vec::with_capacity(64),
   226             tags: Vec::with_capacity(64),
   240             tags: Vec::with_capacity(64),
   227             blocks: vec![],
   241             blocks: vec![],
   228             block_masks: vec![],
   242             block_masks: vec![],
   229             element_sizes: Box::new([0; 64]),
   243             element_sizes: Box::new([0; 64]),
       
   244             element_alignments: Box::new([0; 64]),
   230             lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(),
   245             lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(),
   231         }
   246         }
   232     }
   247     }
   233 
   248 
   234     #[inline]
   249     #[inline]
   386             index as u16
   401             index as u16
   387         } else {
   402         } else {
   388             self.blocks.push(DataBlock::new(
   403             self.blocks.push(DataBlock::new(
   389                 mask.type_mask,
   404                 mask.type_mask,
   390                 &self.element_sizes[0..self.types.len()],
   405                 &self.element_sizes[0..self.types.len()],
       
   406                 &self.element_alignments[0..self.types.len()],
   391             ));
   407             ));
   392             self.block_masks.push(mask);
   408             self.block_masks.push(mask);
   393             (self.blocks.len() - 1) as u16
   409             (self.blocks.len() - 1) as u16
   394         }
   410         }
   395     }
   411     }
   480             }
   496             }
   481         } else {
   497         } else {
   482             if !self.types.contains(&id) {
   498             if !self.types.contains(&id) {
   483                 debug_assert!(self.types.len() <= 64);
   499                 debug_assert!(self.types.len() <= 64);
   484                 self.element_sizes[self.types.len()] = size_of::<T>() as u16;
   500                 self.element_sizes[self.types.len()] = size_of::<T>() as u16;
       
   501                 self.element_alignments[self.types.len()] = align_of::<T>() as u8;
   485                 self.types.push(id);
   502                 self.types.push(id);
   486             }
   503             }
   487         }
   504         }
   488     }
   505     }
   489 
   506