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}