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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
//! Low-level querying.
use std::iter::{repeat_n, Filter, FlatMap, RepeatN, Zip};
use crate::component::storage::archetype::{Archetype, ArchetypeEntity, EntityIter};
use crate::component::storage::{ArchetypeRefIter, Storage as ComponentStorage};
use crate::lock::ReadGuard;
use crate::query::options::Options;
use crate::query::Terms;
use crate::uid::Uid;
use crate::{EntityComponent, World};
/// Low-level entity query structure.
#[derive(Debug)]
pub struct Query<'world, 'terms>
{
component_storage: ReadGuard<'world, ComponentStorage>,
terms: Terms<'terms>,
}
impl<'world, 'terms> Query<'world, 'terms>
{
/// Iterates over the entities matching this query.
#[must_use]
pub fn iter<OptionsT: Options>(&self) -> Iter<'_>
{
Iter {
iter: self
.component_storage
.search_archetypes(self.terms.required_components.as_ref())
.flat_map(
(|archetype| {
repeat_n(archetype, archetype.entity_cnt())
.zip(archetype.entities())
}) as ComponentIterMapFn,
)
.filter(|(_, entity)| OptionsT::entity_filter(&entity.components)),
}
}
pub(crate) fn new(world: &'world World, terms: Terms<'terms>) -> Self
{
Self {
component_storage: world
.data
.component_storage
.read_nonblock()
.expect("Failed to acquire read-only component storage lock"),
terms,
}
}
}
pub struct Iter<'query>
{
iter: QueryEntityIter<'query>,
}
impl<'query> Iterator for Iter<'query>
{
type Item = EntityHandle<'query>;
fn next(&mut self) -> Option<Self::Item>
{
let (archetype, entity) = self.iter.next()?;
Some(EntityHandle { archetype, entity })
}
}
pub struct EntityHandle<'query>
{
archetype: &'query Archetype,
entity: &'query ArchetypeEntity,
}
impl<'query> EntityHandle<'query>
{
/// Returns the [`Uid`] of this entity.
#[inline]
#[must_use]
pub fn uid(&self) -> Uid
{
self.entity.uid
}
#[inline]
#[must_use]
pub fn components(&self) -> &'query [EntityComponent]
{
&self.entity.components
}
#[inline]
#[must_use]
pub fn get_component_index(&self, component_uid: Uid) -> Option<usize>
{
self.archetype.get_index_for_component(component_uid)
}
}
type ComponentIterMapFnOutput<'a> = Zip<RepeatN<&'a Archetype>, EntityIter<'a>>;
type ComponentIterMapFn = for<'a> fn(&'a Archetype) -> ComponentIterMapFnOutput<'a>;
type ComponentIterFilterFn =
for<'a, 'b> fn(&'a (&'b Archetype, &'b ArchetypeEntity)) -> bool;
type QueryEntityIter<'query> = Filter<
FlatMap<
ArchetypeRefIter<'query>,
ComponentIterMapFnOutput<'query>,
ComponentIterMapFn,
>,
ComponentIterFilterFn,
>;
|