Skip to content

Commit

Permalink
Rename UiCamera to TargetCamera
Browse files Browse the repository at this point in the history
  • Loading branch information
bardt authored and robtfm committed Jan 9, 2024
1 parent 87cc976 commit 496d702
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 77 deletions.
9 changes: 4 additions & 5 deletions crates/bevy_ui/src/focus.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::{camera_config::UiCameraConfig, CalculatedClip, Node, UiCamera, UiScale, UiStack};
use bevy_derive::{Deref, DerefMut};
use crate::{camera_config::UiCameraConfig, CalculatedClip, Node, TargetCamera, UiScale, UiStack};
use bevy_ecs::{
change_detection::DetectChangesMut,
entity::Entity,
Expand Down Expand Up @@ -126,7 +125,7 @@ pub struct NodeQuery {
focus_policy: Option<&'static FocusPolicy>,
calculated_clip: Option<&'static CalculatedClip>,
view_visibility: Option<&'static ViewVisibility>,
ui_camera: Option<&'static UiCamera>,
target_camera: Option<&'static TargetCamera>,
}

/// The system that sets Interaction for all UI elements based on the mouse cursor activity
Expand Down Expand Up @@ -226,8 +225,8 @@ pub fn ui_focus_system(
return None;
}
let Some(camera_entity) = node
.ui_camera
.map(UiCamera::entity)
.target_camera
.map(TargetCamera::entity)
.or(default_single_camera)
else {
return None;
Expand Down
33 changes: 17 additions & 16 deletions crates/bevy_ui/src/layout/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod convert;
pub mod debug;

use crate::{ContentSize, Node, Outline, Style, UiCamera, UiScale};
use crate::{ContentSize, Node, Outline, Style, TargetCamera, UiScale};
use bevy_ecs::{
change_detection::{DetectChanges, DetectChangesMut},
entity::Entity,
Expand Down Expand Up @@ -249,8 +249,8 @@ pub fn ui_layout_system(
mut scale_factor_events: EventReader<WindowScaleFactorChanged>,
mut resize_events: EventReader<bevy_window::WindowResized>,
mut ui_surface: ResMut<UiSurface>,
root_node_query: Query<(Entity, Option<&UiCamera>), (With<Node>, Without<Parent>)>,
style_query: Query<(Entity, Ref<Style>, Option<&UiCamera>), With<Node>>,
root_node_query: Query<(Entity, Option<&TargetCamera>), (With<Node>, Without<Parent>)>,
style_query: Query<(Entity, Ref<Style>, Option<&TargetCamera>), With<Node>>,
mut measure_query: Query<(Entity, &mut ContentSize)>,
children_query: Query<(Entity, Ref<Children>), With<Node>>,
just_children_query: Query<&Children>,
Expand All @@ -268,8 +268,11 @@ pub fn ui_layout_system(

// If there is only one camera, we use it as default
let default_single_camera = cameras.get_single().ok().map(|(entity, _)| entity);
let camera_with_default =
|ui_camera: Option<&UiCamera>| ui_camera.map(UiCamera::entity).or(default_single_camera);
let camera_with_default = |target_camera: Option<&TargetCamera>| {
target_camera
.map(TargetCamera::entity)
.or(default_single_camera)
};

let resized_windows: HashSet<Entity> = resize_events.read().map(|event| event.window).collect();
let calculate_camera_layout_info = |camera: &Camera| {
Expand All @@ -291,12 +294,12 @@ pub fn ui_layout_system(

// Precalculate the layout info for each camera, so we have fast access to it for each node
let mut camera_layout_info: HashMap<Entity, CameraLayoutInfo> = HashMap::new();
for (entity, ui_camera) in &root_node_query {
match camera_with_default(ui_camera) {
for (entity, target_camera) in &root_node_query {
match camera_with_default(target_camera) {
Some(camera_entity) => {
let Ok((_, camera)) = cameras.get(camera_entity) else {
warn!(
"UiCamera is pointing to a camera {:?} which doesn't exist",
"TargetCamera is pointing to a camera {:?} which doesn't exist",
camera_entity
);
continue;
Expand All @@ -312,7 +315,7 @@ pub fn ui_layout_system(
} else {
warn!(
"Multiple cameras found, causing UI target ambiguity. \
To fix this, add an explicit `UiCamera` component to root UI node {:?}",
To fix this, add an explicit `TargetCamera` component to the root UI node {:?}",
entity
);
}
Expand All @@ -322,9 +325,9 @@ pub fn ui_layout_system(
}

// Resize all nodes
for (entity, style, ui_camera) in style_query.iter() {
for (entity, style, target_camera) in style_query.iter() {
if let Some(camera) =
camera_with_default(ui_camera).and_then(|c| camera_layout_info.get(&c))
camera_with_default(target_camera).and_then(|c| camera_layout_info.get(&c))
{
if camera.resized
|| !scale_factor_events.is_empty()
Expand All @@ -337,8 +340,6 @@ pub fn ui_layout_system(
);
ui_surface.upsert_node(entity, &style, &layout_context);
}
} else {
continue;
}
}
scale_factor_events.clear();
Expand Down Expand Up @@ -498,7 +499,7 @@ mod tests {
use crate::layout::round_layout_coords;
use crate::prelude::*;
use crate::ui_layout_system;
use crate::update::update_ui_camera_system;
use crate::update::update_target_camera_system;
use crate::ContentSize;
use crate::UiSurface;
use bevy_asset::AssetEvent;
Expand Down Expand Up @@ -553,7 +554,7 @@ mod tests {
world.spawn((
Window {
resolution: WindowResolution::new(WINDOW_WIDTH, WINDOW_HEIGHT),
..Default::default()
..default()
},
PrimaryWindow,
));
Expand All @@ -564,7 +565,7 @@ mod tests {
(
// UI is driven by calculated camera target info, so we need to run the camera system first
bevy_render::camera::camera_system::<OrthographicProjection>,
update_ui_camera_system,
update_target_camera_system,
apply_deferred,
ui_layout_system,
)
Expand Down
8 changes: 4 additions & 4 deletions crates/bevy_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use bevy_render::{extract_component::ExtractComponentPlugin, texture::Image, Ren
use bevy_transform::TransformSystem;
use stack::ui_stack_system;
pub use stack::UiStack;
use update::{update_clipping_system, update_ui_camera_system};
use update::{update_clipping_system, update_target_camera_system};

/// The basic plugin for Bevy UI
#[derive(Default)]
Expand Down Expand Up @@ -119,7 +119,7 @@ impl Plugin for UiPlugin {
.register_type::<RelativeCursorPosition>()
.register_type::<RepeatedGridTrack>()
.register_type::<Style>()
.register_type::<UiCamera>()
.register_type::<TargetCamera>()
.register_type::<UiCameraConfig>()
.register_type::<UiImage>()
.register_type::<UiImageSize>()
Expand Down Expand Up @@ -182,11 +182,11 @@ impl Plugin for UiPlugin {
(
(
widget::update_atlas_content_size_system,
update_ui_camera_system,
update_target_camera_system,
)
.before(UiSystem::Layout),
apply_deferred
.after(update_ui_camera_system)
.after(update_target_camera_system)
.before(UiSystem::Layout),
ui_layout_system
.in_set(UiSystem::Layout)
Expand Down
22 changes: 11 additions & 11 deletions crates/bevy_ui/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
prelude::UiCameraConfig, BackgroundColor, BorderColor, CalculatedClip, ContentSize, Node,
Style, UiImage, UiScale, UiTextureAtlasImage, Val,
};
use crate::{Outline, UiCamera};
use crate::{Outline, TargetCamera};

use bevy_app::prelude::*;
use bevy_asset::{load_internal_asset, AssetEvent, AssetId, Assets, Handle};
Expand Down Expand Up @@ -190,7 +190,7 @@ pub fn extract_atlas_uinodes(
Option<&CalculatedClip>,
&Handle<TextureAtlas>,
&UiTextureAtlasImage,
Option<&UiCamera>,
Option<&TargetCamera>,
),
Without<UiImage>,
>,
Expand All @@ -210,7 +210,7 @@ pub fn extract_atlas_uinodes(
camera,
) in uinode_query.iter()
{
let Some(camera_entity) = camera.map(UiCamera::entity).or(default_single_camera) else {
let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_single_camera) else {
continue;
};
// Skip invisible and completely transparent nodes
Expand Down Expand Up @@ -295,7 +295,7 @@ pub fn extract_uinode_borders(
Option<&Parent>,
&ViewVisibility,
Option<&CalculatedClip>,
Option<&UiCamera>,
Option<&TargetCamera>,
),
Without<ContentSize>,
>,
Expand All @@ -309,7 +309,7 @@ pub fn extract_uinode_borders(
for (node, global_transform, style, border_color, parent, view_visibility, clip, camera) in
&uinode_query
{
let Some(camera_entity) = camera.map(UiCamera::entity).or(default_single_camera) else {
let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_single_camera) else {
continue;
};
// Skip invisible borders
Expand Down Expand Up @@ -413,7 +413,7 @@ pub fn extract_uinode_outlines(
&Outline,
&ViewVisibility,
Option<&Parent>,
Option<&UiCamera>,
Option<&TargetCamera>,
)>,
>,
clip_query: Query<&CalculatedClip>,
Expand All @@ -422,7 +422,7 @@ pub fn extract_uinode_outlines(
let default_single_camera = camera_query.get_single().ok();
let image = AssetId::<Image>::default();
for (node, global_transform, outline, view_visibility, maybe_parent, camera) in &uinode_query {
let Some(camera_entity) = camera.map(UiCamera::entity).or(default_single_camera) else {
let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_single_camera) else {
continue;
};
// Skip invisible outlines
Expand Down Expand Up @@ -513,7 +513,7 @@ pub fn extract_uinodes(
Option<&UiImage>,
&ViewVisibility,
Option<&CalculatedClip>,
Option<&UiCamera>,
Option<&TargetCamera>,
),
Without<UiTextureAtlasImage>,
>,
Expand All @@ -524,7 +524,7 @@ pub fn extract_uinodes(
for (entity, uinode, transform, color, maybe_image, view_visibility, clip, camera) in
uinode_query.iter()
{
let Some(camera_entity) = camera.map(UiCamera::entity).or(default_single_camera) else {
let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_single_camera) else {
continue;
};
// Skip invisible and completely transparent nodes
Expand Down Expand Up @@ -657,7 +657,7 @@ pub fn extract_text_uinodes(
&TextLayoutInfo,
&ViewVisibility,
Option<&CalculatedClip>,
Option<&UiCamera>,
Option<&TargetCamera>,
)>,
>,
) {
Expand All @@ -666,7 +666,7 @@ pub fn extract_text_uinodes(
for (uinode, global_transform, text, text_layout_info, view_visibility, clip, camera) in
uinode_query.iter()
{
let Some(camera_entity) = camera.map(UiCamera::entity).or(default_single_camera) else {
let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_single_camera) else {
continue;
};
// Skip if not visible or if size is set to zero (e.g. when a parent is set to `Display::None`)
Expand Down
12 changes: 10 additions & 2 deletions crates/bevy_ui/src/ui_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1714,10 +1714,18 @@ mod tests {
}
}

/// Indicates that this root [`Node`] entity should be rendered to a specific camera.
/// UI then will be layed out respecting the camera's viewport and scale factor, and
/// rendered to this camera's [`bevy_render::camera::RenderTarget`].
///
/// Setting this component on a non-root node will have no effect. It will be overriden
/// by the root node's component.
///
/// Optional if there is only one camera in the world. Required otherwise.
#[derive(Component, Clone, Debug, Reflect, Eq, PartialEq)]
pub struct UiCamera(pub Entity);
pub struct TargetCamera(pub Entity);

impl UiCamera {
impl TargetCamera {
pub fn entity(&self) -> Entity {
self.0
}
Expand Down
38 changes: 19 additions & 19 deletions crates/bevy_ui/src/update.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! This module contains systems that update the UI when something changes

use crate::{CalculatedClip, OverflowAxis, Style, UiCamera};
use crate::{CalculatedClip, OverflowAxis, Style, TargetCamera};

use super::Node;
use bevy_ecs::{
Expand Down Expand Up @@ -94,40 +94,40 @@ fn update_clipping(
}
}

pub fn update_ui_camera_system(
pub fn update_target_camera_system(
mut commands: Commands,
changed_root_nodes_query: Query<
(Entity, Option<&UiCamera>),
(With<Node>, Without<Parent>, Changed<UiCamera>),
(Entity, Option<&TargetCamera>),
(With<Node>, Without<Parent>, Changed<TargetCamera>),
>,
changed_children_query: Query<(Entity, Option<&UiCamera>), (With<Node>, Changed<Children>)>,
changed_children_query: Query<(Entity, Option<&TargetCamera>), (With<Node>, Changed<Children>)>,
children_query: Query<&Children, With<Node>>,
node_query: Query<Option<&UiCamera>, With<Node>>,
node_query: Query<Option<&TargetCamera>, With<Node>>,
) {
// Track updated entities to prevent redundant updates, as `Commands` changes are deferred,
// and updates done for changed_children_query can overlap with itself or with root_node_query
let mut updated_entities = HashSet::new();

// Assuming that UiCamera is manually set on the root node only,
// Assuming that TargetCamera is manually set on the root node only,
// update root nodes first, since it implies the biggest change
for (root_node, camera) in &changed_root_nodes_query {
update_children_ui_camera(
for (root_node, target_camera) in &changed_root_nodes_query {
update_children_target_camera(
root_node,
camera,
target_camera,
&node_query,
&children_query,
&mut commands,
&mut updated_entities,
);
}

// If the root node UiCamera was changed, then every child is updated
// If the root node TargetCamera was changed, then every child is updated
// by this point, and iteration will be skipped.
// Otherwise, update changed children
for (parent, camera) in &changed_children_query {
update_children_ui_camera(
for (parent, target_camera) in &changed_children_query {
update_children_target_camera(
parent,
camera,
target_camera,
&node_query,
&children_query,
&mut commands,
Expand All @@ -136,10 +136,10 @@ pub fn update_ui_camera_system(
}
}

fn update_children_ui_camera(
fn update_children_target_camera(
entity: Entity,
camera_to_set: Option<&UiCamera>,
node_query: &Query<Option<&UiCamera>, With<Node>>,
camera_to_set: Option<&TargetCamera>,
node_query: &Query<Option<&TargetCamera>, With<Node>>,
children_query: &Query<&Children, With<Node>>,
commands: &mut Commands,
updated_entities: &mut HashSet<Entity>,
Expand All @@ -159,12 +159,12 @@ fn update_children_ui_camera(
commands.entity(child).insert(camera.clone());
}
None => {
commands.entity(child).remove::<UiCamera>();
commands.entity(child).remove::<TargetCamera>();
}
}
updated_entities.insert(child);

update_children_ui_camera(
update_children_target_camera(
child,
camera_to_set,
node_query,
Expand Down
Loading

0 comments on commit 496d702

Please sign in to comment.