bevy_ecs/
traversal.rs

1//! A trait for components that let you traverse the ECS.
2
3use crate::{entity::Entity, query::ReadOnlyQueryData, relationship::Relationship};
4
5/// A component that can point to another entity, and which can be used to define a path through the ECS.
6///
7/// Traversals are used to [specify the direction] of [event propagation] in [observers].
8/// The default query is `()`.
9///
10/// Infinite loops are possible, and are not checked for. While looping can be desirable in some contexts
11/// (for example, an observer that triggers itself multiple times before stopping), following an infinite
12/// traversal loop without an eventual exit will cause your application to hang. Each implementer of `Traversal`
13/// for documenting possible looping behavior, and consumers of those implementations are responsible for
14/// avoiding infinite loops in their code.
15///
16/// Traversals may be parameterized with additional data. For example, in observer event propagation, the
17/// parameter `D` is the event type given in `Trigger<E>`. This allows traversal to differ depending on event
18/// data.
19///
20/// [specify the direction]: crate::event::Event::Traversal
21/// [event propagation]: crate::observer::Trigger::propagate
22/// [observers]: crate::observer::Observer
23pub trait Traversal<D: ?Sized>: ReadOnlyQueryData {
24    /// Returns the next entity to visit.
25    fn traverse(item: Self::Item<'_>, data: &D) -> Option<Entity>;
26}
27
28impl<D> Traversal<D> for () {
29    fn traverse(_: Self::Item<'_>, _data: &D) -> Option<Entity> {
30        None
31    }
32}
33
34/// This provides generalized hierarchy traversal for use in [event propagation].
35///
36/// # Warning
37///
38/// Traversing in a loop could result in infinite loops for relationship graphs with loops.
39///
40/// [event propagation]: crate::observer::Trigger::propagate
41impl<R: Relationship, D> Traversal<D> for &R {
42    fn traverse(item: Self::Item<'_>, _data: &D) -> Option<Entity> {
43        Some(item.get())
44    }
45}