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 } |