Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MeasureFunc improvements #8402

Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c59149e
changes:
ickshonpe Mar 30, 2023
015dd74
fixed unused import
ickshonpe Mar 30, 2023
95f87a4
Merge branch 'bevyengine:main' into flex-node-system-double-leaf-upda…
ickshonpe Mar 31, 2023
3e1fbfe
changes:
ickshonpe Apr 16, 2023
eb47e13
Merge branch 'main' into dont-update-measure-funcs-on-layout-updates
ickshonpe Apr 16, 2023
8a511aa
Merge branch 'main' into dont-update-measure-funcs-on-layout-updates
ickshonpe Apr 18, 2023
3236980
cargo fmt
ickshonpe Apr 18, 2023
09687af
Removed left over commented section from merge
ickshonpe Apr 18, 2023
38931e4
renamed `CalculatedSize` to `ContentSize`
ickshonpe Apr 18, 2023
71bd8aa
Changed comments and variables names to refer to `ContentSize` not `C…
ickshonpe Apr 18, 2023
fb50589
Changed `ContentSize` to hold an `Option<Box<dyn Measurable>>` and ad…
ickshonpe Apr 19, 2023
96903e5
changes:
ickshonpe Apr 20, 2023
6385799
Revert "changes:"
ickshonpe Apr 20, 2023
3849a09
This reverts commit fb50589917fe8452b92f6583cfef3bfdf0e0b902.
ickshonpe Apr 20, 2023
0f10753
This reverts commit 3849a09ecc63628b8594c80425870cc800ba15e6.
ickshonpe Apr 20, 2023
a118920
This reverts commit 6385799d61b64c4ff17b58d2d78211d6ebc74630.
ickshonpe Apr 20, 2023
8b0365d
changes:
ickshonpe Apr 21, 2023
acd290d
Added doc comments for the functions in the `layout` module.
ickshonpe Apr 21, 2023
47d8510
changes
ickshonpe Apr 21, 2023
4a23652
fix imports
ickshonpe Apr 21, 2023
00b515f
cargo fmt
ickshonpe Apr 21, 2023
4142a78
changed `Node` field name back to `calculated_size`
ickshonpe Apr 21, 2023
859528b
Merge branch 'main' into dont-update-measure-funcs-on-layout-updates
ickshonpe Apr 29, 2023
c6c62d2
cargo fmt
ickshonpe Apr 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/bevy_ui/src/accessibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ fn calc_bounds(
let bounds = Rect::new(
translation.x.into(),
translation.y.into(),
(translation.x + node.calculated_size.x).into(),
(translation.y + node.calculated_size.y).into(),
(translation.x + node.content_size.x).into(),
(translation.y + node.content_size.y).into(),
);
accessible.set_bounds(bounds);
}
Expand Down
84 changes: 29 additions & 55 deletions crates/bevy_ui/src/layout/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
mod convert;

use crate::{CalculatedSize, Node, Style, UiScale};
use crate::{ContentSize, Node, Style, UiScale};
use bevy_ecs::{
change_detection::DetectChanges,
entity::Entity,
event::EventReader,
query::{Changed, ReadOnlyWorldQuery, With, Without},
query::{Changed, With, Without},
removal_detection::RemovedComponents,
system::{Query, Res, ResMut, Resource},
world::Ref,
};
use bevy_hierarchy::{Children, Parent};
use bevy_log::warn;
Expand Down Expand Up @@ -90,16 +91,8 @@ impl UiSurface {
}
}

pub fn upsert_leaf(
&mut self,
entity: Entity,
style: &Style,
calculated_size: &CalculatedSize,
context: &LayoutContext,
) {
let taffy = &mut self.taffy;
let taffy_style = convert::from_style(context, style);
let measure = calculated_size.measure.dyn_clone();
pub fn update_measure(&mut self, entity: Entity, content_size: &ContentSize) {
let measure = content_size.measure.dyn_clone();
let measure_func = taffy::node::MeasureFunc::Boxed(Box::new(
move |constraints: Size<Option<f32>>, available: Size<AvailableSpace>| {
let size = measure.measure(
Expand All @@ -114,17 +107,9 @@ impl UiSurface {
}
},
));
if let Some(taffy_node) = self.entity_to_taffy.get(&entity) {
self.taffy.set_style(*taffy_node, taffy_style).unwrap();
self.taffy
.set_measure(*taffy_node, Some(measure_func))
.unwrap();
} else {
let taffy_node = taffy
.new_leaf_with_measure(taffy_style, measure_func)
.unwrap();
self.entity_to_taffy.insert(entity, taffy_node);
}

let taffy_node = self.entity_to_taffy.get(&entity).unwrap();
self.taffy.set_measure(*taffy_node, Some(measure_func)).ok();
}

pub fn update_children(&mut self, entity: Entity, children: &Children) {
Expand Down Expand Up @@ -244,15 +229,11 @@ pub fn ui_layout_system(
mut resize_events: EventReader<bevy_window::WindowResized>,
mut ui_surface: ResMut<UiSurface>,
root_node_query: Query<Entity, (With<Node>, Without<Parent>)>,
node_query: Query<(Entity, &Style, Option<&CalculatedSize>), (With<Node>, Changed<Style>)>,
full_node_query: Query<(Entity, &Style, Option<&CalculatedSize>), With<Node>>,
changed_size_query: Query<
(Entity, &Style, &CalculatedSize),
(With<Node>, Changed<CalculatedSize>),
>,
style_query: Query<(Entity, Ref<Style>), With<Node>>,
measure_query: Query<(Entity, Ref<ContentSize>)>,
children_query: Query<(Entity, &Children), (With<Node>, Changed<Children>)>,
mut removed_children: RemovedComponents<Children>,
mut removed_calculated_sizes: RemovedComponents<CalculatedSize>,
mut removed_content_sizes: RemovedComponents<ContentSize>,
mut node_transform_query: Query<(Entity, &mut Node, &mut Transform, Option<&Parent>)>,
mut removed_nodes: RemovedComponents<Node>,
) {
Expand Down Expand Up @@ -283,40 +264,33 @@ pub fn ui_layout_system(

let scale_factor = logical_to_physical_factor * ui_scale.scale;

let viewport_values = LayoutContext::new(scale_factor, physical_size);

fn update_changed<F: ReadOnlyWorldQuery>(
ui_surface: &mut UiSurface,
viewport_values: &LayoutContext,
query: Query<(Entity, &Style, Option<&CalculatedSize>), F>,
) {
// update changed nodes
for (entity, style, calculated_size) in &query {
// TODO: remove node from old hierarchy if its root has changed
if let Some(calculated_size) = calculated_size {
ui_surface.upsert_leaf(entity, style, calculated_size, viewport_values);
} else {
ui_surface.upsert_node(entity, style, viewport_values);
}
}
}
let layout_context = LayoutContext::new(scale_factor, physical_size);

if !scale_factor_events.is_empty() || ui_scale.is_changed() || resized {
scale_factor_events.clear();
update_changed(&mut ui_surface, &viewport_values, full_node_query);
// update all nodes
for (entity, style) in style_query.iter() {
ui_surface.upsert_node(entity, &style, &layout_context);
}
} else {
update_changed(&mut ui_surface, &viewport_values, node_query);
for (entity, style) in style_query.iter() {
if style.is_changed() {
ui_surface.upsert_node(entity, &style, &layout_context);
}
}
}

for (entity, style, calculated_size) in &changed_size_query {
ui_surface.upsert_leaf(entity, style, calculated_size, &viewport_values);
for (entity, content_size) in measure_query.iter() {
if content_size.is_changed() {
ui_surface.update_measure(entity, &content_size);
}
}

// clean up removed nodes
ui_surface.remove_entities(removed_nodes.iter());

// When a `CalculatedSize` component is removed from an entity, we need to remove the measure from the corresponding taffy node.
for entity in removed_calculated_sizes.iter() {
// When a `ContentSize` component is removed from an entity, we need to remove the measure from the corresponding taffy node.
for entity in removed_content_sizes.iter() {
ui_surface.try_remove_measure(entity);
}

Expand Down Expand Up @@ -346,8 +320,8 @@ pub fn ui_layout_system(
to_logical(layout.size.height),
);
// only trigger change detection when the new value is different
if node.calculated_size != new_size {
node.calculated_size = new_size;
if node.content_size != new_size {
node.content_size = new_size;
}
let mut new_position = transform.translation;
new_position.x = to_logical(layout.location.x + layout.size.width / 2.0);
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl Plugin for UiPlugin {
.register_type::<AlignContent>()
.register_type::<AlignItems>()
.register_type::<AlignSelf>()
.register_type::<CalculatedSize>()
.register_type::<ContentSize>()
.register_type::<Direction>()
.register_type::<Display>()
.register_type::<FlexDirection>()
Expand Down
12 changes: 6 additions & 6 deletions crates/bevy_ui/src/measurement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use bevy_reflect::Reflect;
use std::fmt::Formatter;
pub use taffy::style::AvailableSpace;

impl std::fmt::Debug for CalculatedSize {
impl std::fmt::Debug for ContentSize {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CalculatedSize").finish()
f.debug_struct("ContentSize").finish()
}
}

Expand Down Expand Up @@ -49,17 +49,17 @@ impl Measure for FixedMeasure {
}
}

/// A node with a `CalculatedSize` component is a node where its size
/// A node with a `ContentSize` component is a node where its size
/// is based on its content.
#[derive(Component, Reflect)]
pub struct CalculatedSize {
pub struct ContentSize {
/// The `Measure` used to compute the intrinsic size
#[reflect(ignore)]
pub measure: Box<dyn Measure>,
}

#[allow(clippy::derivable_impls)]
impl Default for CalculatedSize {
impl Default for ContentSize {
fn default() -> Self {
Self {
// Default `FixedMeasure` always returns zero size.
Expand All @@ -68,7 +68,7 @@ impl Default for CalculatedSize {
}
}

impl Clone for CalculatedSize {
impl Clone for ContentSize {
fn clone(&self) -> Self {
Self {
measure: self.measure.dyn_clone(),
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_ui/src/node_bundles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
widget::{Button, UiImageSize},
BackgroundColor, CalculatedSize, FocusPolicy, Interaction, Node, Style, UiImage, ZIndex,
BackgroundColor, ContentSize, FocusPolicy, Interaction, Node, Style, UiImage, ZIndex,
};
use bevy_ecs::bundle::Bundle;
use bevy_render::{
Expand Down Expand Up @@ -74,7 +74,7 @@ pub struct ImageBundle {
/// In some cases these styles also affect how the node drawn/painted.
pub style: Style,
/// The calculated size based on the given image
pub calculated_size: CalculatedSize,
pub calculated_size: ContentSize,
/// The background color, which serves as a "fill" for this node
///
/// Combines with `UiImage` to tint the provided image.
Expand Down Expand Up @@ -119,7 +119,7 @@ pub struct TextBundle {
/// Text layout information
pub text_layout_info: TextLayoutInfo,
/// The calculated size based on the given image
pub calculated_size: CalculatedSize,
pub calculated_size: ContentSize,
/// Whether this node should block interaction with lower nodes
pub focus_policy: FocusPolicy,
/// The transform of the node
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ pub fn extract_uinodes(
color: color.0,
rect: Rect {
min: Vec2::ZERO,
max: uinode.calculated_size,
max: uinode.content_size,
},
image,
atlas_size: None,
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_ui/src/ui_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ use thiserror::Error;
pub struct Node {
/// The size of the node as width and height in logical pixels
/// automatically calculated by [`super::layout::ui_layout_system`]
pub(crate) calculated_size: Vec2,
pub(crate) content_size: Vec2,
}

impl Node {
/// The calculated node size as width and height in logical pixels
/// automatically calculated by [`super::layout::ui_layout_system`]
pub fn size(&self) -> Vec2 {
self.calculated_size
self.content_size
}

/// Returns the logical pixel coordinates of the UI node, based on its `GlobalTransform`.
Expand All @@ -48,7 +48,7 @@ impl Node {

impl Node {
pub const DEFAULT: Self = Self {
calculated_size: Vec2::ZERO,
content_size: Vec2::ZERO,
};
}

Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_ui/src/widget/image.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{measurement::AvailableSpace, CalculatedSize, Measure, Node, UiImage};
use crate::{measurement::AvailableSpace, ContentSize, Measure, Node, UiImage};
use bevy_asset::Assets;
#[cfg(feature = "bevy_text")]
use bevy_ecs::query::Without;
Expand Down Expand Up @@ -68,11 +68,11 @@ impl Measure for ImageMeasure {
pub fn update_image_calculated_size_system(
textures: Res<Assets<Image>>,
#[cfg(feature = "bevy_text")] mut query: Query<
(&mut CalculatedSize, &UiImage, &mut UiImageSize),
(&mut ContentSize, &UiImage, &mut UiImageSize),
(With<Node>, Without<Text>),
>,
#[cfg(not(feature = "bevy_text"))] mut query: Query<
(&mut CalculatedSize, &UiImage, &mut UiImageSize),
(&mut ContentSize, &UiImage, &mut UiImageSize),
With<Node>,
>,
) {
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ui/src/widget/text.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{CalculatedSize, Measure, Node, UiScale};
use crate::{ContentSize, Measure, Node, UiScale};
use bevy_asset::Assets;
use bevy_ecs::{
entity::Entity,
Expand Down Expand Up @@ -70,7 +70,7 @@ pub fn measure_text_system(
mut text_queries: ParamSet<(
Query<Entity, Changed<Text>>,
Query<Entity, (With<Text>, With<Node>)>,
Query<(&Text, &mut CalculatedSize)>,
Query<(&Text, &mut ContentSize)>,
)>,
) {
let window_scale_factor = windows
Expand Down