make bevy_text optional again (#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
This commit is contained in:
parent
695d30bd54
commit
1bd7306a3a
@ -82,6 +82,8 @@ dynamic_linking = ["bevy_diagnostic/dynamic_linking"]
|
||||
# Enable using a shared stdlib for cxx on Android.
|
||||
android_shared_stdcxx = ["bevy_audio/android_shared_stdcxx"]
|
||||
|
||||
bevy_text = ["dep:bevy_text", "bevy_ui?/bevy_text"]
|
||||
|
||||
[dependencies]
|
||||
# bevy
|
||||
bevy_app = { path = "../bevy_app", version = "0.9.0" }
|
||||
|
@ -24,7 +24,7 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.9.0", features = [
|
||||
] }
|
||||
bevy_render = { path = "../bevy_render", version = "0.9.0" }
|
||||
bevy_sprite = { path = "../bevy_sprite", version = "0.9.0" }
|
||||
bevy_text = { path = "../bevy_text", version = "0.9.0" }
|
||||
bevy_text = { path = "../bevy_text", version = "0.9.0", optional = true }
|
||||
bevy_transform = { path = "../bevy_transform", version = "0.9.0" }
|
||||
bevy_window = { path = "../bevy_window", version = "0.9.0" }
|
||||
bevy_utils = { path = "../bevy_utils", version = "0.9.0" }
|
||||
|
@ -14,7 +14,9 @@ pub mod node_bundles;
|
||||
pub mod update;
|
||||
pub mod widget;
|
||||
|
||||
use bevy_render::{camera::CameraUpdateSystem, extract_component::ExtractComponentPlugin};
|
||||
#[cfg(feature = "bevy_text")]
|
||||
use bevy_render::camera::CameraUpdateSystem;
|
||||
use bevy_render::extract_component::ExtractComponentPlugin;
|
||||
pub use flex::*;
|
||||
pub use focus::*;
|
||||
pub use geometry::*;
|
||||
@ -103,44 +105,49 @@ impl Plugin for UiPlugin {
|
||||
.configure_set(UiSystem::Focus.in_base_set(CoreSet::PreUpdate))
|
||||
.configure_set(UiSystem::Flex.in_base_set(CoreSet::PostUpdate))
|
||||
.configure_set(UiSystem::Stack.in_base_set(CoreSet::PostUpdate))
|
||||
.add_system(ui_focus_system.in_set(UiSystem::Focus).after(InputSystem))
|
||||
// add these systems to front because these must run before transform update systems
|
||||
.add_system(
|
||||
widget::text_system
|
||||
.in_base_set(CoreSet::PostUpdate)
|
||||
.before(UiSystem::Flex)
|
||||
// Potential conflict: `Assets<Image>`
|
||||
// In practice, they run independently since `bevy_render::camera_update_system`
|
||||
// will only ever observe its own render target, and `widget::text_system`
|
||||
// will never modify a pre-existing `Image` asset.
|
||||
.ambiguous_with(CameraUpdateSystem)
|
||||
// Potential conflict: `Assets<Image>`
|
||||
// Since both systems will only ever insert new [`Image`] assets,
|
||||
// they will never observe each other's effects.
|
||||
.ambiguous_with(bevy_text::update_text2d_layout),
|
||||
)
|
||||
.add_system(
|
||||
widget::update_image_calculated_size_system
|
||||
.in_base_set(CoreSet::PostUpdate)
|
||||
.before(UiSystem::Flex)
|
||||
// Potential conflicts: `Assets<Image>`
|
||||
// They run independently since `widget::image_node_system` will only ever observe
|
||||
// its own UiImage, and `widget::text_system` & `bevy_text::update_text2d_layout`
|
||||
// will never modify a pre-existing `Image` asset.
|
||||
.ambiguous_with(bevy_text::update_text2d_layout)
|
||||
.ambiguous_with(widget::text_system),
|
||||
)
|
||||
.add_system(
|
||||
flex_node_system
|
||||
.in_set(UiSystem::Flex)
|
||||
.before(TransformSystem::TransformPropagate),
|
||||
)
|
||||
.add_system(ui_stack_system.in_set(UiSystem::Stack))
|
||||
.add_system(
|
||||
update_clipping_system
|
||||
.after(TransformSystem::TransformPropagate)
|
||||
.in_base_set(CoreSet::PostUpdate),
|
||||
);
|
||||
.add_system(ui_focus_system.in_set(UiSystem::Focus).after(InputSystem));
|
||||
// add these systems to front because these must run before transform update systems
|
||||
#[cfg(feature = "bevy_text")]
|
||||
app.add_system(
|
||||
widget::text_system
|
||||
.in_base_set(CoreSet::PostUpdate)
|
||||
.before(UiSystem::Flex)
|
||||
// Potential conflict: `Assets<Image>`
|
||||
// In practice, they run independently since `bevy_render::camera_update_system`
|
||||
// will only ever observe its own render target, and `widget::text_system`
|
||||
// will never modify a pre-existing `Image` asset.
|
||||
.ambiguous_with(CameraUpdateSystem)
|
||||
// Potential conflict: `Assets<Image>`
|
||||
// Since both systems will only ever insert new [`Image`] assets,
|
||||
// they will never observe each other's effects.
|
||||
.ambiguous_with(bevy_text::update_text2d_layout),
|
||||
);
|
||||
app.add_system({
|
||||
let system = widget::update_image_calculated_size_system
|
||||
.in_base_set(CoreSet::PostUpdate)
|
||||
.before(UiSystem::Flex);
|
||||
// Potential conflicts: `Assets<Image>`
|
||||
// They run independently since `widget::image_node_system` will only ever observe
|
||||
// its own UiImage, and `widget::text_system` & `bevy_text::update_text2d_layout`
|
||||
// will never modify a pre-existing `Image` asset.
|
||||
#[cfg(feature = "bevy_text")]
|
||||
let system = system
|
||||
.ambiguous_with(bevy_text::update_text2d_layout)
|
||||
.ambiguous_with(widget::text_system);
|
||||
|
||||
system
|
||||
})
|
||||
.add_system(
|
||||
flex_node_system
|
||||
.in_set(UiSystem::Flex)
|
||||
.before(TransformSystem::TransformPropagate),
|
||||
)
|
||||
.add_system(ui_stack_system.in_set(UiSystem::Stack))
|
||||
.add_system(
|
||||
update_clipping_system
|
||||
.after(TransformSystem::TransformPropagate)
|
||||
.in_base_set(CoreSet::PostUpdate),
|
||||
);
|
||||
|
||||
crate::render::build_ui_render(app);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use bevy_render::{
|
||||
prelude::{Color, ComputedVisibility},
|
||||
view::Visibility,
|
||||
};
|
||||
#[cfg(feature = "bevy_text")]
|
||||
use bevy_text::{Text, TextAlignment, TextSection, TextStyle};
|
||||
use bevy_transform::prelude::{GlobalTransform, Transform};
|
||||
|
||||
@ -95,6 +96,7 @@ pub struct ImageBundle {
|
||||
pub z_index: ZIndex,
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_text")]
|
||||
/// A UI node that is text
|
||||
#[derive(Bundle, Clone, Debug)]
|
||||
pub struct TextBundle {
|
||||
@ -128,6 +130,7 @@ pub struct TextBundle {
|
||||
pub background_color: BackgroundColor,
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_text")]
|
||||
impl Default for TextBundle {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@ -147,6 +150,7 @@ impl Default for TextBundle {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_text")]
|
||||
impl TextBundle {
|
||||
/// Create a [`TextBundle`] from a single section.
|
||||
///
|
||||
|
@ -3,6 +3,7 @@ mod render_pass;
|
||||
|
||||
use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d};
|
||||
use bevy_render::ExtractSchedule;
|
||||
#[cfg(feature = "bevy_text")]
|
||||
use bevy_window::{PrimaryWindow, Window};
|
||||
pub use pipeline::*;
|
||||
pub use render_pass::*;
|
||||
@ -26,7 +27,10 @@ use bevy_render::{
|
||||
view::{ComputedVisibility, ExtractedView, ViewUniforms},
|
||||
Extract, RenderApp, RenderSet,
|
||||
};
|
||||
use bevy_sprite::{SpriteAssetEvents, TextureAtlas};
|
||||
use bevy_sprite::SpriteAssetEvents;
|
||||
#[cfg(feature = "bevy_text")]
|
||||
use bevy_sprite::TextureAtlas;
|
||||
#[cfg(feature = "bevy_text")]
|
||||
use bevy_text::{Text, TextLayoutInfo};
|
||||
use bevy_transform::components::GlobalTransform;
|
||||
use bevy_utils::FloatOrd;
|
||||
@ -78,6 +82,7 @@ pub fn build_ui_render(app: &mut App) {
|
||||
extract_default_ui_camera_view::<Camera2d>,
|
||||
extract_default_ui_camera_view::<Camera3d>,
|
||||
extract_uinodes.in_set(RenderUiSystem::ExtractNode),
|
||||
#[cfg(feature = "bevy_text")]
|
||||
extract_text_uinodes.after(RenderUiSystem::ExtractNode),
|
||||
),
|
||||
)
|
||||
@ -288,6 +293,7 @@ pub fn extract_default_ui_camera_view<T: Component>(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_text")]
|
||||
pub fn extract_text_uinodes(
|
||||
mut extracted_uinodes: ResMut<ExtractedUiNodes>,
|
||||
texture_atlases: Extract<Res<Assets<TextureAtlas>>>,
|
||||
|
@ -1,17 +1,18 @@
|
||||
use crate::{CalculatedSize, UiImage};
|
||||
use bevy_asset::Assets;
|
||||
use bevy_ecs::{
|
||||
query::Without,
|
||||
system::{Query, Res},
|
||||
};
|
||||
#[cfg(feature = "bevy_text")]
|
||||
use bevy_ecs::query::Without;
|
||||
use bevy_ecs::system::{Query, Res};
|
||||
use bevy_math::Vec2;
|
||||
use bevy_render::texture::Image;
|
||||
#[cfg(feature = "bevy_text")]
|
||||
use bevy_text::Text;
|
||||
|
||||
/// Updates calculated size of the node based on the image provided
|
||||
pub fn update_image_calculated_size_system(
|
||||
textures: Res<Assets<Image>>,
|
||||
mut query: Query<(&mut CalculatedSize, &UiImage), Without<Text>>,
|
||||
#[cfg(feature = "bevy_text")] mut query: Query<(&mut CalculatedSize, &UiImage), Without<Text>>,
|
||||
#[cfg(not(feature = "bevy_text"))] mut query: Query<(&mut CalculatedSize, &UiImage)>,
|
||||
) {
|
||||
for (mut calculated_size, image) in &mut query {
|
||||
if let Some(texture) = textures.get(&image.texture) {
|
||||
|
@ -2,8 +2,10 @@
|
||||
|
||||
mod button;
|
||||
mod image;
|
||||
#[cfg(feature = "bevy_text")]
|
||||
mod text;
|
||||
|
||||
pub use button::*;
|
||||
pub use image::*;
|
||||
#[cfg(feature = "bevy_text")]
|
||||
pub use text::*;
|
||||
|
Loading…
Reference in New Issue
Block a user