271 dest_block_index: u16, |
276 dest_block_index: u16, |
272 ) -> u16 { |
277 ) -> u16 { |
273 debug_assert!(src_block_index != dest_block_index); |
278 debug_assert!(src_block_index != dest_block_index); |
274 let src_mask = self.block_masks[src_block_index as usize]; |
279 let src_mask = self.block_masks[src_block_index as usize]; |
275 let dest_mask = self.block_masks[dest_block_index as usize]; |
280 let dest_mask = self.block_masks[dest_block_index as usize]; |
276 debug_assert!(src_mask.type_mask & dest_mask.type_mask == src_mask.type_mask); |
281 debug_assert!(src_mask.type_mask & dest_mask.type_mask != 0); |
277 |
282 |
278 let src_block = &self.blocks[src_block_index as usize]; |
283 let src_block = &self.blocks[src_block_index as usize]; |
279 let dest_block = &self.blocks[dest_block_index as usize]; |
284 let dest_block = &self.blocks[dest_block_index as usize]; |
280 debug_assert!(src_index < src_block.elements_count); |
285 debug_assert!(src_index < src_block.elements_count); |
281 debug_assert!(!dest_block.is_full()); |
286 debug_assert!(!dest_block.is_full()); |
286 while type_mask != 0 { |
291 while type_mask != 0 { |
287 let i = type_mask.trailing_zeros() as usize; |
292 let i = type_mask.trailing_zeros() as usize; |
288 |
293 |
289 let size = self.element_sizes[i]; |
294 let size = self.element_sizes[i]; |
290 let src_ptr = src_block.component_blocks[i].unwrap().as_ptr(); |
295 let src_ptr = src_block.component_blocks[i].unwrap().as_ptr(); |
291 let dest_ptr = dest_block.component_blocks[i].unwrap().as_ptr(); |
296 if let Some(dest_ptr) = dest_block.component_blocks[i] { |
|
297 let dest_ptr = dest_ptr.as_ptr(); |
|
298 unsafe { |
|
299 copy_nonoverlapping( |
|
300 src_ptr.add((src_index * size) as usize), |
|
301 dest_ptr.add((dest_index * size) as usize), |
|
302 size as usize, |
|
303 ); |
|
304 } |
|
305 } |
292 unsafe { |
306 unsafe { |
293 copy_nonoverlapping( |
|
294 src_ptr.add((src_index * size) as usize), |
|
295 dest_ptr.add((dest_index * size) as usize), |
|
296 size as usize, |
|
297 ); |
|
298 if src_index < src_block.elements_count - 1 { |
307 if src_index < src_block.elements_count - 1 { |
299 copy_nonoverlapping( |
308 copy_nonoverlapping( |
300 src_ptr.add((size * (src_block.elements_count - 1)) as usize), |
309 src_ptr.add((size * (src_block.elements_count - 1)) as usize), |
301 src_ptr.add((size * src_index) as usize), |
310 src_ptr.add((size * src_index) as usize), |
302 size as usize, |
311 size as usize, |
308 } |
317 } |
309 |
318 |
310 let src_block = &mut self.blocks[src_block_index as usize]; |
319 let src_block = &mut self.blocks[src_block_index as usize]; |
311 let gear_id = src_block.gear_ids()[src_index as usize]; |
320 let gear_id = src_block.gear_ids()[src_index as usize]; |
312 |
321 |
313 if src_index < src_block.elements_count - 1 { |
322 if src_index + 1 < src_block.elements_count { |
314 let relocated_index = src_block.elements_count as usize - 1; |
323 let relocated_index = src_block.elements_count as usize - 1; |
315 let gear_ids = src_block.gear_ids_mut(); |
324 let gear_ids = src_block.gear_ids_mut(); |
316 let relocated_id = gear_ids[relocated_index]; |
325 let relocated_id = gear_ids[relocated_index]; |
317 |
326 |
318 gear_ids[src_index as usize] = relocated_id; |
327 gear_ids[src_index as usize] = relocated_id; |
468 } |
477 } |
469 } |
478 } |
470 |
479 |
471 pub fn remove<T: 'static>(&mut self, gear_id: GearId) { |
480 pub fn remove<T: 'static>(&mut self, gear_id: GearId) { |
472 if let Some(type_index) = self.get_type_index::<T>() { |
481 if let Some(type_index) = self.get_type_index::<T>() { |
|
482 let type_bit = 1 << type_index as u64; |
473 let entry = self.lookup[gear_id.get() as usize - 1]; |
483 let entry = self.lookup[gear_id.get() as usize - 1]; |
|
484 |
474 if let Some(index) = entry.index { |
485 if let Some(index) = entry.index { |
475 let mut dest_mask = self.block_masks[entry.block_index as usize]; |
486 let mask = self.block_masks[entry.block_index as usize]; |
476 dest_mask.type_mask &= !(1 << type_index as u64); |
487 let new_mask = mask.without_type(type_bit); |
477 |
488 |
478 if dest_mask.type_mask == 0 { |
489 if new_mask != mask { |
479 self.remove_from_block(entry.block_index, index.get() - 1); |
490 if new_mask.type_mask == 0 { |
480 } else { |
491 self.remove_from_block(entry.block_index, index.get() - 1); |
481 let dest_block_index = self.ensure_block(dest_mask); |
492 } else { |
482 self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index); |
493 let dest_block_index = self.ensure_block(new_mask); |
|
494 self.move_between_blocks( |
|
495 entry.block_index, |
|
496 index.get() - 1, |
|
497 dest_block_index, |
|
498 ); |
|
499 } |
483 } |
500 } |
484 } |
501 } |
485 } else { |
502 } else { |
486 panic!("Unregistered type") |
503 panic!("Unregistered type") |
487 } |
504 } |
627 #[cfg(test)] |
644 #[cfg(test)] |
628 mod test { |
645 mod test { |
629 use super::{super::common::GearId, GearDataManager}; |
646 use super::{super::common::GearId, GearDataManager}; |
630 |
647 |
631 #[derive(Clone)] |
648 #[derive(Clone)] |
632 struct Datum { |
649 struct DatumA { |
|
650 value: u32, |
|
651 } |
|
652 |
|
653 #[derive(Clone)] |
|
654 struct DatumB { |
633 value: u32, |
655 value: u32, |
634 } |
656 } |
635 |
657 |
636 #[derive(Clone)] |
658 #[derive(Clone)] |
637 struct Tag; |
659 struct Tag; |
638 |
660 |
639 #[test] |
661 #[test] |
640 fn direct_access() { |
662 fn direct_access() { |
641 let mut manager = GearDataManager::new(); |
663 let mut manager = GearDataManager::new(); |
642 manager.register::<Datum>(); |
664 manager.register::<DatumA>(); |
643 for i in 1..=5 { |
665 for i in 1..=5 { |
644 manager.add(GearId::new(i as u16).unwrap(), &Datum { value: i * i }); |
666 manager.add(GearId::new(i as u16).unwrap(), &DatumA { value: i * i }); |
645 } |
667 } |
646 |
668 |
647 for i in 1..=5 { |
669 for i in 1..=5 { |
648 assert_eq!( |
670 assert_eq!( |
649 manager |
671 manager |
650 .get::<Datum>(GearId::new(i as u16).unwrap()) |
672 .get::<DatumA>(GearId::new(i as u16).unwrap()) |
651 .unwrap() |
673 .unwrap() |
652 .value, |
674 .value, |
653 i * i |
675 i * i |
654 ); |
676 ); |
655 } |
677 } |
656 } |
678 } |
657 |
679 |
658 #[test] |
680 #[test] |
659 fn single_component_iteration() { |
681 fn single_component_iteration() { |
660 let mut manager = GearDataManager::new(); |
682 let mut manager = GearDataManager::new(); |
661 manager.register::<Datum>(); |
683 manager.register::<DatumA>(); |
|
684 |
662 for i in 1..=5 { |
685 for i in 1..=5 { |
663 manager.add(GearId::new(i as u16).unwrap(), &Datum { value: i }); |
686 manager.add(GearId::new(i as u16).unwrap(), &DatumA { value: i }); |
664 } |
687 } |
665 |
688 |
666 let mut sum = 0; |
689 let mut sum = 0; |
667 manager.iter().run(|(d,): (&Datum,)| sum += d.value); |
690 manager.iter().run(|(d,): (&DatumA,)| sum += d.value); |
668 assert_eq!(sum, 15); |
691 assert_eq!(sum, 15); |
669 |
692 |
670 manager.iter().run(|(d,): (&mut Datum,)| d.value += 1); |
693 manager.iter().run(|(d,): (&mut DatumA,)| d.value += 1); |
671 manager.iter().run(|(d,): (&Datum,)| sum += d.value); |
694 manager.iter().run(|(d,): (&DatumA,)| sum += d.value); |
672 assert_eq!(sum, 35); |
695 assert_eq!(sum, 35); |
673 } |
696 } |
674 |
697 |
675 #[test] |
698 #[test] |
676 fn tagged_component_iteration() { |
699 fn tagged_component_iteration() { |
677 let mut manager = GearDataManager::new(); |
700 let mut manager = GearDataManager::new(); |
678 manager.register::<Datum>(); |
701 manager.register::<DatumA>(); |
679 manager.register::<Tag>(); |
702 manager.register::<Tag>(); |
|
703 |
680 for i in 1..=10 { |
704 for i in 1..=10 { |
681 let gear_id = GearId::new(i as u16).unwrap(); |
705 let gear_id = GearId::new(i as u16).unwrap(); |
682 manager.add(gear_id, &Datum { value: i }); |
706 manager.add(gear_id, &DatumA { value: i }); |
683 } |
707 } |
684 |
708 |
685 for i in 1..=10 { |
709 for i in (2..=10).step_by(2) { |
686 let gear_id = GearId::new(i as u16).unwrap(); |
710 let gear_id = GearId::new(i as u16).unwrap(); |
687 if i & 1 == 0 { |
711 manager.add_tag::<Tag>(gear_id); |
688 manager.add_tag::<Tag>(gear_id); |
|
689 } |
|
690 } |
712 } |
691 |
713 |
692 let mut sum = 0; |
714 let mut sum = 0; |
693 manager.iter().run(|(d,): (&Datum,)| sum += d.value); |
715 manager.iter().run(|(d,): (&DatumA,)| sum += d.value); |
694 assert_eq!(sum, 55); |
716 assert_eq!(sum, 55); |
695 |
717 |
696 let mut tag_sum = 0; |
718 let mut tag_sum = 0; |
697 manager |
719 manager |
698 .iter() |
720 .iter() |
699 .with_tags::<&Tag>() |
721 .with_tags::<&Tag>() |
700 .run(|(d,): (&Datum,)| tag_sum += d.value); |
722 .run(|(d,): (&DatumA,)| tag_sum += d.value); |
701 assert_eq!(tag_sum, 30); |
723 assert_eq!(tag_sum, 30); |
702 } |
724 } |
703 } |
725 |
|
726 #[test] |
|
727 fn removal() { |
|
728 let mut manager = GearDataManager::new(); |
|
729 manager.register::<DatumA>(); |
|
730 manager.register::<DatumB>(); |
|
731 |
|
732 for i in 1..=10 { |
|
733 let gear_id = GearId::new(i as u16).unwrap(); |
|
734 manager.add(gear_id, &DatumA { value: i }); |
|
735 manager.add(gear_id, &DatumB { value: i }); |
|
736 } |
|
737 |
|
738 for i in (1..=10).step_by(2) { |
|
739 let gear_id = GearId::new(i as u16).unwrap(); |
|
740 manager.remove::<DatumA>(gear_id); |
|
741 } |
|
742 |
|
743 let mut sum_a = 0; |
|
744 manager.iter().run(|(d,): (&DatumA,)| sum_a += d.value); |
|
745 assert_eq!(sum_a, 30); |
|
746 |
|
747 let mut sum_b = 0; |
|
748 manager.iter().run(|(d,): (&DatumB,)| sum_b += d.value); |
|
749 assert_eq!(sum_b, 55); |
|
750 } |
|
751 } |