Change entity disabling/enabling components to be recursive over Children#24158
Conversation
… recursively over `ChildOf`
alice-i-cecile
left a comment
There was a problem hiding this comment.
It would be cool if this was generic over all relations based on the linked despawn behavior, but I don't see any way to get there immediately.
|
Import is broken :) |
ChildOfChildren
This is already possible since |
|
A couple of observations:
|
|
Eh whatever here is the 0.18 code from my crate, you pass an fn add_enablded_children_to_set(
world: &World,
parent: EntityRef,
entities_set: &mut EntityHashSet
) {
if parent.contains::<Disabled>() {
// already disabled
return;
}
let children = parent
.archetype()
.components()
.iter()
.flat_map(|&component_id| {
world
.components()
.get_info(component_id)
.unwrap() // listed component id should be known to the world
.relationship_accessor()
.and_then(|relationship| match *relationship {
RelationshipAccessor::RelationshipTarget { iter, linked_spawn: true } => {
// should not panic as parent's archetype lists this component id
let ptr = parent.get_by_id(component_id).unwrap();
// SAFETY: given ComponentId matches the RelationshipAccessor of the
// component type
unsafe { Some(iter(ptr)) }
}
_ => None,
})
.into_iter()
.flatten()
});
for child in children {
if !entities_set.insert(child) {
// already known
continue;
}
let Ok(child_ref) = world.get_entity(child) else {
// despawned
entities_set.remove(child);
continue;
};
if child_ref.contains::<Disabled>() {
// already disabled
entities_set.remove(child);
continue;
}
add_enablded_children_to_set(world, child_ref, entities_set);
}
}Then you'd batch-insert it with the set. I have no method for enabling them again but you get the gist here to rewrite it for that too. Probably just need another boolean argument and do equality checks with |
These operations should have tests, IMHO, to assure clarity of intended function. They can be fragile to changes of code. (See history of visibility operations for examples.) |
Objective
Addresses part of #24157
Solution
Change
.try_insert(Disabled)to.insert_recursive::<Children>(Disabled), and.try_remove::<Disabled>()to.remove_recursive::<Children, Disabled>()