I'm trying to understand some ECS behaviour with hierarchy but i'm struggling.
I wrote this test:
#[derive(Resource, Default)]
struct Counter(usize);
fn observe_children_updated(trigger: Trigger<OnAdd, ChildOf>, parent: Query<&ChildOf>, children: Query<&Children>, mut counter: ResMut<Counter>) {
if let Some(parent) = parent.related(trigger.target()) {
std::dbg!("ChildOf is present");
if let Ok(children) = children.get(parent) {
std::dbg!("Parent's children:", children);
counter.0 += 1
}
}
}
#[test]
fn child_spawn_observer() {
let mut world = World::new();
world.init_resource::<Counter>();
world.add_observer(observe_children_updated);
let parent = world.spawn_empty().id();
let child = world.spawn(ChildOf(parent));
let child_2 = world.spawn(ChildOf(parent));
assert_eq!(world.resource::<Counter>().0, 1);
}
What I see is:
"ChildOf is present" = "ChildOf is present"
"ChildOf is present" = "ChildOf is present"
"Parent's children:" = "Parent's children:"
children = Children(
[
2v1#4294967298,
],
)
It makes sense that Children is only printed on the second call. On the first call, when ChildOf is inserted, the order of operations is:
- ChildOf inserted
- on-add hook runs, queues a command to insert
Childrenon parent - parent observer runs but
Childrenis missing - flush, which adds
Childrenon the parent
But I don't get why when the second child gets inserted; the log doesn't show both children inside of Children, since the order should be:
- ChildOf inserted
- on-add hook runs, adds an extra child to the
Childrencomponent of the parent - parent observers runs and queries
Children=> is it we don't callupdate_archetypes()so theQueryhasn't been updated?