1 use super::common::GearId; |
1 use super::common::GearId; |
2 use std::{ |
2 use std::{ |
3 any::TypeId, |
3 any::TypeId, |
4 mem::{size_of, MaybeUninit}, |
4 mem::{size_of, MaybeUninit}, |
5 num::NonZeroU16, |
5 num::NonZeroU16, |
6 ptr::{copy_nonoverlapping, NonNull, null_mut}, |
6 ptr::{copy_nonoverlapping, null_mut, NonNull}, |
7 slice, |
7 slice, |
8 }; |
8 }; |
9 |
9 |
10 pub unsafe trait TypeTuple: Sized { |
10 pub trait TypeTuple: Sized { |
11 fn len() -> usize; |
11 fn len() -> usize; |
12 fn get_types(dest: &mut Vec<TypeId>); |
12 fn get_types(dest: &mut Vec<TypeId>); |
13 unsafe fn iter<F>(slices: &[*mut u8], count: usize, mut f: F) |
13 unsafe fn iter<F: FnMut(Self)>(slices: &[*mut u8], count: usize, mut f: F); |
14 where |
14 } |
15 F: FnMut(Self); |
15 |
16 } |
16 macro_rules! type_typle_impl { |
17 |
17 ($($n: literal: $t: ident),*) => { |
18 unsafe impl<T: 'static> TypeTuple for (&T,) { |
18 impl<$($t: 'static),*> TypeTuple for ($(&$t),*,) { |
19 fn len() -> usize { |
19 fn len() -> usize { |
20 1 |
20 [$({TypeId::of::<$t>(); 1}),*].iter().sum() |
21 } |
21 } |
22 |
22 |
23 fn get_types(dest: &mut Vec<TypeId>) { |
23 fn get_types(types: &mut Vec<TypeId>) { |
24 dest.push(TypeId::of::<T>()); |
24 $(types.push(TypeId::of::<$t>()));* |
25 } |
25 } |
26 |
26 |
27 unsafe fn iter<F>(slices: &[*mut u8], count: usize, mut f: F) |
27 unsafe fn iter<F: FnMut(Self)>(slices: &[*mut u8], count: usize, mut f: F) |
28 where |
28 { |
29 F: FnMut(Self), |
29 for i in 0..count { |
30 { |
30 unsafe { |
31 let slice1 = slice::from_raw_parts(slices[0] as *const T, count); |
31 f(($(&*(*slices.get_unchecked($n) as *mut $t).add(i)),*,)); |
32 for i in 0..count { |
32 } |
33 f((slice1.get_unchecked(i),)); |
33 } |
34 } |
34 } |
35 } |
35 } |
36 } |
36 |
|
37 impl<$($t: 'static),*> TypeTuple for ($(&mut $t),*,) { |
|
38 fn len() -> usize { |
|
39 [$({TypeId::of::<$t>(); 1}),*].iter().sum() |
|
40 } |
|
41 |
|
42 fn get_types(types: &mut Vec<TypeId>) { |
|
43 $(types.push(TypeId::of::<$t>()));* |
|
44 } |
|
45 |
|
46 unsafe fn iter<F: FnMut(Self)>(slices: &[*mut u8], count: usize, mut f: F) |
|
47 { |
|
48 for i in 0..count { |
|
49 unsafe { |
|
50 f(($(&mut *(*slices.get_unchecked($n) as *mut $t).add(i)),*,)); |
|
51 } |
|
52 } |
|
53 } |
|
54 } |
|
55 } |
|
56 } |
|
57 |
|
58 type_typle_impl!(0: A); |
|
59 type_typle_impl!(0: A, 1: B); |
|
60 type_typle_impl!(0: A, 1: B, 2: C); |
|
61 type_typle_impl!(0: A, 1: B, 2: C, 3: D); |
|
62 type_typle_impl!(0: A, 1: B, 2: C, 3: D, 4: E); |
37 |
63 |
38 const BLOCK_SIZE: usize = 32768; |
64 const BLOCK_SIZE: usize = 32768; |
39 |
65 |
40 struct DataBlock { |
66 struct DataBlock { |
41 max_elements: u16, |
67 max_elements: u16, |
265 match self.types.iter().position(|t| t == type_id) { |
291 match self.types.iter().position(|t| t == type_id) { |
266 Some(i) if selector & 1 << i as u64 != 0 => panic!("Duplicate type"), |
292 Some(i) if selector & 1 << i as u64 != 0 => panic!("Duplicate type"), |
267 Some(i) => { |
293 Some(i) => { |
268 type_indices[arg_index] = i as i8; |
294 type_indices[arg_index] = i as i8; |
269 selector &= 1 << i as u64; |
295 selector &= 1 << i as u64; |
270 }, |
296 } |
271 None => panic!("Unregistered type") |
297 None => panic!("Unregistered type"), |
272 } |
298 } |
273 } |
299 } |
274 |
300 |
275 let mut slices = vec![null_mut(); arg_types.len()]; |
301 let mut slices = vec![null_mut(); arg_types.len()]; |
276 |
302 |
277 for (block_index, mask) in self.block_masks.iter().enumerate() { |
303 for (block_index, mask) in self.block_masks.iter().enumerate() { |
278 if mask & selector == selector { |
304 if mask & selector == selector { |
279 let block = &self.blocks[block_index]; |
305 let block = &self.blocks[block_index]; |
280 |
306 |
281 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() { |
307 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() { |
282 slices[arg_index as usize] = |
308 slices[arg_index as usize] = block.component_blocks[type_index as usize] |
283 block.component_blocks[type_index as usize].unwrap().as_ptr() |
309 .unwrap() |
|
310 .as_ptr() |
284 } |
311 } |
285 |
312 |
286 unsafe { |
313 unsafe { |
287 T::iter(&slices[..], block.elements_count as usize, |x| f(x)); |
314 T::iter(&slices[..], block.elements_count as usize, |x| f(x)); |
288 } |
315 } |