1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
use hibitset::{BitSet, BitSetLike}; use specs::{Entity, Join}; pub trait GuidedJoin<'a, G, I>: Join where G: 'a + IntoIterator<Item = &'a Entity, IntoIter = I>, I: 'a + Iterator<Item = &'a Entity>, <Self as Join>::Type: 'a, { #[inline] fn guided_join(self, guide: G) -> GuidedJoinIter<'a, Self, I> where Self: Sized, { GuidedJoinIter::new(self, guide.into_iter()) } } impl<'a, J, G, I> GuidedJoin<'a, G, I> for J where G: 'a + IntoIterator<Item = &'a Entity, IntoIter = I>, I: 'a + Iterator<Item = &'a Entity>, J: 'a + Join, {} pub struct GuidedJoinIter<'a, J, I> where I: 'a + Iterator<Item = &'a Entity>, J: 'a + Join, { bitset: BitSet, guide: I, values: J::Value, } impl<'a, J, I> GuidedJoinIter<'a, J, I> where I: 'a + Iterator<Item = &'a Entity>, J: 'a + Join, { #[inline] fn new(join: J, guide: I) -> Self where Self: Sized, { let (keys, values) = unsafe { join.open() }; let mut bitset = BitSet::new(); for idx in keys.iter() { bitset.add(idx); } GuidedJoinIter { bitset: bitset, guide: guide, values: values, } } } impl<'a, J, I> Iterator for GuidedJoinIter<'a, J, I> where I: 'a + Iterator<Item = &'a Entity>, J: 'a + Join, { type Item = J::Type; #[inline] fn next(&mut self) -> Option<J::Type> { while let Some(entity) = self.guide.next() { let index = entity.id(); if self.bitset.contains(index) { return Some(unsafe { J::get(&mut self.values, index) }); } } None } }