lyra-engine/lyra-ecs/src/query/view.rs

93 lines
2.3 KiB
Rust
Raw Normal View History

2023-11-25 18:43:11 -05:00
use std::ops::Range;
2023-11-29 23:21:27 -05:00
use crate::{archetype::{Archetype, ArchetypeId}, world::{ArchetypeEntityId, World}};
2023-11-25 18:43:11 -05:00
use super::{Query, Fetch};
pub struct View<'a, Q: Query> {
2023-11-29 23:21:27 -05:00
world: &'a World,
2023-11-25 18:43:11 -05:00
query: Q,
archetypes: Vec<&'a Archetype>,
}
impl<'a, Q> View<'a, Q>
where
Q: Query,
{
2023-11-29 23:21:27 -05:00
pub fn new(world: &'a World, query: Q, archetypes: Vec<&'a Archetype>) -> Self {
2023-11-25 18:43:11 -05:00
Self {
2023-11-29 23:21:27 -05:00
world,
2023-11-25 18:43:11 -05:00
query,
archetypes,
}
}
}
impl<'a, Q> IntoIterator for View<'a, Q>
where
Q: Query,
{
type Item = Q::Item<'a>;
type IntoIter = ViewIter<'a, Q>;
fn into_iter(self) -> Self::IntoIter {
ViewIter {
2023-11-29 23:21:27 -05:00
world: self.world,
2023-11-25 18:43:11 -05:00
query: self.query,
fetcher: Q::Fetch::dangling(),
2023-11-25 18:43:11 -05:00
archetypes: self.archetypes,
next_archetype: 0,
component_indices: 0..0,
}
}
}
pub struct ViewIter<'a, Q: Query> {
2023-11-29 23:21:27 -05:00
world: &'a World,
2023-11-25 18:43:11 -05:00
query: Q,
fetcher: Q::Fetch<'a>,
archetypes: Vec<&'a Archetype>,
next_archetype: usize,
component_indices: Range<u64>,
}
impl<'a, Q> Iterator for ViewIter<'a, Q>
where
Q: Query,
{
type Item = Q::Item<'a>;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(entity_index) = self.component_indices.next() {
let entity_index = ArchetypeEntityId(entity_index);
if !self.fetcher.can_visit_item(entity_index) {
continue;
} else {
let i = unsafe { self.fetcher.get_item(entity_index) };
return Some(i);
}
} else {
if self.next_archetype >= self.archetypes.len() {
return None; // ran out of archetypes to go through
}
let arch_id = self.next_archetype;
self.next_archetype += 1;
let arch = unsafe { self.archetypes.get_unchecked(arch_id) };
if arch.entities.len() == 0 {
continue;
}
if !self.query.can_visit_archetype(arch) {
continue;
}
2023-11-29 23:21:27 -05:00
self.fetcher = unsafe { self.query.fetch(self.world, ArchetypeId(arch_id as u64), arch) };
2023-11-25 18:43:11 -05:00
self.component_indices = 0..arch.entities.len() as u64;
}
}
}
}