9 slice, |
9 slice, |
10 }; |
10 }; |
11 |
11 |
12 pub trait TypeTuple: Sized { |
12 pub trait TypeTuple: Sized { |
13 fn get_types(types: &mut Vec<TypeId>); |
13 fn get_types(types: &mut Vec<TypeId>); |
14 unsafe fn iter<F: FnMut(Self)>(slices: &[*mut u8], count: usize, mut f: F); |
14 unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: F); |
15 } |
15 } |
16 |
16 |
17 macro_rules! type_tuple_impl { |
17 macro_rules! type_tuple_impl { |
18 ($($n: literal: $t: ident),+) => { |
18 ($($n: literal: $t: ident),+) => { |
19 impl<$($t: 'static),+> TypeTuple for ($(&$t),+,) { |
19 impl<$($t: 'static),+> TypeTuple for ($(&$t),+,) { |
20 fn get_types(types: &mut Vec<TypeId>) { |
20 fn get_types(types: &mut Vec<TypeId>) { |
21 $(types.push(TypeId::of::<$t>()));+ |
21 $(types.push(TypeId::of::<$t>()));+ |
22 } |
22 } |
23 |
23 |
24 unsafe fn iter<F: FnMut(Self)>(slices: &[*mut u8], count: usize, mut f: F) { |
24 unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: F) { |
25 for i in 0..count { |
25 for i in 0..count { |
26 unsafe { |
26 unsafe { |
27 f(($(&*(*slices.get_unchecked($n) as *mut $t).add(i)),+,)); |
27 f(*(*slices.get_unchecked(0) as *const GearId).add(i), |
|
28 ($(&*(*slices.get_unchecked($n + 1) as *mut $t).add(i)),+,)); |
28 } |
29 } |
29 } |
30 } |
30 } |
31 } |
31 } |
32 } |
32 |
33 |
33 impl<$($t: 'static),+> TypeTuple for ($(&mut $t),+,) { |
34 impl<$($t: 'static),+> TypeTuple for ($(&mut $t),+,) { |
34 fn get_types(types: &mut Vec<TypeId>) { |
35 fn get_types(types: &mut Vec<TypeId>) { |
35 $(types.push(TypeId::of::<$t>()));+ |
36 $(types.push(TypeId::of::<$t>()));+ |
36 } |
37 } |
37 |
38 |
38 unsafe fn iter<F: FnMut(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) { |
39 for i in 0..count { |
40 for i in 0..count { |
40 unsafe { |
41 unsafe { |
41 f(($(&mut *(*slices.get_unchecked($n) as *mut $t).add(i)),+,)); |
42 f(*(*slices.get_unchecked(0) as *const GearId).add(i), |
|
43 ($(&mut *(*slices.get_unchecked($n + 1) as *mut $t).add(i)),+,)); |
42 } |
44 } |
43 } |
45 } |
44 } |
46 } |
45 } |
47 } |
46 } |
48 } |
378 self.element_sizes[self.types.len()] = size_of::<T>() as u16; |
380 self.element_sizes[self.types.len()] = size_of::<T>() as u16; |
379 self.types.push(id); |
381 self.types.push(id); |
380 } |
382 } |
381 } |
383 } |
382 |
384 |
383 pub fn iter<T: TypeTuple + 'static, F: FnMut(T)>(&self, mut f: F) { |
385 |
|
386 pub fn iter<T: TypeTuple + 'static, F: FnMut(T)>(&mut self, mut f: F) { |
|
387 self.iter_id(|_, x| f(x)); |
|
388 } |
|
389 |
|
390 pub fn iter_id<T: TypeTuple + 'static, F: FnMut(GearId, T)>(&mut self, mut f: F) { |
384 let mut arg_types = Vec::with_capacity(64); |
391 let mut arg_types = Vec::with_capacity(64); |
385 T::get_types(&mut arg_types); |
392 T::get_types(&mut arg_types); |
386 |
393 |
387 let mut type_indices = vec![-1i8; arg_types.len()]; |
394 let mut type_indices = vec![-1i8; arg_types.len()]; |
388 let mut selector = 0u64; |
395 let mut selector = 0u64; |
395 selector |= 1 << i as u64; |
402 selector |= 1 << i as u64; |
396 } |
403 } |
397 None => panic!("Unregistered type"), |
404 None => panic!("Unregistered type"), |
398 } |
405 } |
399 } |
406 } |
400 let mut slices = vec![null_mut(); arg_types.len()]; |
407 let mut slices = vec![null_mut(); arg_types.len() + 1]; |
401 |
408 |
402 for (block_index, mask) in self.block_masks.iter().enumerate() { |
409 for (block_index, mask) in self.block_masks.iter().enumerate() { |
403 if mask & selector == selector { |
410 if mask & selector == selector { |
404 let block = &self.blocks[block_index]; |
411 let block = &mut self.blocks[block_index]; |
405 block.elements_count; |
412 slices[0] = block.data.as_mut_ptr(); |
|
413 |
406 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() { |
414 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() { |
407 slices[arg_index as usize] = block.component_blocks[type_index as usize] |
415 slices[arg_index as usize + 1] = block.component_blocks[type_index as usize] |
408 .unwrap() |
416 .unwrap() |
409 .as_ptr() |
417 .as_ptr() |
410 } |
418 } |
411 |
419 |
412 unsafe { |
420 unsafe { |
413 T::iter(&slices[..], block.elements_count as usize, |x| f(x)); |
421 T::iter(&slices[..], block.elements_count as usize, |id, x| f(id, x)); |
414 } |
422 } |
415 } |
423 } |
416 } |
424 } |
417 } |
425 } |
418 } |
426 } |