Skip to content

Feature gate render in UI (fix bevy_test feature) #16322

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

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion crates/bevy_image/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::dds::*;
#[cfg(feature = "ktx2")]
use super::ktx2::*;

use bevy_asset::{Asset, RenderAssetUsages};
use bevy_asset::{Asset, Handle, RenderAssetUsages};
use bevy_color::{Color, ColorToComponents, Gray, LinearRgba, Srgba, Xyza};
use bevy_math::{AspectRatio, UVec2, UVec3, Vec2};
use bevy_reflect::std_traits::ReflectDefault;
Expand Down Expand Up @@ -282,6 +282,14 @@ impl ImageFormat {
}
}

/// A handle to a 1 x 1 transparent white image.
///
/// Like [`Handle<Image>::default`], this is a handle to a fallback image asset.
/// While that handle points to an opaque white 1 x 1 image, this handle points to a transparent 1 x 1 white image.
// Number randomly selected by fair WolframAlpha query. Totally arbitrary.
pub const TRANSPARENT_IMAGE_HANDLE: Handle<Image> =
Handle::weak_from_u128(154728948001857810431816125397303024160);

#[derive(Asset, Reflect, Debug, Clone)]
#[reflect(opaque)]
#[reflect(Default, Debug)]
Expand Down
16 changes: 6 additions & 10 deletions crates/bevy_render/src/texture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ mod texture_cache;
pub use crate::render_resource::DefaultImageSampler;
#[cfg(feature = "basis-universal")]
use bevy_image::CompressedImageSaver;
#[cfg(feature = "exr")]
use bevy_image::ExrTextureLoader;
#[cfg(feature = "hdr")]
use bevy_image::HdrTextureLoader;
use bevy_image::{CompressedImageFormats, Image, ImageLoader, ImageSamplerDescriptor};
use bevy_image::{
CompressedImageFormats, Image, ImageLoader, ImageSamplerDescriptor, TRANSPARENT_IMAGE_HANDLE,
};
pub use fallback_image::*;
pub use gpu_image::*;
pub use texture_attachment::*;
Expand All @@ -21,14 +25,6 @@ use bevy_app::{App, Plugin};
use bevy_asset::{AssetApp, Assets, Handle};
use bevy_ecs::prelude::*;

/// A handle to a 1 x 1 transparent white image.
///
/// Like [`Handle<Image>::default`], this is a handle to a fallback image asset.
/// While that handle points to an opaque white 1 x 1 image, this handle points to a transparent 1 x 1 white image.
// Number randomly selected by fair WolframAlpha query. Totally arbitrary.
pub const TRANSPARENT_IMAGE_HANDLE: Handle<Image> =
Handle::weak_from_u128(154728948001857810431816125397303024160);

