Skip to content

Commit 5a193ee

Browse files
DJMcNabexjam
authored andcommitted
Update layout/style when scale factor changes too (bevyengine#4689)
# Objective - Fix bevyengine#4688 ## Solution - Fixes bevyengine#4688 - This raises an interesting question about our change detection system - is filtered queries actually a good UX for this? They're ergonomic in the easy case, but what do we recommend when it's not so. - In this case, the system should have been migrated similary to bevyengine#4180 anyway, so I've done that.
1 parent 0d7a6e6 commit 5a193ee

File tree

2 files changed

+25
-32
lines changed

2 files changed

+25
-32
lines changed

crates/bevy_text/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ impl Plugin for TextPlugin {
4747
.register_type::<HorizontalAlign>()
4848
.init_asset_loader::<FontLoader>()
4949
.insert_resource(DefaultTextPipeline::default())
50-
.add_system_to_stage(CoreStage::PostUpdate, text2d_system.after(ModifiesWindows));
50+
.add_system_to_stage(
51+
CoreStage::PostUpdate,
52+
update_text2d_layout.after(ModifiesWindows),
53+
);
5154

5255
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
5356
render_app.add_system_to_stage(

crates/bevy_text/src/text2d.rs

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@ use bevy_ecs::{
33
bundle::Bundle,
44
component::Component,
55
entity::Entity,
6-
query::{Changed, With},
6+
event::EventReader,
7+
query::Changed,
78
reflect::ReflectComponent,
8-
system::{Local, ParamSet, Query, Res, ResMut},
9+
system::{Local, Query, Res, ResMut},
910
};
1011
use bevy_math::{Vec2, Vec3};
1112
use bevy_reflect::Reflect;
1213
use bevy_render::{texture::Image, view::Visibility, RenderWorld};
1314
use bevy_sprite::{Anchor, ExtractedSprite, ExtractedSprites, TextureAtlas};
1415
use bevy_transform::prelude::{GlobalTransform, Transform};
15-
use bevy_window::{WindowId, Windows};
16+
use bevy_utils::HashSet;
17+
use bevy_window::{WindowId, WindowScaleFactorChanged, Windows};
1618

1719
use crate::{
1820
DefaultTextPipeline, Font, FontAtlasSet, HorizontalAlign, Text, TextError, VerticalAlign,
@@ -123,44 +125,34 @@ pub fn extract_text2d_sprite(
123125
}
124126
}
125127

126-
#[derive(Debug, Default)]
127-
pub struct QueuedText2d {
128-
entities: Vec<Entity>,
129-
}
130-
131128
/// Updates the layout and size information whenever the text or style is changed.
132129
/// This information is computed by the `TextPipeline` on insertion, then stored.
133130
#[allow(clippy::too_many_arguments, clippy::type_complexity)]
134-
pub fn text2d_system(
135-
mut queued_text: Local<QueuedText2d>,
131+
pub fn update_text2d_layout(
132+
// Text items which should be reprocessed again, generally when the font hasn't loaded yet.
133+
mut queue: Local<HashSet<Entity>>,
136134
mut textures: ResMut<Assets<Image>>,
137135
fonts: Res<Assets<Font>>,
138136
windows: Res<Windows>,
137+
mut scale_factor_changed: EventReader<WindowScaleFactorChanged>,
139138
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
140139
mut font_atlas_set_storage: ResMut<Assets<FontAtlasSet>>,
141140
mut text_pipeline: ResMut<DefaultTextPipeline>,
142-
mut text_queries: ParamSet<(
143-
Query<Entity, (With<Text2dSize>, Changed<Text>)>,
144-
Query<(&Text, Option<&Text2dBounds>, &mut Text2dSize), With<Text2dSize>>,
141+
mut text_query: Query<(
142+
Entity,
143+
Changed<Text>,
144+
&Text,
145+
Option<&Text2dBounds>,
146+
&mut Text2dSize,
145147
)>,
146148
) {
147-
// Adds all entities where the text or the style has changed to the local queue
148-
for entity in text_queries.p0().iter_mut() {
149-
queued_text.entities.push(entity);
150-
}
151-
152-
if queued_text.entities.is_empty() {
153-
return;
154-
}
155-
149+
// We need to consume the entire iterator, hence `last`
150+
let factor_changed = scale_factor_changed.iter().last().is_some();
156151
let scale_factor = windows.scale_factor(WindowId::primary());
157152

158-
// Computes all text in the local queue
159-
let mut new_queue = Vec::new();
160-
let mut query = text_queries.p1();
161-
for entity in queued_text.entities.drain(..) {
162-
if let Ok((text, bounds, mut calculated_size)) = query.get_mut(entity) {
163-
let text_bounds = match bounds {
153+
for (entity, text_changed, text, maybe_bounds, mut calculated_size) in text_query.iter_mut() {
154+
if factor_changed || text_changed || queue.remove(&entity) {
155+
let text_bounds = match maybe_bounds {
164156
Some(bounds) => Vec2::new(
165157
scale_value(bounds.size.x, scale_factor),
166158
scale_value(bounds.size.y, scale_factor),
@@ -181,7 +173,7 @@ pub fn text2d_system(
181173
Err(TextError::NoSuchFont) => {
182174
// There was an error processing the text layout, let's add this entity to the
183175
// queue for further processing
184-
new_queue.push(entity);
176+
queue.insert(entity);
185177
}
186178
Err(e @ TextError::FailedToAddGlyph(_)) => {
187179
panic!("Fatal error when processing text: {}.", e);
@@ -198,8 +190,6 @@ pub fn text2d_system(
198190
}
199191
}
200192
}
201-
202-
queued_text.entities = new_queue;
203193
}
204194

205195
pub fn scale_value(value: f32, factor: f64) -> f32 {

0 commit comments

Comments
 (0)