Skip to content

Commit 49f74af

Browse files
mockersfProfLander
authored andcommitted
make bevy_text optional again (bevyengine#7801)
# Objective - `bevy_text` used to be "optional". the feature could be disabled, which meant that the systems were not added but `bevy_text` was still compiled because of a hard dependency in `bevy_ui` - Running something without `bevy_text` enabled and with `bevy_ui` enabled now crashes: ``` thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /bevy/crates/bevy_ecs/src/schedule/schedule.rs:1147:34 ``` - This is because `bevy_ui` declares some of its systems in ambiguity sets with systems from `bevy_text`, which were not added if `bevy_text` is disabled ## Solution - Make `bevy_text` completely optional ## Migration Guide - feature `bevy_text` now completely removes `bevy_text` from the dependencies when not enabled. Enable feature `bevy_text` if you use Bevy to render text
1 parent 52bebdf commit 49f74af

File tree

7 files changed

+68
-46
lines changed

7 files changed

+68
-46
lines changed

crates/bevy_internal/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ dynamic_linking = ["bevy_diagnostic/dynamic_linking"]
8282
# Enable using a shared stdlib for cxx on Android.
8383
android_shared_stdcxx = ["bevy_audio/android_shared_stdcxx"]
8484

85+
bevy_text = ["dep:bevy_text", "bevy_ui?/bevy_text"]
86+
8587
[dependencies]
8688
# bevy
8789
bevy_app = { path = "../bevy_app", version = "0.9.0" }

crates/bevy_ui/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.9.0", features = [
2424
] }
2525
bevy_render = { path = "../bevy_render", version = "0.9.0" }
2626
bevy_sprite = { path = "../bevy_sprite", version = "0.9.0" }
27-
bevy_text = { path = "../bevy_text", version = "0.9.0" }
27+
bevy_text = { path = "../bevy_text", version = "0.9.0", optional = true }
2828
bevy_transform = { path = "../bevy_transform", version = "0.9.0" }
2929
bevy_window = { path = "../bevy_window", version = "0.9.0" }
3030
bevy_utils = { path = "../bevy_utils", version = "0.9.0" }

crates/bevy_ui/src/lib.rs

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ pub mod node_bundles;
1414
pub mod update;
1515
pub mod widget;
1616

17-
use bevy_render::{camera::CameraUpdateSystem, extract_component::ExtractComponentPlugin};
17+
#[cfg(feature = "bevy_text")]
18+
use bevy_render::camera::CameraUpdateSystem;
19+
use bevy_render::extract_component::ExtractComponentPlugin;
1820
pub use flex::*;
1921
pub use focus::*;
2022
pub use geometry::*;
@@ -103,44 +105,49 @@ impl Plugin for UiPlugin {
103105
.configure_set(UiSystem::Focus.in_base_set(CoreSet::PreUpdate))
104106
.configure_set(UiSystem::Flex.in_base_set(CoreSet::PostUpdate))
105107
.configure_set(UiSystem::Stack.in_base_set(CoreSet::PostUpdate))
106-
.add_system(ui_focus_system.in_set(UiSystem::Focus).after(InputSystem))
107-
// add these systems to front because these must run before transform update systems
108-
.add_system(
109-
widget::text_system
110-
.in_base_set(CoreSet::PostUpdate)
111-
.before(UiSystem::Flex)
112-
// Potential conflict: `Assets<Image>`
113-
// In practice, they run independently since `bevy_render::camera_update_system`
114-
// will only ever observe its own render target, and `widget::text_system`
115-
// will never modify a pre-existing `Image` asset.
116-
.ambiguous_with(CameraUpdateSystem)
117-
// Potential conflict: `Assets<Image>`
118-
// Since both systems will only ever insert new [`Image`] assets,
119-
// they will never observe each other's effects.
120-
.ambiguous_with(bevy_text::update_text2d_layout),
121-
)
122-
.add_system(
123-
widget::update_image_calculated_size_system
124-
.in_base_set(CoreSet::PostUpdate)
125-
.before(UiSystem::Flex)
126-
// Potential conflicts: `Assets<Image>`
127-
// They run independently since `widget::image_node_system` will only ever observe
128-
// its own UiImage, and `widget::text_system` & `bevy_text::update_text2d_layout`
129-
// will never modify a pre-existing `Image` asset.
130-
.ambiguous_with(bevy_text::update_text2d_layout)
131-
.ambiguous_with(widget::text_system),
132-
)
133-
.add_system(
134-
flex_node_system
135-
.in_set(UiSystem::Flex)
136-
.before(TransformSystem::TransformPropagate),
137-
)
138-
.add_system(ui_stack_system.in_set(UiSystem::Stack))
139-
.add_system(
140-
update_clipping_system
141-
.after(TransformSystem::TransformPropagate)
142-
.in_base_set(CoreSet::PostUpdate),
143-
);
108+
.add_system(ui_focus_system.in_set(UiSystem::Focus).after(InputSystem));
109+
// add these systems to front because these must run before transform update systems
110+
#[cfg(feature = "bevy_text")]
111+
app.add_system(
112+
widget::text_system
113+
.in_base_set(CoreSet::PostUpdate)
114+
.before(UiSystem::Flex)
115+
// Potential conflict: `Assets<Image>`
116+
// In practice, they run independently since `bevy_render::camera_update_system`
117+
// will only ever observe its own render target, and `widget::text_system`
118+
// will never modify a pre-existing `Image` asset.
119+
.ambiguous_with(CameraUpdateSystem)
120+
// Potential conflict: `Assets<Image>`
121+
// Since both systems will only ever insert new [`Image`] assets,
122+
// they will never observe each other's effects.
123+
.ambiguous_with(bevy_text::update_text2d_layout),
124+
);
125+
app.add_system({
126+
let system = widget::update_image_calculated_size_system
127+
.in_base_set(CoreSet::PostUpdate)
128+
.before(UiSystem::Flex);
129+
// Potential conflicts: `Assets<Image>`
130+
// They run independently since `widget::image_node_system` will only ever observe
131+
// its own UiImage, and `widget::text_system` & `bevy_text::update_text2d_layout`
132+
// will never modify a pre-existing `Image` asset.
133+
#[cfg(feature = "bevy_text")]
134+
let system = system
135+
.ambiguous_with(bevy_text::update_text2d_layout)
136+
.ambiguous_with(widget::text_system);
137+
138+
system
139+
})
140+
.add_system(
141+
flex_node_system
142+
.in_set(UiSystem::Flex)
143+
.before(TransformSystem::TransformPropagate),
144+
)
145+
.add_system(ui_stack_system.in_set(UiSystem::Stack))
146+
.add_system(
147+
update_clipping_system
148+
.after(TransformSystem::TransformPropagate)
149+
.in_base_set(CoreSet::PostUpdate),
150+
);
144151

145152
crate::render::build_ui_render(app);
146153
}

