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

Conversation

ickshonpe
Copy link
Contributor

@ickshonpe ickshonpe commented Apr 16, 2023

Objective

fixes #8516

  • Give CalculatedSize a more specific and intuitive name.

  • MeasureFuncs should only be updated when their CalculatedSize is modified by the systems managing their content.

    For example, suppose that you have a UI displaying an image using an ImageNode. When the window is resized, the node's MeasureFunc will be updated even though the dimensions of the texture contained by the node are unchanged.

  • Fix the CalculatedSize API so that it no longer requires the extra boxing and the dyn_clone method.

Solution

  • Rename CalculatedSize to ContentSize

  • Only update MeasureFuncs on CalculatedSize changes.

  • Remove the dyn_clone method from Measure and move the Measure from the ContentSize component rather than cloning it.

  • Change the measure_func field of ContentSize to type Option<taffy::node::MeasureFunc>. Add a set method that wraps the given measure appropriately.


Changelog

  • Renamed CalculatedSize to ContentSize.
  • Replaced upsert_leaf with a function update_measure that only updates the node's MeasureFunc.
  • MeasureFuncs are only updated when the ContentSize changes and not when the layout changes.
  • Scale factor is no longer applied to the size values passed to the MeasureFunc.
  • Remove the ContentSize scaling in text_system.
  • The dyn_clone method has been removed from the Measure trait.
  • Measures are moved from the ContentSize component instead of cloning them.
  • Added set method to ContentSize that replaces the new function.

Migration Guide

  • CalculatedSize has been renamed to ContentSize.
  • The upsert_leaf function has been removed from UiSurface and replaced with update_measure which updates the MeasureFunc without node insertion.
  • The dyn_clone method has been removed from the Measure trait.
  • The new function of CalculatedSize has been replaced with the method set.

* Removed function `update_changed` from `flex_node_system`
* Added a `Without<Calculated>` query filter so the two changed node queries in `flex_node_system` are mutually exclusive.
* Moved the leaf node update loop into the else block of the update-all if statement.
* Replaced `upsert_leaf` with a function `update_measure` that only updates a nodes `MeasureFunc`.
* `MeasureFunc`s are only updated when the `CalculatedSize` changes and not when the layout changes.
* Scale factor is no longer applied to the size values passed to the measure func.
* Remove the `CalculatedSize` scaling in `text_system`.
@ickshonpe ickshonpe mentioned this pull request Apr 16, 2023
@james7132 james7132 added A-UI Graphical user interfaces, styles, layouts, and widgets C-Breaking-Change A breaking change to Bevy's public API that needs to be noted in a migration guide labels Apr 16, 2023
@github-actions
Copy link
Contributor

It looks like your PR is a breaking change, but you didn't provide a migration guide.

Could you add some context on what users should update when this change get released in a new version of Bevy?
It will be used to help writing the migration guide for the version. Putting it after a ## Migration Guide will help it get automatically picked up by our tooling.

@james7132 james7132 added the C-Performance A change motivated by improving speed, memory usage or compile times label Apr 16, 2023
@nicoburns
Copy link
Contributor

@ickshonpe If Taffy is being passed scaled physical styles, then don't the measure_func's also need to be working in physical-sizes? Or are these values already scaled?

@ickshonpe
Copy link
Contributor Author

@ickshonpe If Taffy is being passed scaled physical styles, then don't the measure_func's also need to be working in physical-sizes? Or are these values already scaled?

They are already scaled.

Copy link
Contributor

@nicoburns nicoburns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks good to me. The only thing that confused me was the name of CalculatedSize, because (at least in the case of text) it does not actually contain a calculated size, but a MeasureFunc. I wonder if it ought to be renamed to MeasureFunction or IntrinsicSize or ContentSize or something like that?

@ickshonpe
Copy link
Contributor Author

Yeah, the name CalculatedSize doesn't make sense anymore. I was going to change it to IntrinsicSize in the text-system-split PR but decided it had enough breaking changes already.

ContentSize might be good, I think users would it find more intuitive than InstrinsicSize or MeasureFunction probably.

@mockersf
Copy link
Member

mockersf commented Apr 18, 2023

there is a small style issue, a merge issue in crates/bevy_ui/src/widget/text.rs, and I would be for renaming. ContentSize sounds good 👍

@ickshonpe
Copy link
Contributor Author

very artificial benchmark:

cargo run --profile stress-test --features trace_tracy --example many_buttons recompute-layout

update_content_size

…ded a new function that wraps a `Measure` into a Taffy `Measurable`.

Changed `UiSurface::set_measure` to move the boxed `Measurable` from the ContentSize component to the Taffy measure slotmap without boxing or cloning.
* cargo fmt --all
* Removed change detection check from `set_measure`
This reverts commit 96903e5.
@ickshonpe
Copy link
Contributor Author

ickshonpe commented Apr 20, 2023

Since a MeasureFunc doesn't ever need to be reupdated by ui_layout_system, the MeasureFunc can just be moved from the ContentSize component instead of cloning and that annoying dyn_clone method can be got rid of as well.

@nicoburns
Copy link
Contributor

Since a MeasureFunc doesn't ever need to be reupdated by ui_layout_system, the MeasureFunc can just be moved from the ContentSize component instead of cloning and that annoying dyn_clone method can be got rid of as well.

How does that interact with change detection on the ContentSize component? Wouldn't moving out of the component change it?

@ickshonpe
Copy link
Contributor Author

ickshonpe commented Apr 20, 2023

Since a MeasureFunc doesn't ever need to be reupdated by ui_layout_system, the MeasureFunc can just be moved from the ContentSize component instead of cloning and that annoying dyn_clone method can be got rid of as well.

How does that interact with change detection on the ContentSize component? Wouldn't moving out of the component change it?

ContentSize isn't queried for changes anymore, ui_layout_system just takes the Measure out of an option.

bypass_change_detection can always be used if it was needed for some reason.

* Removed the `new` function from `ContentSize`.
* Changed the `measure_func` field of `ContentSize` to an `Option<taffy::node::MeasureFunc>`. This puts all the `MeasureFunc` wrapping code is in one place and allows us to use an unboxed function as a `MeasureFunc`.
* Added `set` and `set_fn` methods to `ContentSize` to replace the `new` function.
* Default zero-size measure uses an unboxed closure instead of a boxed `Measure`.
* Removed the `FixedMeasure` type, which is no longer needed as an unboxed function is simpler and more efficient.
@ickshonpe ickshonpe changed the title Only update MeasureFuncs on CalculatedSize changes MeasureFunc improvements Apr 21, 2023
@ickshonpe
Copy link
Contributor Author

Also fixes #8516, not sure why. Might be some problem in UiSurface not setting the needs measure or dirty flags correctly.

@nicoburns
Copy link
Contributor

@ickshonpe Would you now consider this PR ready for review? I've been waiting for you to stop committing to it to re-review.

@ickshonpe
Copy link
Contributor Author

ickshonpe commented Apr 30, 2023 via email

Copy link
Contributor

@nicoburns nicoburns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. Also seems to work with a quick test locally.

@nicoburns nicoburns added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label May 1, 2023
@nicoburns nicoburns added this to the 0.11 milestone May 1, 2023
@alice-i-cecile alice-i-cecile added this pull request to the merge queue May 1, 2023
Merged via the queue into bevyengine:main with commit ba532e4 May 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-UI Graphical user interfaces, styles, layouts, and widgets C-Breaking-Change A breaking change to Bevy's public API that needs to be noted in a migration guide C-Performance A change motivated by improving speed, memory usage or compile times S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Disappearing space in the layout with intrinsically sized UI nodes
5 participants