Skip to content

Commit 069a877

Browse files
authored
Feature-gate all references to bevy_text in bevy_ui (#11391)
# Objective - `bevy_ui` fails to compile without `bevy_text` being enabled. - Fixes #11363. ## Solution - Add `#[cfg(feature = "bevy_text")]` to all items that require it. I think this change is honestly a bit ugly, but I can't see any other way around it. I considered making `bevy_text` required, but we agreed [on Discord](https://discord.com/channels/691052431525675048/743663673393938453/1196868117486379148) that there were some use cases for `bevy_ui` without `bevy_text`. If you have any ideas that decreases the amount of `#[cfg(...)]`s and `#[allow(...)]`s, that would be greatly appreciated. This was tested by running the following commands: ```shell $ cargo clippy -p bevy_ui $ cargo clippy -p bevy_ui -F bevy_text $ cargo run -p ci ``` --- ## Changelog - Fixed `bevy_ui` not compiling without `bevy_text`.
1 parent 6e959db commit 069a877

File tree

3 files changed

+71
-63
lines changed

3 files changed

+71
-63
lines changed

crates/bevy_ui/src/lib.rs

Lines changed: 68 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ pub mod widget;
1212
use bevy_derive::{Deref, DerefMut};
1313
use bevy_reflect::Reflect;
1414
#[cfg(feature = "bevy_text")]
15-
use bevy_text::TextLayoutInfo;
16-
#[cfg(feature = "bevy_text")]
1715
mod accessibility;
1816
mod focus;
1917
mod geometry;
@@ -40,8 +38,6 @@ pub mod prelude {
4038
};
4139
}
4240

43-
#[cfg(feature = "bevy_text")]
44-
use crate::widget::TextFlags;
4541
use bevy_app::prelude::*;
4642
use bevy_ecs::prelude::*;
4743
use bevy_input::InputSystem;
@@ -81,6 +77,14 @@ impl Default for UiScale {
8177
}
8278
}
8379

