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 |
|
12 const MAX_TYPES: usize = 8; |
|
13 |
12 pub trait TypeTuple: Sized { |
14 pub trait TypeTuple: Sized { |
13 fn get_types(types: &mut Vec<TypeId>); |
15 fn get_types(_types: &mut [TypeId; MAX_TYPES]) -> usize; |
14 } |
16 } |
15 |
17 |
16 impl TypeTuple for () { |
18 impl TypeTuple for () { |
17 fn get_types(_types: &mut Vec<TypeId>) {} |
19 fn get_types(_types: &mut [TypeId; MAX_TYPES]) -> usize { |
|
20 0 |
|
21 } |
18 } |
22 } |
19 |
23 |
20 impl<T: 'static> TypeTuple for &T { |
24 impl<T: 'static> TypeTuple for &T { |
21 fn get_types(types: &mut Vec<TypeId>) { |
25 fn get_types(types: &mut [TypeId; MAX_TYPES]) -> usize { |
22 types.push(TypeId::of::<T>()); |
26 if MAX_TYPES > 0 { |
|
27 unsafe { |
|
28 *types.get_unchecked_mut(0) = TypeId::of::<T>(); |
|
29 } |
|
30 1 |
|
31 } else { |
|
32 0 |
|
33 } |
23 } |
34 } |
24 } |
35 } |
25 |
36 |
26 pub trait TypeIter: TypeTuple { |
37 pub trait TypeIter: TypeTuple { |
27 unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, f: F); |
38 unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, f: F); |
28 } |
39 } |
29 |
40 |
30 macro_rules! type_tuple_impl { |
41 macro_rules! type_tuple_impl { |
31 ($($n: literal: $t: ident),+) => { |
42 ($($n: literal: $t: ident),+) => { |
32 impl<$($t: 'static),+> TypeTuple for ($(&$t),+,) { |
43 impl<$($t: 'static),+> TypeTuple for ($(&$t),+,) { |
33 fn get_types(types: &mut Vec<TypeId>) { |
44 fn get_types(types: &mut [TypeId; MAX_TYPES]) -> usize { |
34 $(types.push(TypeId::of::<$t>()));+ |
45 let mut count = 0; |
|
46 $({ |
|
47 if MAX_TYPES > $n { |
|
48 unsafe { |
|
49 *types.get_unchecked_mut($n) = TypeId::of::<$t>(); |
|
50 } |
|
51 count = $n + 1; |
|
52 } |
|
53 });+ |
|
54 count |
35 } |
55 } |
36 } |
56 } |
37 |
57 |
38 impl<$($t: 'static),+> TypeIter for ($(&$t),+,) { |
58 impl<$($t: 'static),+> TypeIter for ($(&$t),+,) { |
39 unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: F) { |
59 unsafe fn iter<FI: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: FI) { |
40 for i in 0..count { |
60 for i in 0..count { |
41 f(*(*slices.get_unchecked(0) as *const GearId).add(i), |
61 f(*(*slices.get_unchecked(0) as *const GearId).add(i), |
42 ($(&*(*slices.get_unchecked($n + 1) as *mut $t).add(i)),+,)); |
62 ($(&*(*slices.get_unchecked($n + 1) as *mut $t).add(i)),+,)); |
43 } |
63 } |
44 } |
64 } |
45 } |
65 } |
46 |
66 |
47 impl<$($t: 'static),+> TypeTuple for ($(&mut $t),+,) { |
67 impl<$($t: 'static),+> TypeTuple for ($(&mut $t),+,) { |
48 fn get_types(types: &mut Vec<TypeId>) { |
68 fn get_types(types: &mut [TypeId; MAX_TYPES]) -> usize { |
49 $(types.push(TypeId::of::<$t>()));+ |
69 let mut count = 0; |
|
70 $({ |
|
71 if MAX_TYPES > $n { |
|
72 unsafe { |
|
73 *types.get_unchecked_mut($n) = TypeId::of::<$t>(); |
|
74 } |
|
75 count = $n + 1; |
|
76 } |
|
77 });+ |
|
78 count |
50 } |
79 } |
51 } |
80 } |
52 |
81 |
53 impl<$($t: 'static),+> TypeIter for ($(&mut $t),+,) { |
82 impl<$($t: 'static),+> TypeIter for ($(&mut $t),+,) { |
54 unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: F) { |
83 unsafe fn iter<FI: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: FI) { |
55 for i in 0..count { |
84 for i in 0..count { |
56 f(*(*slices.get_unchecked(0) as *const GearId).add(i), |
85 f(*(*slices.get_unchecked(0) as *const GearId).add(i), |
57 ($(&mut *(*slices.get_unchecked($n + 1) as *mut $t).add(i)),+,)); |
86 ($(&mut *(*slices.get_unchecked($n + 1) as *mut $t).add(i)),+,)); |
58 } |
87 } |
59 } |
88 } |
64 type_tuple_impl!(0: A); |
93 type_tuple_impl!(0: A); |
65 type_tuple_impl!(0: A, 1: B); |
94 type_tuple_impl!(0: A, 1: B); |
66 type_tuple_impl!(0: A, 1: B, 2: C); |
95 type_tuple_impl!(0: A, 1: B, 2: C); |
67 type_tuple_impl!(0: A, 1: B, 2: C, 3: D); |
96 type_tuple_impl!(0: A, 1: B, 2: C, 3: D); |
68 type_tuple_impl!(0: A, 1: B, 2: C, 3: D, 4: E); |
97 type_tuple_impl!(0: A, 1: B, 2: C, 3: D, 4: E); |
|
98 type_tuple_impl!(0: A, 1: B, 2: C, 3: D, 4: E, 5: F); |
|
99 type_tuple_impl!(0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G); |
|
100 type_tuple_impl!(0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H); |
69 |
101 |
70 const BLOCK_SIZE: usize = 32768; |
102 const BLOCK_SIZE: usize = 32768; |
71 |
103 |
72 struct DataBlock { |
104 struct DataBlock { |
73 max_elements: u16, |
105 max_elements: u16, |
572 _ => None, |
608 _ => None, |
573 } |
609 } |
574 } |
610 } |
575 |
611 |
576 pub fn iter<T: TypeIter + 'static>(&mut self) -> DataIterator<T> { |
612 pub fn iter<T: TypeIter + 'static>(&mut self) -> DataIterator<T> { |
577 let mut arg_types = Vec::with_capacity(64); |
613 let mut arg_types: [TypeId; MAX_TYPES] = unsafe { MaybeUninit::uninit().assume_init() }; |
578 T::get_types(&mut arg_types); |
614 let types_count = T::get_types(&mut arg_types); |
579 let mut type_indices = vec![-1i8; arg_types.len()]; |
615 let mut type_indices = [-1; MAX_TYPES]; |
580 let mut selector = 0u64; |
616 let mut selector = 0u64; |
581 |
617 |
582 for (arg_index, type_id) in arg_types.iter().enumerate() { |
618 for (arg_index, type_id) in arg_types[0..types_count].iter().enumerate() { |
583 match self.types.iter().position(|t| t == type_id) { |
619 match self.types.iter().position(|t| t == type_id) { |
584 Some(i) if selector & (1 << i as u64) != 0 => panic!("Duplicate type"), |
620 Some(i) if selector & (1 << i as u64) != 0 => panic!("Duplicate type"), |
585 Some(i) => { |
621 Some(i) => { |
586 type_indices[arg_index] = i as i8; |
622 type_indices[arg_index] = i as i8; |
587 selector |= 1 << i as u64; |
623 selector |= 1 << i as u64; |
594 } |
630 } |
595 |
631 |
596 pub struct DataIterator<'a, T> { |
632 pub struct DataIterator<'a, T> { |
597 data: &'a mut GearDataManager, |
633 data: &'a mut GearDataManager, |
598 types: u64, |
634 types: u64, |
599 type_indices: Vec<i8>, |
635 type_indices: [i8; MAX_TYPES], |
600 tags: u64, |
636 tags: u64, |
601 phantom_types: PhantomData<T>, |
637 phantom_types: PhantomData<T>, |
602 } |
638 } |
603 |
639 |
604 impl<'a, T: TypeIter + 'static> DataIterator<'a, T> { |
640 impl<'a, T: TypeIter + 'static> DataIterator<'a, T> { |
605 fn new( |
641 fn new( |
606 data: &'a mut GearDataManager, |
642 data: &'a mut GearDataManager, |
607 types: u64, |
643 types: u64, |
608 type_indices: Vec<i8>, |
644 type_indices: [i8; MAX_TYPES], |
609 ) -> DataIterator<'a, T> { |
645 ) -> DataIterator<'a, T> { |
610 Self { |
646 Self { |
611 data, |
647 data, |
612 types, |
648 types, |
613 type_indices, |
649 type_indices, |
615 phantom_types: PhantomData, |
651 phantom_types: PhantomData, |
616 } |
652 } |
617 } |
653 } |
618 |
654 |
619 pub fn with_tags<U: TypeTuple + 'static>(self) -> Self { |
655 pub fn with_tags<U: TypeTuple + 'static>(self) -> Self { |
620 let mut tag_types = Vec::with_capacity(64); |
656 let mut tag_types: [TypeId; MAX_TYPES] = unsafe { MaybeUninit::uninit().assume_init() }; |
621 U::get_types(&mut tag_types); |
657 let tags_count = U::get_types(&mut tag_types); |
622 let mut tags = 0; |
658 let mut tags = 0; |
623 |
659 |
624 for (i, tag) in self.data.tags.iter().enumerate() { |
660 for (i, tag) in self.data.tags.iter().enumerate() { |
625 if tag_types.contains(tag) { |
661 if tag_types[0..tags_count].contains(tag) { |
626 tags |= 1 << i as u64; |
662 tags |= 1 << i as u64; |
627 } |
663 } |
628 } |
664 } |
629 Self { tags, ..self } |
665 Self { tags, ..self } |
630 } |
666 } |