Skip to content

Commit

Permalink
Simplified ui_stack_system (bevyengine#9889)
Browse files Browse the repository at this point in the history
# Objective

`ui_stack_system` generates a tree of `StackingContexts` which it then
flattens to get the `UiStack`.

But there's no need to construct a new tree. We can query for nodes with
a global `ZIndex`, add those nodes to the root nodes list and then build
the `UiStack` from a walk of the existing layout tree, ignoring any
branches that have a global `Zindex`.

Fixes bevyengine#9877

## Solution

Split the `ZIndex` enum into two separate components, `ZIndex` and
`GlobalZIndex`

Query for nodes with a `GlobalZIndex`, add those nodes to the root nodes
list and then build the `UiStack` from a walk of the existing layout
tree, filtering branches by `Without<GlobalZIndex>` so we don't revisit
nodes.

```
cargo run --profile stress-test --features trace_tracy --example many_buttons
```

<img width="672" alt="ui-stack-system-walk-split-enum"
src="https://github.com/bevyengine/bevy/assets/27962798/11e357a5-477f-4804-8ada-c4527c009421">

(Yellow is this PR, red is main)

---

## Changelog
`Zindex`
* The `ZIndex` enum has been split into two separate components `ZIndex`
(which replaces `ZIndex::Local`) and `GlobalZIndex` (which replaces
`ZIndex::Global`). An entity can have both a `ZIndex` and
`GlobalZIndex`, in comparisons `ZIndex` breaks ties if two
`GlobalZIndex` values are equal.

`ui_stack_system`
* Instead of generating a tree of `StackingContexts`, query for nodes
with a `GlobalZIndex`, add those nodes to the root nodes list and then
build the `UiStack` from a walk of the existing layout tree, filtering
branches by `Without<GlobalZIndex` so we don't revisit nodes.

## Migration Guide

The `ZIndex` enum has been split into two separate components `ZIndex`
(which replaces `ZIndex::Local`) and `GlobalZIndex` (which replaces
`ZIndex::Global`). An entity can have both a `ZIndex` and
`GlobalZIndex`, in comparisons `ZIndex` breaks ties if two
`GlobalZindex` values are equal.

---------

Co-authored-by: Gabriel Bourgeois <gabriel.bourgeoisv4si@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: UkoeHB <37489173+UkoeHB@users.noreply.github.com>
  • Loading branch information
4 people authored and robtfm committed Oct 4, 2024
1 parent 1b33d72 commit 3aca5c2
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 199 deletions.
22 changes: 12 additions & 10 deletions crates/bevy_dev_tools/src/fps_overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ use bevy_render::view::Visibility;
use bevy_text::{Font, Text, TextSection, TextStyle};
use bevy_ui::{
node_bundles::{NodeBundle, TextBundle},
PositionType, Style, ZIndex,
GlobalZIndex, PositionType, Style,
};
use bevy_utils::default;

/// Global [`ZIndex`] used to render the fps overlay.
/// [`GlobalZIndex`] used to render the fps overlay.
///
/// We use a number slightly under `i32::MAX` so you can render on top of it if you really need to.
pub const FPS_OVERLAY_ZINDEX: i32 = i32::MAX - 32;
Expand Down Expand Up @@ -83,16 +83,18 @@ struct FpsText;

fn setup(mut commands: Commands, overlay_config: Res<FpsOverlayConfig>) {
commands
.spawn(NodeBundle {
style: Style {
// We need to make sure the overlay doesn't affect the position of other UI nodes
position_type: PositionType::Absolute,
.spawn((
NodeBundle {
style: Style {
// We need to make sure the overlay doesn't affect the position of other UI nodes
position_type: PositionType::Absolute,
..default()
},
// Render overlay on top of everything
..default()
},
// Render overlay on top of everything
z_index: ZIndex::Global(FPS_OVERLAY_ZINDEX),
..default()
})
GlobalZIndex(FPS_OVERLAY_ZINDEX),
))
.with_children(|c| {
c.spawn((
TextBundle::from_sections([
Expand Down
Loading

0 comments on commit 3aca5c2

Please sign in to comment.