Skip to main content

examples/observers/
observer_propagate.rs

1use crate::z_ignore_test_common::*;
2
3use flecs_ecs::prelude::*;
4
5#[derive(Debug, Component)]
6pub struct Position {
7    pub x: f32,
8    pub y: f32,
9}
10
11// Events are propagated along relationship edges. This means that observers can
12// listen for events from a parent or prefab, like triggering when a component
13// inherited from a prefab was set.
14//
15// Event propagation happens automatically when an observer contains a query
16// with the EcsUp flag set (indicating upwards traversal). Observers use the
17// same matching logic as queries: if a query with upwards traversal matches an
18// entity, so will an observer.
19//
20// Events are only propagated along traversable relationship edges.
21
22fn main() {
23    let world = World::new();
24
25    // Create observer that listens for events from both self and parent
26    world
27        .observer::<flecs::OnSet, (&Position, &Position)>()
28        .term_at(1)
29        .parent()
30        .each_iter(|it, index, (pos_self, pos_parent)| {
31            println!(
32                " - {}: {}: {}: self: {{ {}, {} }}, parent: {{ {}, {} }}",
33                it.event().name(),
34                it.event_id().to_str(),
35                it.entity(index).name(),
36                pos_self.x,
37                pos_self.y,
38                pos_parent.x,
39                pos_parent.y
40            );
41        });
42
43    // Create entity and parent
44    let parent = world.entity_named("p");
45    let entity = world.entity_named("e").child_of(parent);
46
47    // Set Position on entity. This doesn't trigger the observer yet, since the
48    // parent doesn't have Position yet.
49    entity.set(Position { x: 10.0, y: 20.0 });
50
51    // Set Position on parent. This event will be propagated and trigger the
52    // observer, as the observer query now matches.
53    parent.set(Position { x: 1.0, y: 2.0 });
54
55    // Output:
56    //  - OnSet: Position: e: self: { 10, 20 }, parent: { 1, 2 }
57}
58
59#[cfg(feature = "flecs_nightly_tests")]
60#[test]
61fn test() {
62    let output_capture = OutputCapture::capture().unwrap();
63    main();
64    output_capture.test("observer_propagate".to_string());
65}