child spawned before a parent sometimes becomes a sibling?
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## Bevy version
main 1116207
Replicates in 0.11.2
## What you did
```
use bevy::prelude::*;
const S: Val = Val::Px(100.);
const B: Val = Val::Px(10.);
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, update)
.run();
}
fn update(input: Res>, mut root_node_query: Query<&mut Style, Without>, mut text_query: Query<&mut Text>) {
if input.just_pressed(KeyCode::W) {
for mut style in root_node_query.iter_mut() {
style.width = match style.width {
Val::Auto => Val::Percent(100.),
_ => Val::Auto,
};
text_query.single_mut().sections[1].value = format!("{:?}", style.width);
}
}
if input.just_pressed(KeyCode::Space) {
for mut style in root_node_query.iter_mut() {
style.align_items = match style.align_items {
AlignItems::Default => AlignItems::Start,
AlignItems::Start => AlignItems::Stretch,
AlignItems::Stretch => AlignItems::Baseline,
AlignItems::Baseline => AlignItems::Center,
AlignItems::Center => AlignItems::End,
AlignItems::End => AlignItems::FlexStart,
AlignItems::FlexStart => AlignItems::FlexEnd,
AlignItems::FlexEnd => AlignItems::Default,
};
text_query.single_mut().sections[3].value = format!("{:?}", style.align_items);
}
}
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());
commands
.spawn(NodeBundle {
style: Style {
flex_direction: FlexDirection::Column,
row_gap: B,
..Default::default()
},
..Default::default()
})
.with_children(|builder| {
spawn_grid(builder);
builder.spawn(TextBundle::from_sections([
"width: ".into(),
"Auto".into(),
"\nalign_items: ".into(),
"Default".into(),
]));
});
}
fn spawn_grid(builder: &mut ChildBuilder) {
builder
.spawn(NodeBundle {
style: Style {
column_gap: B,
..Default::default()
},
background_color: Color::BLACK.into(),
..Default::default()
})
.with_children(|builder| {
case_1(builder);
case_1(builder);
case_1(builder);
});
builder
.spawn(NodeBundle {
style: Style {
column_gap: B,
..Default::default()
},
background_color: Color::BLACK.into(),
..Default::default()
})
.with_children(|builder| {
case_1(builder);
case_2(builder);
case_1(builder);
});
builder
.spawn(NodeBundle {
style: Style {
column_gap: B,
..Default::default()
},
background_color: Color::BLACK.into(),
..Default::default()
})
.with_children(|builder| {
case_1(builder);
case_3(builder);
case_1(builder);
});
}
fn child() -> NodeBundle {
NodeBundle {
style: Style {
flex_grow: 1.,
..Default::default()
},
background_color: Color::BLUE.into(),
..Default::default()
}
}
fn parent() -> NodeBundle {
NodeBundle {
style: Style {
width: S,
height: S,
border: UiRect::all(B),
..Default::default()
},
background_color: Color::RED.into(),
..Default::default()
}
}
fn child_2() -> NodeBundle {
NodeBundle {
style: Style {
..Default::default()
},
background_color: Color::BLUE.into(),
..Default::default()
}
}
fn parent_2() -> NodeBundle {
NodeBundle {
style: Style {
width: S,
height: S,
border: UiRect::all(B),
align_items: AlignItems::Stretch,
..Default::default()
},
background_color: Color::RED.into(),
..Default::default()
}
}
fn case_1(builder: &mut ChildBuilder) {
builder.spawn(parent()).with_children(|builder| {
builder.spawn(child());
});
}
fn case_2(builder: &mut ChildBuilder) {
let parent_id = builder.spawn(parent()).id();
let child_id = builder.spawn(child()).id();
builder.add_command(AddChild {
parent: parent_id,
child: child_id,
});
}
fn case_3(builder: &mut ChildBuilder) {
let child_id = builder.spawn(child_2()).id();
builder.spawn(parent_2()).add_child(child_id);
}
```
## What went wrong
Lots of bugs, as far as I can tell:
1. Should not have a black gap on the end.
2. Second node should have a blue child node centered on it and the gap between the second and third node is doubled.
3. Second node should have a blue child node centered on it and the gap between the first and second node is doubled.
1. This row is correct.
2. Second node should have a blue child node centered on it and the gap between the second and third node is doubled.
3. Second node should have a blue child node centered on it and the gap between the first and second node is doubled.
1. This row is correct.
2. The blue child is added as a child of its parent's parent.
3. Second node should have a blue child node centered on it and the gap between the first and second node is doubled.
Other combinations also have problems, not got time to write them all up now.
Contributor guide
Research direction
Run the provided Rust reproduction and start with the setup, spawn_grid, case_2, and case_3 entry points, comparing the different child-attachment paths. Done means the reproduced layouts consistently retain the intended parent-child relationships, child positioning, and gap sizes across the listed width and align_items states.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100