Description
Bevy version
main
What you did
I put this in a unit test on lib.rs
of bevy_ecs
to let me print the required components of A
and their depth:
#[derive(Component, Default)]
#[require(B)]
struct A;
#[derive(Component, Default)]
#[require(C)]
struct B;
#[derive(Component, Default)]
#[require(D)]
struct C;
#[derive(Component, Default)]
struct D;
let mut world = World::new();
let a_id = world.register_component::<A>();
std::println!("A: {:?}", a_id);
std::println!("B: {:?}", world.register_component::<B>());
std::println!("C: {:?}", world.register_component::<C>());
std::println!("D: {:?}", world.register_component::<D>());
let required = world
.components()
.get_info(a_id)
.unwrap()
.required_components();
for (id, meta) in &required.0 {
std::println!("required id: {id:?}, inheritance_depth: {}", meta.inheritance_depth);
}
What went wrong
This prints:
A: ComponentId(7)
B: ComponentId(8)
C: ComponentId(9)
D: ComponentId(10)
required id: ComponentId(9), inheritance_depth: 1
required id: ComponentId(10), inheritance_depth: 1
required id: ComponentId(8), inheritance_depth: 0
According to the docs of inheritance_depth
(I made the significant part bold) ...
The depth of the component requirement in the requirement hierarchy for this component.
This is used for determining which constructor is used in cases where there are duplicate requires.For example, consider the inheritance tree
X -> Y -> Z
, where->
indicates a requirement.
X -> Y
andY -> Z
are direct requirements with a depth of0
, whileZ
is only indirectly
required forX
with a depth of1
.In cases where there are multiple conflicting requirements with the same depth, a higher priority
will be given to components listed earlier in therequire
attribute, or to the latest added requirement
if registered at runtime.
... I expect the inheritance_depth
of D: ComponentId(10)
to be 2
, not 1
.
Either the docs are wrong or the implementation?
Right now it seems this can and will cause bugs with required components.
Additional information
I stumbled on this while fixing bundles becoming outdated by World::register_required_component
. I also saw for example the issue #16406 required three PRs (plus two closed ones) to be fixed. I can imagine this was caused by the actual issue not being found originally?.