crates/bevy_ui/src/node_bundles.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use bevy_render::{
99
prelude::{Color, ComputedVisibility},
1010
view::Visibility,
1111
};
12+
#[cfg(feature = "bevy_text")]
1213
use bevy_text::{Text, TextAlignment, TextSection, TextStyle};
1314
use bevy_transform::prelude::{GlobalTransform, Transform};
1415

@@ -95,6 +96,7 @@ pub struct ImageBundle {
9596
pub z_index: ZIndex,
9697
}
9798

99+
#[cfg(feature = "bevy_text")]
98100
/// A UI node that is text
99101
#[derive(Bundle, Clone, Debug)]
100102
pub struct TextBundle {
@@ -128,6 +130,7 @@ pub struct TextBundle {
128130
pub background_color: BackgroundColor,
129131
}
130132

133+
#[cfg(feature = "bevy_text")]
131134
impl Default for TextBundle {
132135
fn default() -> Self {
133136
Self {
@@ -147,6 +150,7 @@ impl Default for TextBundle {
147150
}
148151
}
149152

153+
#[cfg(feature = "bevy_text")]
150154
impl TextBundle {
151155
/// Create a [`TextBundle`] from a single section.
152156
///

crates/bevy_ui/src/render/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ mod render_pass;
33

44
use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d};
55
use bevy_render::ExtractSchedule;
6+
#[cfg(feature = "bevy_text")]
67
use bevy_window::{PrimaryWindow, Window};
78
pub use pipeline::*;
89
pub use render_pass::*;
@@ -26,7 +27,10 @@ use bevy_render::{
2627
view::{ComputedVisibility, ExtractedView, ViewUniforms},
2728
Extract, RenderApp, RenderSet,
2829
};
29-
use bevy_sprite::{SpriteAssetEvents, TextureAtlas};
30+
use bevy_sprite::SpriteAssetEvents;
31+
#[cfg(feature = "bevy_text")]
32+
use bevy_sprite::TextureAtlas;
33+
#[cfg(feature = "bevy_text")]
3034
use bevy_text::{Text, TextLayoutInfo};
3135
use bevy_transform::components::GlobalTransform;
3236
use bevy_utils::FloatOrd;
@@ -78,6 +82,7 @@ pub fn build_ui_render(app: &mut App) {
7882
extract_default_ui_camera_view::<Camera2d>,
7983
extract_default_ui_camera_view::<Camera3d>,
8084
extract_uinodes.in_set(RenderUiSystem::ExtractNode),
85+
#[cfg(feature = "bevy_text")]
8186
extract_text_uinodes.after(RenderUiSystem::ExtractNode),
8287
),
8388
)
@@ -288,6 +293,7 @@ pub fn extract_default_ui_camera_view<T: Component>(
288293
}
289294
}
290295

296+
#[cfg(feature = "bevy_text")]
291297
pub fn extract_text_uinodes(
292298
mut extracted_uinodes: ResMut<ExtractedUiNodes>,
293299
texture_atlases: Extract<Res<Assets<TextureAtlas>>>,

crates/bevy_ui/src/widget/image.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
use crate::{CalculatedSize, UiImage};
22
use bevy_asset::Assets;
3-
use bevy_ecs::{
4-
query::Without,
5-
system::{Query, Res},
6-
};
3+
#[cfg(feature = "bevy_text")]
4+
use bevy_ecs::query::Without;
5+
use bevy_ecs::system::{Query, Res};
76
use bevy_math::Vec2;
87
use bevy_render::texture::Image;
8+
#[cfg(feature = "bevy_text")]
99
use bevy_text::Text;
1010

1111
/// Updates calculated size of the node based on the image provided
1212
pub fn update_image_calculated_size_system(
1313
textures: Res<Assets<Image>>,
14-
mut query: Query<(&mut CalculatedSize, &UiImage), Without<Text>>,
14+
#[cfg(feature = "bevy_text")] mut query: Query<(&mut CalculatedSize, &UiImage), Without<Text>>,
15+
#[cfg(not(feature = "bevy_text"))] mut query: Query<(&mut CalculatedSize, &UiImage)>,
1516
) {
1617
for (mut calculated_size, image) in &mut query {
1718
if let Some(texture) = textures.get(&image.texture) {

crates/bevy_ui/src/widget/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
33
mod button;
44
mod image;
5+
#[cfg(feature = "bevy_text")]
56
mod text;
67

78
pub use button::*;
89
pub use image::*;
10+
#[cfg(feature = "bevy_text")]
911
pub use text::*;

0 commit comments

Comments
 (0)