brood/query/
entries.rs

1//! Entity access at query time.
2//!
3//! This module allows access to entity entries in a `World` while iterating over entities in the
4//! same `World`. Such access allows for strong inter-entity relationships.
5//!
6//! Access to components of entities is restricted to the specific components viewed. These views
7//! must not conflict with the components being iterated simultaneously.
8
9use crate::{
10    entity,
11    entity::allocator::Location,
12    query::{
13        filter::And,
14        view,
15        view::SubSet,
16    },
17    registry,
18    registry::contains::views::{
19        ContainsViewsOuter,
20        Sealed as ContainsViewsSealed,
21    },
22    Query,
23    World,
24};
25use core::marker::PhantomData;
26
27/// A view into a single entity in a [`World`].
28///
29/// [`World`]: crate::World
30pub struct Entry<'a, 'b, Registry, Resources, Views, Indices>
31where
32    Registry: registry::Registry,
33{
34    entries: &'b mut Entries<'a, Registry, Resources, Views, Indices>,
35    location: Location<Registry>,
36}
37
38impl<'a, 'b, Registry, Resources, Views, Indices> Entry<'a, 'b, Registry, Resources, Views, Indices>
39where
40    Registry: registry::Registry,
41{
42    fn new(
43        entries: &'b mut Entries<'a, Registry, Resources, Views, Indices>,
44        location: Location<Registry>,
45    ) -> Self {
46        Self { entries, location }
47    }
48}
49
50impl<'a, 'b, Registry, Resources, Views, Indices> Entry<'a, 'b, Registry, Resources, Views, Indices>
51where
52    Views: view::Views<'a>,
53    Registry: registry::ContainsViews<'a, Views, Indices>,
54{
55    /// Query for components contained within this entity using the given `SubViews` and `Filter`.
56    ///
57    /// Returns a `Some` value if the entity matches the `SubViews` and `Filter`, and returns a
58    /// `None` value otherwise.
59    ///
60    /// Note that `SubViews` must be a [`SubSet`] of `Views`. See the documentation for the
61    /// `SubSet` trait for what exactly is required for a subset.
62    pub fn query<SubViews, Filter, FilterIndices, SubViewsFilterIndices, SubSetIndices>(
63        &mut self,
64        #[allow(unused_variables)] query: Query<SubViews, Filter>,
65    ) -> Option<SubViews>
66    where
67        SubViews: SubSet<'a, Views, SubSetIndices> + view::Views<'a>,
68        // Note: we currently can't filter on components outside of the `Views`. This is an
69        // unfortunate limitation of not being able to index directly into the `Registry` for an
70        // arbitrary `Filter`.
71        Views: view::ContainsFilter<
72            'a,
73            And<Filter, SubViews>,
74            And<FilterIndices, SubViewsFilterIndices>,
75        >,
76    {
77        let indices = <<Registry as ContainsViewsSealed<'a, Views, Indices>>::Viewable as ContainsViewsOuter<'a, Views, <Registry as ContainsViewsSealed<'a, Views, Indices>>::Containments, <Registry as ContainsViewsSealed<'a, Views, Indices>>::Indices, <Registry as ContainsViewsSealed<'a, Views, Indices>>::ReshapeIndices>>::indices();
78        // SAFETY: The `indices` provided here are the valid indices into `Registry`, and therefore
79        // into the `archetype::Identifier<Registry>` used here.
80        if unsafe { Views::filter(&indices, self.location.identifier) } {
81            // Since we can't view with the subviews directly on the registry, we instead view on
82            // the super-views `Views` first, and then mask it with the `SubViews`.
83            //
84            // This is necessary because callers can't guarantee that every possible `Registry` is
85            // viewable by every possible `SubViews` (for example, in a `System` where the
86            // `Registry` is generic). Therefore, we instead prove that the `Views` can be viewed
87            // by the `SubViews`.
88
89            // SAFETY: `self.location.index` is a valid index into this archetype, as guaranteed by
90            // the entity allocator.
91            let super_views = unsafe {
92                (*self.entries.world)
93                    .archetypes
94                    .get_mut(self.location.identifier)?
95                    .view_row_maybe_uninit_unchecked::<Views, Indices>(self.location.index)
96            };
97
98            // SAFETY: `super_views` is viewed on the archetype identified by
99            // `self.location.identifier`. The `indices` also correspond to the registry the
100            // archetype is generic over. Finally, the `SubViews` filter has already been applied.
101            Some(unsafe { SubViews::view(super_views, indices, self.location.identifier) })
102        } else {
103            None
104        }
105    }
106}
107
108/// Access to entity [`Entry`]s.
109///
110/// These entity `Entry`s allow access to the components viewed in `Views`.
111pub struct Entries<'a, Registry, Resources, Views, Indices>
112where
113    Registry: registry::Registry,
114{
115    world: *mut World<Registry, Resources>,
116
117    lifetime: PhantomData<&'a ()>,
118    views: PhantomData<Views>,
119    indices: PhantomData<Indices>,
120}
121
122impl<'a, Registry, Resources, Views, Indices> Entries<'a, Registry, Resources, Views, Indices>
123where
124    Registry: registry::Registry,
125{
126    /// Creates a new `Entries` for the given `world`, allowing [`Entry`] access to the components
127    /// viewed by `Views`.
128    ///
129    /// # Safety
130    /// The returned `Entries` must not outlive `world`. In other words, the lifetime `'a` must not
131    /// outlive the lifetime of `world`.
132    ///
133    /// The components in `world` accessed by `Views` must not be accessed anywhere else (such as,
134    /// for example, in a simultaneous query iteration).
135    ///
136    /// Entities must not be added or removed from the `World` while pointed at by `Entries`, nor
137    /// should existing entities change shape (meaning, they shouldn't be moved between
138    /// archetypes).
139    ///
140    /// # Example
141    /// ```
142    /// use brood::{
143    ///     entity,
144    ///     query::{
145    ///         filter,
146    ///         result,
147    ///         Views,
148    ///     },
149    ///     Query,
150    ///     Registry,
151    ///     World,
152    /// };
153    ///
154    /// #[derive(Debug, PartialEq)]
155    /// struct A(u32);
156    /// struct B(char);
157    ///
158    /// let mut world = World::<Registry!(A, B)>::new();
159    /// let entity_identifier = world.insert(entity!(A(42), B('a')));
160    ///
161    /// let mut query_result =
162    ///     world.query(Query::<Views!(), filter::None, Views!(), Views!(&A)>::new());
163    ///
164    /// let result!(a) = query_result
165    ///     .entries
166    ///     .entry(entity_identifier)
167    ///     .unwrap()
168    ///     .query(Query::<Views!(&A)>::new())
169    ///     .unwrap();
170    /// assert_eq!(a, &A(42));
171    /// ```
172    pub(crate) unsafe fn new(world: *mut World<Registry, Resources>) -> Self {
173        Entries {
174            world,
175
176            lifetime: PhantomData,
177            views: PhantomData,
178            indices: PhantomData,
179        }
180    }
181
182    /// Gets an [`Entry`] for the entity associated with an `entity::Identifier`.
183    ///
184    /// If no such entry exists, [`None`] is returned.
185    ///
186    /// [`None`]: Option::None
187    pub fn entry<'b>(
188        &'b mut self,
189        entity_identifier: entity::Identifier,
190    ) -> Option<Entry<'a, 'b, Registry, Resources, Views, Indices>> {
191        // SAFETY: The invariants of `Entries` guarantees that `World` won't have any entities
192        // added or removed, meaning the `entity_allocator` will not be mutated during this time.
193        unsafe { &*self.world }
194            .entity_allocator
195            .get(entity_identifier)
196            .map(|location| Entry::new(self, location))
197    }
198}
199
200// SAFETY: Since the access to the viewed components is unique, this can be sent between threads
201// safely.
202unsafe impl<'a, Registry, Resources, Views, Indices> Send
203    for Entries<'a, Registry, Resources, Views, Indices>
204where
205    Registry: registry::Registry,
206{
207}
208
209// SAFETY: Since the access to the viewed components is unique, this can be shared between threads
210// safely.
211unsafe impl<'a, Registry, Resources, Views, Indices> Sync
212    for Entries<'a, Registry, Resources, Views, Indices>
213where
214    Registry: registry::Registry,
215{
216}
217
218#[cfg(test)]
219mod tests {
220    use super::Entries;
221    use crate::{
222        entity,
223        query::{
224            filter,
225            result,
226            Views,
227        },
228        Query,
229        Registry,
230        World,
231    };
232    use claims::{
233        assert_none,
234        assert_some,
235    };
236
237    // Define components.
238    #[derive(Debug, PartialEq)]
239    struct A(u32);
240    #[derive(Debug, PartialEq)]
241    struct B(char);
242    #[derive(Debug, PartialEq)]
243    struct C(f32);
244
245    type Registry = Registry!(A, B, C);
246
247    #[test]
248    fn empty_query() {
249        let mut world = World::<Registry!()>::new();
250        let identifier = world.insert(entity!());
251
252        let mut entries = unsafe { Entries::<_, _, Views!(), _>::new(&mut world) };
253        let mut entry = assert_some!(entries.entry(identifier));
254
255        assert_some!(entry.query(Query::<Views!()>::new()));
256    }
257
258    #[test]
259    fn empty_query_with_filter_succeeds() {
260        let mut world = World::<Registry>::new();
261        let identifier = world.insert(entity!(A(42)));
262
263        let mut entries = unsafe { Entries::<_, _, Views!(&A), _>::new(&mut world) };
264        let mut entry = assert_some!(entries.entry(identifier));
265
266        assert_some!(entry.query(Query::<Views!(), filter::Has<A>>::new()));
267    }
268
269    #[test]
270    fn empty_query_with_filter_fails() {
271        let mut world = World::<Registry>::new();
272        let identifier = world.insert(entity!(A(42)));
273
274        let mut entries = unsafe { Entries::<_, _, Views!(&B), _>::new(&mut world) };
275        let mut entry = assert_some!(entries.entry(identifier));
276
277        assert_none!(entry.query(Query::<Views!(), filter::Has<B>>::new()));
278    }
279
280    #[test]
281    fn empty_query_with_filter_on_mutable_ref_in_super_views() {
282        let mut world = World::<Registry>::new();
283        let identifier = world.insert(entity!(A(42)));
284
285        let mut entries = unsafe { Entries::<_, _, Views!(&mut A), _>::new(&mut world) };
286        let mut entry = assert_some!(entries.entry(identifier));
287
288        assert_some!(entry.query(Query::<Views!(), filter::Has<A>>::new()));
289    }
290
291    #[test]
292    fn empty_query_with_filter_on_optional_ref_in_super_views() {
293        let mut world = World::<Registry>::new();
294        let identifier = world.insert(entity!(A(42)));
295
296        let mut entries = unsafe { Entries::<_, _, Views!(Option<&A>), _>::new(&mut world) };
297        let mut entry = assert_some!(entries.entry(identifier));
298
299        assert_some!(entry.query(Query::<Views!(), filter::Has<A>>::new()));
300    }
301
302    #[test]
303    fn empty_query_with_filter_on_optional_mutable_ref_in_super_views() {
304        let mut world = World::<Registry>::new();
305        let identifier = world.insert(entity!(A(42)));
306
307        let mut entries = unsafe { Entries::<_, _, Views!(Option<&mut A>), _>::new(&mut world) };
308        let mut entry = assert_some!(entries.entry(identifier));
309
310        assert_some!(entry.query(Query::<Views!(), filter::Has<A>>::new()));
311    }
312
313    #[test]
314    fn empty_query_with_filter_on_second_view_in_super_views() {
315        let mut world = World::<Registry>::new();
316        let identifier = world.insert(entity!(A(42)));
317
318        let mut entries = unsafe { Entries::<_, _, Views!(&C, &A), _>::new(&mut world) };
319        let mut entry = assert_some!(entries.entry(identifier));
320
321        assert_some!(entry.query(Query::<Views!(), filter::Has<A>>::new()));
322    }
323
324    #[test]
325    fn empty_query_with_or_filter() {
326        let mut world = World::<Registry>::new();
327        let identifier = world.insert(entity!(A(42)));
328
329        let mut entries = unsafe { Entries::<_, _, Views!(&A, &B), _>::new(&mut world) };
330        let mut entry = assert_some!(entries.entry(identifier));
331
332        assert_some!(
333            entry.query(Query::<Views!(), filter::Or<filter::Has<A>, filter::Has<B>>>::new())
334        );
335    }
336
337    #[test]
338    fn empty_query_with_or_filter_second() {
339        let mut world = World::<Registry>::new();
340        let identifier = world.insert(entity!(A(42)));
341
342        let mut entries = unsafe { Entries::<_, _, Views!(&A, &B), _>::new(&mut world) };
343        let mut entry = assert_some!(entries.entry(identifier));
344
345        assert_some!(
346            entry.query(Query::<Views!(), filter::Or<filter::Has<B>, filter::Has<A>>>::new())
347        );
348    }
349
350    #[test]
351    fn empty_query_with_and_filter() {
352        let mut world = World::<Registry>::new();
353        let identifier = world.insert(entity!(A(42), B('a')));
354
355        let mut entries = unsafe { Entries::<_, _, Views!(&A, &B), _>::new(&mut world) };
356        let mut entry = assert_some!(entries.entry(identifier));
357
358        assert_some!(
359            entry.query(Query::<Views!(), filter::And<filter::Has<A>, filter::Has<B>>>::new())
360        );
361    }
362
363    #[test]
364    fn empty_query_with_not_filter() {
365        let mut world = World::<Registry>::new();
366        let identifier = world.insert(entity!(A(42)));
367
368        let mut entries = unsafe { Entries::<_, _, Views!(&B), _>::new(&mut world) };
369        let mut entry = assert_some!(entries.entry(identifier));
370
371        assert_some!(entry.query(Query::<Views!(), filter::Not<filter::Has<B>>>::new()));
372    }
373
374    #[test]
375    fn empty_query_with_nonempty_superset() {
376        let mut world = World::<Registry>::new();
377        let identifier = world.insert(entity!());
378
379        let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
380        let mut entry = assert_some!(entries.entry(identifier));
381
382        assert_some!(entry.query(Query::<Views!()>::new()));
383    }
384
385    #[test]
386    fn query_immutable_superset_immutable() {
387        let mut world = World::<Registry>::new();
388        let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
389
390        let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
391        let mut entry = assert_some!(entries.entry(identifier));
392
393        let result!(a) = assert_some!(entry.query(Query::<Views!(&A)>::new()));
394        assert_eq!(a, &A(42));
395    }
396
397    #[test]
398    fn query_immutable_superset_mutable() {
399        let mut world = World::<Registry>::new();
400        let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
401
402        let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
403        let mut entry = assert_some!(entries.entry(identifier));
404
405        let result!(c) = assert_some!(entry.query(Query::<Views!(&C)>::new()));
406        assert_eq!(c, &C(3.14));
407    }
408
409    #[test]
410    fn query_mutable_superset_mutable() {
411        let mut world = World::<Registry>::new();
412        let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
413
414        let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
415        let mut entry = assert_some!(entries.entry(identifier));
416
417        let result!(c) = assert_some!(entry.query(Query::<Views!(&mut C)>::new()));
418        assert_eq!(c, &mut C(3.14));
419    }
420
421    #[test]
422    fn query_optional_immutable_superset_immutable() {
423        let mut world = World::<Registry>::new();
424        let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
425
426        let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
427        let mut entry = assert_some!(entries.entry(identifier));
428
429        let result!(a) = assert_some!(entry.query(Query::<Views!(Option<&A>)>::new()));
430        assert_eq!(a, Some(&A(42)));
431    }
432
433    #[test]
434    fn query_optional_immutable_superset_mutable() {
435        let mut world = World::<Registry>::new();
436        let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
437
438        let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
439        let mut entry = assert_some!(entries.entry(identifier));
440
441        let result!(c) = assert_some!(entry.query(Query::<Views!(Option<&C>)>::new()));
442        assert_eq!(c, Some(&C(3.14)));
443    }
444
445    #[test]
446    fn query_optional_immutable_superset_mutable_not_present() {
447        let mut world = World::<Registry>::new();
448        let identifier = world.insert(entity!(A(42), B('a')));
449
450        let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
451        let mut entry = assert_some!(entries.entry(identifier));
452
453        let result!(c) = assert_some!(entry.query(Query::<Views!(Option<&C>)>::new()));
454        assert_eq!(c, None);
455    }
456
457    #[test]
458    fn query_optional_mutable_superset_mutable() {
459        let mut world = World::<Registry>::new();
460        let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
461
462        let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
463        let mut entry = assert_some!(entries.entry(identifier));
464
465        let result!(c) = assert_some!(entry.query(Query::<Views!(Option<&mut C>)>::new()));
466        assert_eq!(c, Some(&mut C(3.14)));
467    }
468
469    #[test]
470    fn query_optional_mutable_superset_mutable_not_present() {
471        let mut world = World::<Registry>::new();
472        let identifier = world.insert(entity!(A(42), B('a')));
473
474        let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
475        let mut entry = assert_some!(entries.entry(identifier));
476
477        let result!(c) = assert_some!(entry.query(Query::<Views!(Option<&mut C>)>::new()));
478        assert_eq!(c, None);
479    }
480
481    #[test]
482    fn query_optional_none() {
483        let mut world = World::<Registry>::new();
484        let identifier = world.insert(entity!(A(42), C(3.14)));
485
486        let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C, &B), _>::new(&mut world) };
487        let mut entry = assert_some!(entries.entry(identifier));
488
489        let result!(b) = assert_some!(entry.query(Query::<Views!(Option<&B>)>::new()));
490        assert_eq!(b, None);
491    }
492
493    #[test]
494    fn query_entity_identifier() {
495        let mut world = World::<Registry>::new();
496        let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
497
498        let mut entries =
499            unsafe { Entries::<_, _, Views!(&A, &mut C, entity::Identifier), _>::new(&mut world) };
500        let mut entry = assert_some!(entries.entry(identifier));
501
502        let result!(queried_identifier) =
503            assert_some!(entry.query(Query::<Views!(entity::Identifier)>::new()));
504        assert_eq!(queried_identifier, identifier);
505    }
506
507    #[test]
508    fn query_multiple() {
509        let mut world = World::<Registry>::new();
510        let identifier = world.insert(entity!(B('a'), C(3.14)));
511
512        let mut entries =
513            unsafe { Entries::<_, _, Views!(&A, &mut B, entity::Identifier), _>::new(&mut world) };
514        let mut entry = assert_some!(entries.entry(identifier));
515
516        let result!(queried_identifier, b, a) =
517            assert_some!(entry.query(Query::<Views!(entity::Identifier, &B, Option<&A>)>::new()));
518        assert_eq!(queried_identifier, identifier);
519        assert_eq!(a, None);
520        assert_eq!(b, &B('a'));
521    }
522
523    #[test]
524    fn query_ref_with_optional_super_view() {
525        let mut world = World::<Registry>::new();
526        let identifier = world.insert(entity!(A(42)));
527
528        let mut entries = unsafe { Entries::<_, _, Views!(Option<&A>), _>::new(&mut world) };
529        let mut entry = assert_some!(entries.entry(identifier));
530
531        let result!(a) = assert_some!(entry.query(Query::<Views!(&A)>::new()));
532        assert_eq!(a, &A(42));
533    }
534
535    #[test]
536    fn query_ref_with_optional_mutable_super_view() {
537        let mut world = World::<Registry>::new();
538        let identifier = world.insert(entity!(A(42)));
539
540        let mut entries = unsafe { Entries::<_, _, Views!(Option<&mut A>), _>::new(&mut world) };
541        let mut entry = assert_some!(entries.entry(identifier));
542
543        let result!(a) = assert_some!(entry.query(Query::<Views!(&A)>::new()));
544        assert_eq!(a, &A(42));
545    }
546
547    #[test]
548    fn query_mutable_ref_with_optional_mutable_super_view() {
549        let mut world = World::<Registry>::new();
550        let identifier = world.insert(entity!(A(42)));
551
552        let mut entries = unsafe { Entries::<_, _, Views!(Option<&mut A>), _>::new(&mut world) };
553        let mut entry = assert_some!(entries.entry(identifier));
554
555        let result!(a) = assert_some!(entry.query(Query::<Views!(&mut A)>::new()));
556        assert_eq!(a, &mut A(42));
557    }
558
559    #[test]
560    fn query_optional_with_optional_super_view() {
561        let mut world = World::<Registry>::new();
562        let identifier = world.insert(entity!(A(42)));
563
564        let mut entries = unsafe { Entries::<_, _, Views!(Option<&A>), _>::new(&mut world) };
565        let mut entry = assert_some!(entries.entry(identifier));
566
567        let result!(a) = assert_some!(entry.query(Query::<Views!(Option<&A>)>::new()));
568        assert_eq!(a, Some(&A(42)));
569    }
570
571    #[test]
572    fn query_optional_with_optional_mutable_super_view() {
573        let mut world = World::<Registry>::new();
574        let identifier = world.insert(entity!(A(42)));
575
576        let mut entries = unsafe { Entries::<_, _, Views!(Option<&mut A>), _>::new(&mut world) };
577        let mut entry = assert_some!(entries.entry(identifier));
578
579        let result!(a) = assert_some!(entry.query(Query::<Views!(Option<&A>)>::new()));
580        assert_eq!(a, Some(&A(42)));
581    }
582
583    #[test]
584    fn query_optional_mutable_with_optional_mutable_super_view() {
585        let mut world = World::<Registry>::new();
586        let identifier = world.insert(entity!(A(42)));
587
588        let mut entries = unsafe { Entries::<_, _, Views!(Option<&mut A>), _>::new(&mut world) };
589        let mut entry = assert_some!(entries.entry(identifier));
590
591        let result!(a) = assert_some!(entry.query(Query::<Views!(Option<&mut A>)>::new()));
592        assert_eq!(a, Some(&mut A(42)));
593    }
594}