80+
// Marks systems that can be ambiguous with [`widget::text_system`] if the `bevy_text` feature is enabled.
81+
// See https://github.com/bevyengine/bevy/pull/11391 for more details.
82+
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
83+
struct AmbiguousWithTextSystem;
84+
85+
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
86+
struct AmbiguousWithUpdateText2DLayout;
87+
8488
impl Plugin for UiPlugin {
8589
fn build(&self, app: &mut App) {
8690
app.init_resource::<UiSurface>()
@@ -129,51 +133,6 @@ impl Plugin for UiPlugin {
129133
ui_focus_system.in_set(UiSystem::Focus).after(InputSystem),
130134
);
131135

132-
#[cfg(feature = "bevy_text")]
133-
app.register_type::<TextLayoutInfo>()
134-
.register_type::<TextFlags>();
135-
// add these systems to front because these must run before transform update systems
136-
#[cfg(feature = "bevy_text")]
137-
app.add_systems(
138-
PostUpdate,
139-
(
140-
widget::measure_text_system
141-
.before(UiSystem::Layout)
142-
// Potential conflict: `Assets<Image>`
143-
// In practice, they run independently since `bevy_render::camera_update_system`
144-
// will only ever observe its own render target, and `widget::measure_text_system`
145-
// will never modify a pre-existing `Image` asset.
146-
.ambiguous_with(bevy_render::camera::CameraUpdateSystem)
147-
// Potential conflict: `Assets<Image>`
148-
// Since both systems will only ever insert new [`Image`] assets,
149-
// they will never observe each other's effects.
150-
.ambiguous_with(bevy_text::update_text2d_layout)
151-
// We assume Text is on disjoint UI entities to UiImage and UiTextureAtlasImage
152-
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
153-
.ambiguous_with(widget::update_image_content_size_system),
154-
widget::text_system
155-
.after(UiSystem::Layout)
156-
.after(bevy_text::remove_dropped_font_atlas_sets)
157-
// Text2d and bevy_ui text are entirely on separate entities
158-
.ambiguous_with(bevy_text::update_text2d_layout),
159-
),
160-
);
161-
#[cfg(feature = "bevy_text")]
162-
app.add_plugins(accessibility::AccessibilityPlugin);
163-
app.add_systems(PostUpdate, {
164-
let system = widget::update_image_content_size_system.before(UiSystem::Layout);
165-
// Potential conflicts: `Assets<Image>`
166-
// They run independently since `widget::image_node_system` will only ever observe
167-
// its own UiImage, and `widget::text_system` & `bevy_text::update_text2d_layout`
168-
// will never modify a pre-existing `Image` asset.
169-
#[cfg(feature = "bevy_text")]
170-
let system = system
171-
.ambiguous_with(bevy_text::update_text2d_layout)
172-
.ambiguous_with(widget::text_system);
173-
174-
system
175-
});
176-
177136
app.add_systems(
178137
PostUpdate,
179138
(
@@ -189,18 +148,29 @@ impl Plugin for UiPlugin {
189148
.after(UiSystem::Layout)
190149
// clipping doesn't care about outlines
191150
.ambiguous_with(update_clipping_system)
192-
.ambiguous_with(widget::text_system),
151+
.in_set(AmbiguousWithTextSystem),
193152
ui_stack_system
194153
.in_set(UiSystem::Stack)
195154
// the systems don't care about stack index
196155
.ambiguous_with(update_clipping_system)
197156
.ambiguous_with(resolve_outlines_system)
198157
.ambiguous_with(ui_layout_system)
199-
.ambiguous_with(widget::text_system),
158+
.in_set(AmbiguousWithTextSystem),
200159
update_clipping_system.after(TransformSystem::TransformPropagate),
160+
// Potential conflicts: `Assets<Image>`
161+
// They run independently since `widget::image_node_system` will only ever observe
162+
// its own UiImage, and `widget::text_system` & `bevy_text::update_text2d_layout`
163+
// will never modify a pre-existing `Image` asset.
164+
widget::update_image_content_size_system
165+
.before(UiSystem::Layout)
166+
.in_set(AmbiguousWithTextSystem)
167+
.in_set(AmbiguousWithUpdateText2DLayout),
201168
),
202169
);
203170

171+
#[cfg(feature = "bevy_text")]
172+
build_text_interop(app);
173+
204174
build_ui_render(app);
205175
}
206176

@@ -212,3 +182,50 @@ impl Plugin for UiPlugin {
212182
render_app.init_resource::<UiPipeline>();
213183
}
214184
}
185+
186+
/// A function that should be called from [`UiPlugin::build`] when [`bevy_text`] is enabled.
187+
#[cfg(feature = "bevy_text")]
188+
fn build_text_interop(app: &mut App) {
189+
use crate::widget::TextFlags;
190+
use bevy_text::TextLayoutInfo;
191+
192+
app.register_type::<TextLayoutInfo>()
193+
.register_type::<TextFlags>();
194+
195+
app.add_systems(
196+
PostUpdate,
197+
(
198+
widget::measure_text_system
199+
.before(UiSystem::Layout)
200+
// Potential conflict: `Assets<Image>`
201+
// In practice, they run independently since `bevy_render::camera_update_system`
202+
// will only ever observe its own render target, and `widget::measure_text_system`
203+
// will never modify a pre-existing `Image` asset.
204+
.ambiguous_with(bevy_render::camera::CameraUpdateSystem)
205+
// Potential conflict: `Assets<Image>`
206+
// Since both systems will only ever insert new [`Image`] assets,
207+
// they will never observe each other's effects.
208+
.ambiguous_with(bevy_text::update_text2d_layout)
209+
// We assume Text is on disjoint UI entities to UiImage and UiTextureAtlasImage
210+
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
211+
.ambiguous_with(widget::update_image_content_size_system),
212+
widget::text_system
213+
.after(UiSystem::Layout)
214+
.after(bevy_text::remove_dropped_font_atlas_sets)
215+
// Text2d and bevy_ui text are entirely on separate entities
216+
.ambiguous_with(bevy_text::update_text2d_layout),
217+
),
218+
);
219+
220+
app.add_plugins(accessibility::AccessibilityPlugin);
221+
222+
app.configure_sets(
223+
PostUpdate,
224+
AmbiguousWithTextSystem.ambiguous_with(widget::text_system),
225+
);
226+
227+
app.configure_sets(
228+
PostUpdate,
229+
AmbiguousWithUpdateText2DLayout.ambiguous_with(bevy_text::update_text2d_layout),
230+
);
231+
}

crates/bevy_ui/src/render/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ pub use render_pass::*;
1414
pub use ui_material_pipeline::*;
1515

1616
use crate::{
17-
BackgroundColor, BorderColor, CalculatedClip, ContentSize, Node, Style, UiImage, UiScale, Val,
17+
BackgroundColor, BorderColor, CalculatedClip, ContentSize, DefaultUiCamera, Node, Outline,
18+
Style, TargetCamera, UiImage, UiScale, Val,
1819
};
19-
use crate::{DefaultUiCamera, Outline, TargetCamera};
2020

2121
use bevy_app::prelude::*;
2222
use bevy_asset::{load_internal_asset, AssetEvent, AssetId, Assets, Handle};
@@ -34,7 +34,6 @@ use bevy_render::{
3434
view::{ExtractedView, ViewUniforms},
3535
Extract, RenderApp, RenderSet,
3636
};
37-
#[cfg(feature = "bevy_text")]
3837
use bevy_sprite::TextureAtlasLayout;
3938
#[cfg(feature = "bevy_text")]
4039
use bevy_text::{PositionedGlyph, Text, TextLayoutInfo};

crates/bevy_ui/src/widget/image.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
use crate::{measurement::AvailableSpace, ContentSize, Measure, Node, UiImage, UiScale};
22
use bevy_asset::Assets;
3-
4-
use bevy_ecs::change_detection::DetectChanges;
5-
use bevy_ecs::query::Without;
6-
use bevy_ecs::{
7-
prelude::Component,
8-
query::With,
9-
reflect::ReflectComponent,
10-
system::{Local, Query, Res},
11-
};
3+
use bevy_ecs::prelude::*;
124
use bevy_math::Vec2;
135
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
146
use bevy_render::texture::Image;

0 commit comments

Comments
 (0)