-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
ContentSize
replacement fix
#9753
ContentSize
replacement fix
#9753
Conversation
If you remove a `ContentSize` component from a Bevy UI entity and then immediately replace it `ui_layout_system` will remove the measure func from the internal Taffy layout tree but no new measure func will be generated to replace it since it's the widget systems that are responsible for creating their respective measure funcs not `ui_layout_system`. The widget systems only perform updates on changes to their content, and don't check `ContentSize` for changes. This means that until the content is changed in some way, no content will be displayed by the node. This commit fixes this by performing `ui_layout_system`'s `ContentSize` removal detection and resolution first, before measure func updates and in the widget systems generating a new `Measure` when a `ContentSize` component is added to a widget entity.
Just for the sake of documentation:
|
I'm not sure if there are any specific use cases. @viridia seemed to be experimenting with some quite complicated ideas that might require it. It's about the API obeying the basic principle that an entity is defined by its components. For example, suppose that you have an entity with the |
I haven't gotten around to messing with ContentSize yet. However... I am working with adding and removing components. For example, suppose you have a style asset that has a "background-color" attribute. The background color can either be a color (in which case the BackgroundColor component needs to exist) or it can be "transparent", which means "don't render a background color at all" (it does not mean render with alpha 0), which requires that the BackgroundColor component be removed from the entity. This style property can change due to several causes: a hot reload of the style asset; an override of a context variable farther up the tree; a dynamic style change due to a state change in a widget. That being said, it's hard to imagine a use case for dynamically changing ContentSize, other than hot reloading of a style asset. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while a very uncommon case, this should have pretty much no perf impact when not hitting that case
@ickshonpe once merge conflicts are fixed I'll merge this for you. |
# Objective If you remove a `ContentSize` component from a Bevy UI entity and then replace it `ui_layout_system` will remove the measure func from the internal Taffy layout tree but no new measure func will be generated to replace it since it's the widget systems that are responsible for creating their respective measure funcs not `ui_layout_system`. The widget systems only perform a measure func update on changes to a widget entity's content. This means that until its content is changed in some way, no content will be displayed by the node. ### Example This example spawns a text node which disappears after a few moments once its `ContentSize` component is replaced. ```rust use bevy::prelude::*; use bevy::ui::ContentSize; fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_systems(Update, delayed_replacement) .run(); } fn setup(mut commands: Commands) { commands.spawn(Camera2dBundle::default()); commands.spawn( TextBundle::from_section( "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", TextStyle::default(), ) ); } // Waits a few frames to make sure the font is loaded and the text's glyph layout has been generated. fn delayed_replacement(mut commands: Commands, mut count: Local<usize>, query: Query<Entity, With<Style>>) { *count += 1; if *count == 10 { for item in query.iter() { commands .entity(item) .remove::<ContentSize>() .insert(ContentSize::default()); } } } ``` ## Solution Perform `ui_layout_system`'s `ContentSize` removal detection and resolution first, before the measure func updates. Then in the widget systems, generate a new `Measure` when a `ContentSize` component is added to a widget entity. ## Changelog * `measure_text_system`, `update_image_content_size_system` and `update_atlas_content_size_system` generate a new `Measure` when a `ContentSize` component is added.
Objective
If you remove a
ContentSize
component from a Bevy UI entity and then replace itui_layout_system
will remove the measure func from the internal Taffy layout tree but no new measure func will be generated to replace it since it's the widget systems that are responsible for creating their respective measure funcs notui_layout_system
. The widget systems only perform a measure func update on changes to a widget entity's content. This means that until its content is changed in some way, no content will be displayed by the node.Example
This example spawns a text node which disappears after a few moments once its
ContentSize
component is replaced.Solution
Perform
ui_layout_system
'sContentSize
removal detection and resolution first, before the measure func updates.Then in the widget systems, generate a new
Measure
when aContentSize
component is added to a widget entity.Changelog
measure_text_system
,update_image_content_size_system
andupdate_atlas_content_size_system
generate a newMeasure
when aContentSize
component is added.