// TODO: replace Texture names with Image names?
/// Adds the [`Image`] as an asset and makes sure that they are extracted and prepared for the GPU.
pub struct ImagePlugin {
Expand Down Expand Up @@ -62,7 +58,7 @@ impl Plugin for ImagePlugin {
fn build(&self, app: &mut App) {
#[cfg(feature = "exr")]
{
app.init_asset_loader::<bevy_image::ExrTextureLoader>();
app.init_asset_loader::<ExrTextureLoader>();
}

#[cfg(feature = "hdr")]
Expand Down
7 changes: 4 additions & 3 deletions crates/bevy_ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ bevy_math = { path = "../bevy_math", version = "0.15.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [
"bevy",
] }
bevy_render = { path = "../bevy_render", version = "0.15.0-dev" }
bevy_render = { path = "../bevy_render", version = "0.15.0-dev", optional = true }
bevy_animation = { path = "../bevy_animation", version = "0.15.0-dev" }
bevy_sprite = { path = "../bevy_sprite", version = "0.15.0-dev" }
bevy_text = { path = "../bevy_text", version = "0.15.0-dev" }
bevy_text = { path = "../bevy_text", version = "0.15.0-dev", optional = true }
bevy_picking = { path = "../bevy_picking", version = "0.15.0-dev", optional = true }
bevy_transform = { path = "../bevy_transform", version = "0.15.0-dev" }
bevy_window = { path = "../bevy_window", version = "0.15.0-dev" }
Expand All @@ -43,7 +44,7 @@ smallvec = "1.11"
accesskit = "0.17"

[features]
default = []
default = ["bevy_ui_picking_backend", "bevy_render", "bevy_text"]
serialize = ["serde", "smallvec/serde", "bevy_math/serialize"]
bevy_ui_picking_backend = ["bevy_picking"]
bevy_ui_debug = []
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/accessibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use bevy_app::{App, Plugin, PostUpdate};
use bevy_ecs::{
prelude::{DetectChanges, Entity},
query::{Changed, Without},
schedule::IntoSystemConfigs,
schedule::IntoSystemConfigs as _,
system::{Commands, Query},
world::Ref,
};
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_ui/src/experimental/ghost_hierarchy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use bevy_ecs::{prelude::*, system::SystemParam};
use bevy_hierarchy::{Children, HierarchyQueryExt, Parent};
use bevy_reflect::prelude::*;
#[cfg(feature = "bevy_render")]
use bevy_render::view::Visibility;
use bevy_transform::prelude::Transform;
use core::marker::PhantomData;
Expand All @@ -20,7 +21,8 @@ use crate::Node;
#[derive(Component, Debug, Copy, Clone, Reflect)]
#[cfg_attr(feature = "ghost_nodes", derive(Default))]
#[reflect(Component, Debug)]
#[require(Visibility, Transform)]
#[cfg_attr(feature = "bevy_render", require(Visibility))]
#[require(Transform)]
pub struct GhostNode {
// This is a workaround to ensure that GhostNode is only constructable when the appropriate feature flag is enabled
#[reflect(ignore)]
Expand Down
38 changes: 22 additions & 16 deletions crates/bevy_ui/src/focus.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
use crate::{
CalculatedClip, ComputedNode, DefaultUiCamera, ResolvedBorderRadius, TargetCamera, UiStack,
};
use bevy_ecs::{
change_detection::DetectChangesMut,
entity::{Entity, EntityBorrow},
prelude::{Component, With},
query::QueryData,
reflect::ReflectComponent,
system::{Local, Query, Res},
};
use bevy_input::{mouse::MouseButton, touch::Touches, ButtonInput};
use crate::{CalculatedClip, ComputedNode};
use bevy_ecs::{entity::Entity, prelude::Component, query::QueryData, reflect::ReflectComponent};
use bevy_math::{Rect, Vec2};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_render::{camera::NormalizedRenderTarget, prelude::Camera, view::ViewVisibility};
use bevy_transform::components::GlobalTransform;
use bevy_utils::HashMap;
use bevy_window::{PrimaryWindow, Window};

use smallvec::SmallVec;
#[cfg(feature = "bevy_render")]
use {
crate::{DefaultUiCamera, ResolvedBorderRadius, TargetCamera, UiStack},
bevy_ecs::{
change_detection::DetectChangesMut as _,
entity::EntityBorrow as _,
prelude::With,
system::{Local, Query, Res},
},
bevy_input::{mouse::MouseButton, touch::Touches, ButtonInput},
bevy_render::{camera::NormalizedRenderTarget, prelude::Camera, view::ViewVisibility},
bevy_utils::HashMap,
bevy_window::{PrimaryWindow, Window},
smallvec::SmallVec,
};

#[cfg(feature = "serialize")]
use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
Expand Down Expand Up @@ -125,6 +126,7 @@ impl Default for FocusPolicy {

/// Contains entities whose Interaction should be set to None
#[derive(Default)]
#[cfg(feature = "bevy_render")]
pub struct State {
entities_to_reset: SmallVec<[Entity; 1]>,
}
Expand All @@ -140,14 +142,17 @@ pub struct NodeQuery {
relative_cursor_position: Option<&'static mut RelativeCursorPosition>,
focus_policy: Option<&'static FocusPolicy>,
calculated_clip: Option<&'static CalculatedClip>,
#[cfg(feature = "bevy_render")]
view_visibility: Option<&'static ViewVisibility>,
#[cfg(feature = "bevy_render")]
target_camera: Option<&'static TargetCamera>,
}

/// The system that sets Interaction for all UI elements based on the mouse cursor activity
///
/// Entities with a hidden [`ViewVisibility`] are always treated as released.
#[allow(clippy::too_many_arguments)]
#[cfg(feature = "bevy_render")]
pub fn ui_focus_system(
mut state: Local<State>,
camera_query: Query<(Entity, &Camera)>,
Expand Down Expand Up @@ -346,6 +351,7 @@ pub fn ui_focus_system(
// the given size and border radius.
//
// Matches the sdf function in `ui.wgsl` that is used by the UI renderer to draw rounded rectangles.
#[cfg(feature = "bevy_render")]
pub(crate) fn pick_rounded_rect(
point: Vec2,
size: Vec2,
Expand Down
61 changes: 36 additions & 25 deletions crates/bevy_ui/src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged};
use thiserror::Error;
use ui_surface::UiSurface;

use bevy_text::ComputedTextBlock;

use bevy_text::CosmicFontSystem;
#[cfg(feature = "bevy_text")]
use bevy_text::{ComputedTextBlock, CosmicFontSystem};

mod convert;
pub mod debug;
Expand Down Expand Up @@ -126,8 +125,8 @@ pub fn ui_layout_system(
Option<&ScrollPosition>,
)>,

mut buffer_query: Query<&mut ComputedTextBlock>,
mut font_system: ResMut<CosmicFontSystem>,
#[cfg(feature = "bevy_text")] mut buffer_query: Query<&mut ComputedTextBlock>,
#[cfg(feature = "bevy_text")] mut font_system: ResMut<CosmicFontSystem>,
) {
let UiLayoutSystemBuffers {
interned_root_nodes,
Expand Down Expand Up @@ -269,6 +268,7 @@ with UI components as a child of an entity without UI components, your UI layout
}
});

#[cfg(feature = "bevy_text")]
let text_buffers = &mut buffer_query;
// clean up removed nodes after syncing children to avoid potential panic (invalid SlotMap key used)
ui_surface.remove_entities(
Expand All @@ -288,8 +288,14 @@ with UI components as a child of an entity without UI components, your UI layout
for (camera_id, mut camera) in camera_layout_info.drain() {
let inverse_target_scale_factor = camera.scale_factor.recip();

ui_surface.compute_camera_layout(camera_id, camera.size, text_buffers, &mut font_system);

ui_surface.compute_camera_layout(
camera_id,
camera.size,
#[cfg(feature = "bevy_text")]
text_buffers,
#[cfg(feature = "bevy_text")]
&mut font_system,
);
for root in &camera.root_nodes {
update_uinode_geometry_recursive(
&mut commands,
Expand Down Expand Up @@ -488,6 +494,7 @@ mod tests {
};
use bevy_image::Image;
use bevy_math::{Rect, UVec2, Vec2};
use bevy_render::camera::Viewport;
use bevy_render::{camera::ManualTextureViews, prelude::Camera};
use bevy_transform::{
prelude::GlobalTransform,
Expand All @@ -504,6 +511,9 @@ mod tests {
update::update_target_camera_system, ContentSize, LayoutContext,
};

#[cfg(feature = "bevy_text")]
use bevy_text::{ComputedTextBlock, CosmicFontSystem, SwashCache, TextPipeline};

// these window dimensions are easy to convert to and from percentage values
const WINDOW_WIDTH: f32 = 1000.;
const WINDOW_HEIGHT: f32 = 100.;
Expand All @@ -519,13 +529,12 @@ mod tests {
world.init_resource::<Events<AssetEvent<Image>>>();
world.init_resource::<Assets<Image>>();
world.init_resource::<ManualTextureViews>();

world.init_resource::<bevy_text::TextPipeline>();

world.init_resource::<bevy_text::CosmicFontSystem>();

world.init_resource::<bevy_text::SwashCache>();

#[cfg(feature = "bevy_text")]
{
world.init_resource::<TextPipeline>();
world.init_resource::<CosmicFontSystem>();
world.init_resource::<SwashCache>();
}
// spawn a dummy primary window and camera
world.spawn((
Window {
Expand Down Expand Up @@ -915,7 +924,7 @@ mod tests {
let viewport_height = primary_window.resolution.physical_height();
let physical_position = UVec2::new(viewport_width * camera_index as u32, 0);
let physical_size = UVec2::new(viewport_width, viewport_height);
camera.viewport = Some(bevy_render::camera::Viewport {
camera.viewport = Some(Viewport {
physical_position,
physical_size,
..default()
Expand Down Expand Up @@ -1164,13 +1173,12 @@ mod tests {
world.init_resource::<Events<AssetEvent<Image>>>();
world.init_resource::<Assets<Image>>();
world.init_resource::<ManualTextureViews>();

world.init_resource::<bevy_text::TextPipeline>();

world.init_resource::<bevy_text::CosmicFontSystem>();

world.init_resource::<bevy_text::SwashCache>();

#[cfg(feature = "bevy_text")]
{
world.init_resource::<TextPipeline>();
world.init_resource::<CosmicFontSystem>();
world.init_resource::<SwashCache>();
}
// spawn a dummy primary window and camera
world.spawn((
Window {
Expand Down Expand Up @@ -1230,20 +1238,23 @@ mod tests {
fn test_system(
params: In<TestSystemParam>,
mut ui_surface: ResMut<UiSurface>,
mut computed_text_block_query: Query<&mut bevy_text::ComputedTextBlock>,
mut font_system: ResMut<bevy_text::CosmicFontSystem>,
#[cfg(feature = "bevy_text")] mut computed_text_block_query: Query<
&mut ComputedTextBlock,
>,
#[cfg(feature = "bevy_text")] mut font_system: ResMut<CosmicFontSystem>,
) {
ui_surface.upsert_node(
&LayoutContext::TEST_CONTEXT,
params.root_node_entity,
&Node::default(),
None,
);

ui_surface.compute_camera_layout(
params.camera_entity,
UVec2::new(800, 600),
#[cfg(feature = "bevy_text")]
&mut computed_text_block_query,
#[cfg(feature = "bevy_text")]
&mut font_system,
);
}
Expand Down
24 changes: 15 additions & 9 deletions crates/bevy_ui/src/layout/ui_surface.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
use core::fmt;

use taffy::TaffyTree;

use crate::{layout::convert, LayoutContext, LayoutError, Node, NodeMeasure};
use crate::{Measure, MeasureArgs};
use bevy_ecs::{
entity::{Entity, EntityHashMap},
prelude::Resource,
};
use bevy_math::{UVec2, Vec2};
use bevy_utils::default;

use crate::{layout::convert, LayoutContext, LayoutError, Measure, MeasureArgs, Node, NodeMeasure};
#[cfg(feature = "bevy_text")]
use bevy_text::CosmicFontSystem;
use bevy_utils::default;
use core::fmt;
use taffy::TaffyTree;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RootNodePair {
Expand Down Expand Up @@ -198,8 +197,10 @@ impl UiSurface {
&mut self,
camera: Entity,
render_target_resolution: UVec2,
buffer_query: &'a mut bevy_ecs::prelude::Query<&mut bevy_text::ComputedTextBlock>,
font_system: &'a mut CosmicFontSystem,
#[cfg(feature = "bevy_text")] buffer_query: &'a mut bevy_ecs::prelude::Query<
&mut bevy_text::ComputedTextBlock,
>,
#[cfg(feature = "bevy_text")] font_system: &'a mut CosmicFontSystem,
) {
let Some(camera_root_nodes) = self.camera_roots.get(&camera) else {
return;
Expand All @@ -222,6 +223,7 @@ impl UiSurface {
-> taffy::Size<f32> {
context
.map(|ctx| {
#[cfg(feature = "bevy_text")]
let buffer = get_text_buffer(
crate::widget::TextMeasure::needs_buffer(
known_dimensions.height,
Expand All @@ -236,8 +238,11 @@ impl UiSurface {
height: known_dimensions.height,
available_width: available_space.width,
available_height: available_space.height,
#[cfg(feature = "bevy_text")]
font_system,
#[cfg(feature = "bevy_text")]
buffer,
_phantom: default(),
},
style,
);
Expand Down Expand Up @@ -307,6 +312,7 @@ impl UiSurface {
}
}

#[cfg(feature = "bevy_text")]
fn get_text_buffer<'a>(
needs_buffer: bool,
ctx: &mut NodeMeasure,
Expand Down
Loading
Loading