rust/hwphysics/src/data.rs
changeset 15392 b387a51705ac
parent 15387 90a79670de52
child 15393 0ef770a40e75
equal deleted inserted replaced
15391:7a3d70c364fd 15392:b387a51705ac
     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     mem::{size_of, MaybeUninit},
     6     mem::{size_of, MaybeUninit},
     6     num::NonZeroU16,
     7     num::NonZeroU16,
     7     ptr::{copy_nonoverlapping, null_mut, NonNull},
     8     ptr::{copy_nonoverlapping, null_mut, NonNull},
     8     slice,
     9     slice,
     9 };
    10 };
    10 
    11 
    11 pub trait TypeTuple: Sized {
    12 pub trait TypeTuple: Sized {
    12     fn get_types(types: &mut Vec<TypeId>);
    13     fn get_types(types: &mut Vec<TypeId>);
       
    14 }
       
    15 
       
    16 impl TypeTuple for () {
       
    17     fn get_types(types: &mut Vec<TypeId>) {}
       
    18 }
       
    19 
       
    20 impl<T: 'static> TypeTuple for &T {
       
    21     fn get_types(types: &mut Vec<TypeId>) {
       
    22         types.push(TypeId::of::<T>());
       
    23     }
       
    24 }
       
    25 
       
    26 pub trait TypeIter: TypeTuple {
    13     unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, f: F);
    27     unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, f: F);
    14 }
    28 }
    15 
    29 
    16 macro_rules! type_tuple_impl {
    30 macro_rules! type_tuple_impl {
    17     ($($n: literal: $t: ident),+) => {
    31     ($($n: literal: $t: ident),+) => {
    18         impl<$($t: 'static),+> TypeTuple for ($(&$t),+,) {
    32         impl<$($t: 'static),+> TypeTuple for ($(&$t),+,) {
    19             fn get_types(types: &mut Vec<TypeId>) {
    33             fn get_types(types: &mut Vec<TypeId>) {
    20                 $(types.push(TypeId::of::<$t>()));+
    34                 $(types.push(TypeId::of::<$t>()));+
    21             }
    35             }
    22 
    36         }
       
    37 
       
    38         impl<$($t: 'static),+> TypeIter for ($(&$t),+,) {
    23             unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: F) {
    39             unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: F) {
    24                 for i in 0..count {
    40                 for i in 0..count {
    25                     f(*(*slices.get_unchecked(0) as *const GearId).add(i),
    41                     f(*(*slices.get_unchecked(0) as *const GearId).add(i),
    26                       ($(&*(*slices.get_unchecked($n + 1) as *mut $t).add(i)),+,));
    42                       ($(&*(*slices.get_unchecked($n + 1) as *mut $t).add(i)),+,));
    27                 }
    43                 }
    30 
    46 
    31         impl<$($t: 'static),+> TypeTuple for ($(&mut $t),+,) {
    47         impl<$($t: 'static),+> TypeTuple for ($(&mut $t),+,) {
    32             fn get_types(types: &mut Vec<TypeId>) {
    48             fn get_types(types: &mut Vec<TypeId>) {
    33                 $(types.push(TypeId::of::<$t>()));+
    49                 $(types.push(TypeId::of::<$t>()));+
    34             }
    50             }
    35 
    51         }
       
    52 
       
    53         impl<$($t: 'static),+> TypeIter for ($(&mut $t),+,) {
    36             unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: F) {
    54             unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: F) {
    37                 for i in 0..count {
    55                 for i in 0..count {
    38                     f(*(*slices.get_unchecked(0) as *const GearId).add(i),
    56                     f(*(*slices.get_unchecked(0) as *const GearId).add(i),
    39                       ($(&mut *(*slices.get_unchecked($n + 1) as *mut $t).add(i)),+,));
    57                       ($(&mut *(*slices.get_unchecked($n + 1) as *mut $t).add(i)),+,));
    40                 }
    58                 }
   442                 self.types.push(id);
   460                 self.types.push(id);
   443             }
   461             }
   444         }
   462         }
   445     }
   463     }
   446 
   464 
   447     #[inline]
   465     fn run_impl<T: TypeIter + 'static, F: FnMut(GearId, T)>(
   448     pub fn iter<T: TypeTuple + 'static, F: FnMut(T)>(&mut self, mut f: F) {
   466         &mut self,
   449         self.iter_id(|_, x| f(x));
   467         type_selector: u64,
   450     }
   468         included_tags: u64,
   451 
   469         type_indices: &[i8],
   452     pub fn iter_id<T: TypeTuple + 'static, F: FnMut(GearId, T)>(&mut self, mut f: F) {
   470         mut f: F,
       
   471     ) {
       
   472         let mut slices = vec![null_mut(); type_indices.len() + 1];
       
   473 
       
   474         for (block_index, mask) in self.block_masks.iter().enumerate() {
       
   475             if mask.type_mask & type_selector == type_selector
       
   476                 && mask.tag_mask & included_tags == included_tags
       
   477             {
       
   478                 let block = &mut self.blocks[block_index];
       
   479                 slices[0] = block.data.as_mut_ptr();
       
   480 
       
   481                 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() {
       
   482                     slices[arg_index as usize + 1] = block.component_blocks[type_index as usize]
       
   483                         .unwrap()
       
   484                         .as_ptr()
       
   485                 }
       
   486 
       
   487                 unsafe {
       
   488                     T::iter(&slices[..], block.elements_count as usize, |id, x| f(id, x));
       
   489                 }
       
   490             }
       
   491         }
       
   492     }
       
   493 
       
   494     pub fn iter<T: TypeIter + 'static>(&mut self) -> DataIterator<T> {
   453         let mut arg_types = Vec::with_capacity(64);
   495         let mut arg_types = Vec::with_capacity(64);
   454         T::get_types(&mut arg_types);
   496         T::get_types(&mut arg_types);
   455 
       
   456         let mut type_indices = vec![-1i8; arg_types.len()];
   497         let mut type_indices = vec![-1i8; arg_types.len()];
   457         let mut selector = 0u64;
   498         let mut selector = 0u64;
   458 
   499 
   459         for (arg_index, type_id) in arg_types.iter().enumerate() {
   500         for (arg_index, type_id) in arg_types.iter().enumerate() {
   460             match self.types.iter().position(|t| t == type_id) {
   501             match self.types.iter().position(|t| t == type_id) {
   464                     selector |= 1 << i as u64;
   505                     selector |= 1 << i as u64;
   465                 }
   506                 }
   466                 None => panic!("Unregistered type"),
   507                 None => panic!("Unregistered type"),
   467             }
   508             }
   468         }
   509         }
   469         let mut slices = vec![null_mut(); arg_types.len() + 1];
   510         DataIterator::new(self, selector, type_indices)
   470 
   511     }
   471         for (block_index, mask) in self.block_masks.iter().enumerate() {
   512 }
   472             if mask.type_mask & selector == selector {
   513 
   473                 let block = &mut self.blocks[block_index];
   514 pub struct DataIterator<'a, T> {
   474                 slices[0] = block.data.as_mut_ptr();
   515     data: &'a mut GearDataManager,
   475 
   516     types: u64,
   476                 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() {
   517     type_indices: Vec<i8>,
   477                     slices[arg_index as usize + 1] = block.component_blocks[type_index as usize]
   518     tags: u64,
   478                         .unwrap()
   519     phantom_types: PhantomData<T>,
   479                         .as_ptr()
   520 }
   480                 }
   521 
   481 
   522 impl<'a, T: TypeIter + 'static> DataIterator<'a, T> {
   482                 unsafe {
   523     fn new(
   483                     T::iter(&slices[..], block.elements_count as usize, |id, x| f(id, x));
   524         data: &'a mut GearDataManager,
   484                 }
   525         types: u64,
   485             }
   526         type_indices: Vec<i8>,
   486         }
   527     ) -> DataIterator<'a, T> {
       
   528         Self {
       
   529             data,
       
   530             types,
       
   531             type_indices,
       
   532             tags: 0,
       
   533             phantom_types: PhantomData,
       
   534         }
       
   535     }
       
   536 
       
   537     pub fn with_tags<U: TypeTuple + 'static>(self) -> Self {
       
   538         let mut tag_types = Vec::with_capacity(64);
       
   539         U::get_types(&mut tag_types);
       
   540         let mut tags = 0;
       
   541 
       
   542         for (i, tag) in self.data.tags.iter().enumerate() {
       
   543             if tag_types.contains(tag) {
       
   544                 tags |= 1 << i as u64;
       
   545             }
       
   546         }
       
   547         Self { tags, ..self }
       
   548     }
       
   549 
       
   550     #[inline]
       
   551     pub fn run<F: FnMut(T)>(&mut self, mut f: F) {
       
   552         self.run_id(|_, x| f(x))
       
   553     }
       
   554 
       
   555     #[inline]
       
   556     pub fn run_id<F: FnMut(GearId, T)>(&mut self, f: F) {
       
   557         self.data
       
   558             .run_impl(self.types, self.tags, &self.type_indices, f);
   487     }
   559     }
   488 }
   560 }
   489 
   561 
   490 #[cfg(test)]
   562 #[cfg(test)]
   491 mod test {
   563 mod test {
   495     struct Datum {
   567     struct Datum {
   496         value: u32,
   568         value: u32,
   497     }
   569     }
   498 
   570 
   499     #[derive(Clone)]
   571     #[derive(Clone)]
   500     struct Tag {
   572     struct Tag;
   501         nothing: u8,
       
   502     }
       
   503 
   573 
   504     #[test]
   574     #[test]
   505     fn single_component_iteration() {
   575     fn single_component_iteration() {
   506         let mut manager = GearDataManager::new();
   576         let mut manager = GearDataManager::new();
   507         manager.register::<Datum>();
   577         manager.register::<Datum>();
   508         for i in 1..=5 {
   578         for i in 1..=5 {
   509             manager.add(GearId::new(i as u16).unwrap(), &Datum { value: i });
   579             manager.add(GearId::new(i as u16).unwrap(), &Datum { value: i });
   510         }
   580         }
   511 
   581 
   512         let mut sum = 0;
   582         let mut sum = 0;
   513         manager.iter(|(d,): (&Datum,)| sum += d.value);
   583         manager.iter().run(|(d,): (&Datum,)| sum += d.value);
   514         assert_eq!(sum, 15);
   584         assert_eq!(sum, 15);
   515 
   585 
   516         manager.iter(|(d,): (&mut Datum,)| d.value += 1);
   586         manager.iter().run(|(d,): (&mut Datum,)| d.value += 1);
   517         manager.iter(|(d,): (&Datum,)| sum += d.value);
   587         manager.iter().run(|(d,): (&Datum,)| sum += d.value);
   518         assert_eq!(sum, 35);
   588         assert_eq!(sum, 35);
   519     }
   589     }
   520 
   590 
   521     #[test]
   591     #[test]
   522     fn multiple_component_iteration() {
   592     fn tagged_component_iteration() {
   523         let mut manager = GearDataManager::new();
   593         let mut manager = GearDataManager::new();
   524         manager.register::<Datum>();
   594         manager.register::<Datum>();
   525         manager.register::<Tag>();
   595         manager.register::<Tag>();
   526         for i in 1..=10 {
   596         for i in 1..=10 {
   527             let gear_id = GearId::new(i as u16).unwrap();
   597             let gear_id = GearId::new(i as u16).unwrap();
   529         }
   599         }
   530 
   600 
   531         for i in 1..=10 {
   601         for i in 1..=10 {
   532             let gear_id = GearId::new(i as u16).unwrap();
   602             let gear_id = GearId::new(i as u16).unwrap();
   533             if i & 1 == 0 {
   603             if i & 1 == 0 {
   534                 manager.add(GearId::new(i as u16).unwrap(), &Tag { nothing: 0 });
   604                 manager.add_tag::<Tag>(gear_id);
   535             }
   605             }
   536         }
   606         }
   537 
   607 
   538         let mut sum = 0;
   608         let mut sum = 0;
   539         manager.iter(|(d,): (&Datum,)| sum += d.value);
   609         manager.iter().run(|(d,): (&Datum,)| sum += d.value);
   540         assert_eq!(sum, 55);
   610         assert_eq!(sum, 55);
   541 
   611 
   542         let mut tag_sum1 = 0;
   612         let mut tag_sum = 0;
   543         let mut tag_sum2 = 0;
   613         manager
   544         manager.iter(|(d, _): (&Datum, &Tag)| tag_sum1 += d.value);
   614             .iter()
   545         manager.iter(|(_, d): (&Tag, &Datum)| tag_sum2 += d.value);
   615             .with_tags::<&Tag>()
   546         assert_eq!(tag_sum1, 30);
   616             .run(|(d,): (&Datum,)| tag_sum += d.value);
   547         assert_eq!(tag_sum2, tag_sum1);
   617         assert_eq!(tag_sum, 30);
   548     }
   618     }
   549 }
   619 }