Merge branch 'main' into val-physical-resolve

This commit is contained in:
ickshonpe 2025-05-26 17:03:34 +01:00 committed by GitHub
commit 0516a9bee6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 39 additions and 123 deletions

View File

@ -10,7 +10,7 @@ keywords = ["game", "engine", "gamedev", "graphics", "bevy"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
repository = "https://github.com/bevyengine/bevy" repository = "https://github.com/bevyengine/bevy"
documentation = "https://docs.rs/bevy" documentation = "https://docs.rs/bevy"
rust-version = "1.85.0" rust-version = "1.86.0"
[workspace] [workspace]
resolver = "2" resolver = "2"

View File

@ -205,8 +205,6 @@ pub fn derive_enum_variant_meta(input: TokenStream) -> TokenStream {
pub fn derive_app_label(input: TokenStream) -> TokenStream { pub fn derive_app_label(input: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(input as syn::DeriveInput); let input = syn::parse_macro_input!(input as syn::DeriveInput);
let mut trait_path = BevyManifest::shared().get_path("bevy_app"); let mut trait_path = BevyManifest::shared().get_path("bevy_app");
let mut dyn_eq_path = trait_path.clone();
trait_path.segments.push(format_ident!("AppLabel").into()); trait_path.segments.push(format_ident!("AppLabel").into());
dyn_eq_path.segments.push(format_ident!("DynEq").into()); derive_label(input, "AppLabel", &trait_path)
derive_label(input, "AppLabel", &trait_path, &dyn_eq_path)
} }

View File

@ -1,7 +1,6 @@
//! Text and on-screen debugging tools //! Text and on-screen debugging tools
use bevy_app::prelude::*; use bevy_app::prelude::*;
use bevy_asset::prelude::*;
use bevy_color::prelude::*; use bevy_color::prelude::*;
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use bevy_picking::backend::HitData; use bevy_picking::backend::HitData;
@ -248,25 +247,18 @@ pub fn debug_draw(
pointers: Query<(Entity, &PointerId, &PointerDebug)>, pointers: Query<(Entity, &PointerId, &PointerDebug)>,
scale: Res<UiScale>, scale: Res<UiScale>,
) { ) {
let font_handle: Handle<Font> = Default::default(); for (entity, id, debug) in &pointers {
for (entity, id, debug) in pointers.iter() {
let Some(pointer_location) = &debug.location else { let Some(pointer_location) = &debug.location else {
continue; continue;
}; };
let text = format!("{id:?}\n{debug}"); let text = format!("{id:?}\n{debug}");
for camera in camera_query for (camera, _) in camera_query.iter().filter(|(_, camera)| {
.iter() camera
.map(|(entity, camera)| { .target
( .normalize(primary_window.single().ok())
entity, .is_some_and(|target| target == pointer_location.target)
camera.target.normalize(primary_window.single().ok()), }) {
)
})
.filter_map(|(entity, target)| Some(entity).zip(target))
.filter(|(_entity, target)| target == &pointer_location.target)
.map(|(cam_entity, _target)| cam_entity)
{
let mut pointer_pos = pointer_location.position; let mut pointer_pos = pointer_location.position;
if let Some(viewport) = camera_query if let Some(viewport) = camera_query
.get(camera) .get(camera)
@ -278,23 +270,21 @@ pub fn debug_draw(
commands commands
.entity(entity) .entity(entity)
.despawn_related::<Children>()
.insert(( .insert((
Text::new(text.clone()),
TextFont {
font: font_handle.clone(),
font_size: 12.0,
..Default::default()
},
TextColor(Color::WHITE),
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
left: Val::Px(pointer_pos.x + 5.0) / scale.0, left: Val::Px(pointer_pos.x + 5.0) / scale.0,
top: Val::Px(pointer_pos.y + 5.0) / scale.0, top: Val::Px(pointer_pos.y + 5.0) / scale.0,
padding: UiRect::px(10.0, 10.0, 8.0, 6.0),
..Default::default() ..Default::default()
}, },
)) BackgroundColor(Color::BLACK.with_alpha(0.75)),
.insert(Pickable::IGNORE) GlobalZIndex(i32::MAX),
.insert(UiTargetCamera(camera)); Pickable::IGNORE,
UiTargetCamera(camera),
children![(Text::new(text.clone()), TextFont::from_font_size(12.0))],
));
} }
} }
} }

View File

@ -8,7 +8,7 @@ repository = "https://github.com/bevyengine/bevy"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
keywords = ["ecs", "game", "bevy"] keywords = ["ecs", "game", "bevy"]
categories = ["game-engines", "data-structures"] categories = ["game-engines", "data-structures"]
rust-version = "1.85.0" rust-version = "1.86.0"
[features] [features]
default = ["std", "bevy_reflect", "async_executor", "backtrace"] default = ["std", "bevy_reflect", "async_executor", "backtrace"]

View File

@ -503,12 +503,10 @@ pub fn derive_schedule_label(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput); let input = parse_macro_input!(input as DeriveInput);
let mut trait_path = bevy_ecs_path(); let mut trait_path = bevy_ecs_path();
trait_path.segments.push(format_ident!("schedule").into()); trait_path.segments.push(format_ident!("schedule").into());
let mut dyn_eq_path = trait_path.clone();
trait_path trait_path
.segments .segments
.push(format_ident!("ScheduleLabel").into()); .push(format_ident!("ScheduleLabel").into());
dyn_eq_path.segments.push(format_ident!("DynEq").into()); derive_label(input, "ScheduleLabel", &trait_path)
derive_label(input, "ScheduleLabel", &trait_path, &dyn_eq_path)
} }
/// Derive macro generating an impl of the trait `SystemSet`. /// Derive macro generating an impl of the trait `SystemSet`.
@ -519,10 +517,8 @@ pub fn derive_system_set(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput); let input = parse_macro_input!(input as DeriveInput);
let mut trait_path = bevy_ecs_path(); let mut trait_path = bevy_ecs_path();
trait_path.segments.push(format_ident!("schedule").into()); trait_path.segments.push(format_ident!("schedule").into());
let mut dyn_eq_path = trait_path.clone();
trait_path.segments.push(format_ident!("SystemSet").into()); trait_path.segments.push(format_ident!("SystemSet").into());
dyn_eq_path.segments.push(format_ident!("DynEq").into()); derive_label(input, "SystemSet", &trait_path)
derive_label(input, "SystemSet", &trait_path, &dyn_eq_path)
} }
pub(crate) fn bevy_ecs_path() -> syn::Path { pub(crate) fn bevy_ecs_path() -> syn::Path {

View File

@ -12,9 +12,6 @@ pub use alloc::boxed::Box;
/// An object safe version of [`Eq`]. This trait is automatically implemented /// An object safe version of [`Eq`]. This trait is automatically implemented
/// for any `'static` type that implements `Eq`. /// for any `'static` type that implements `Eq`.
pub trait DynEq: Any { pub trait DynEq: Any {
/// Casts the type to `dyn Any`.
fn as_any(&self) -> &dyn Any;
/// This method tests for `self` and `other` values to be equal. /// This method tests for `self` and `other` values to be equal.
/// ///
/// Implementers should avoid returning `true` when the underlying types are /// Implementers should avoid returning `true` when the underlying types are
@ -29,12 +26,8 @@ impl<T> DynEq for T
where where
T: Any + Eq, T: Any + Eq,
{ {
fn as_any(&self) -> &dyn Any {
self
}
fn dyn_eq(&self, other: &dyn DynEq) -> bool { fn dyn_eq(&self, other: &dyn DynEq) -> bool {
if let Some(other) = other.as_any().downcast_ref::<T>() { if let Some(other) = (other as &dyn Any).downcast_ref::<T>() {
return self == other; return self == other;
} }
false false
@ -44,9 +37,6 @@ where
/// An object safe version of [`Hash`]. This trait is automatically implemented /// An object safe version of [`Hash`]. This trait is automatically implemented
/// for any `'static` type that implements `Hash`. /// for any `'static` type that implements `Hash`.
pub trait DynHash: DynEq { pub trait DynHash: DynEq {
/// Casts the type to `dyn Any`.
fn as_dyn_eq(&self) -> &dyn DynEq;
/// Feeds this value into the given [`Hasher`]. /// Feeds this value into the given [`Hasher`].
fn dyn_hash(&self, state: &mut dyn Hasher); fn dyn_hash(&self, state: &mut dyn Hasher);
} }
@ -58,10 +48,6 @@ impl<T> DynHash for T
where where
T: DynEq + Hash, T: DynEq + Hash,
{ {
fn as_dyn_eq(&self) -> &dyn DynEq {
self
}
fn dyn_hash(&self, mut state: &mut dyn Hasher) { fn dyn_hash(&self, mut state: &mut dyn Hasher) {
T::hash(self, &mut state); T::hash(self, &mut state);
self.type_id().hash(&mut state); self.type_id().hash(&mut state);
@ -120,7 +106,7 @@ macro_rules! define_label {
) => { ) => {
$(#[$label_attr])* $(#[$label_attr])*
pub trait $label_trait_name: 'static + Send + Sync + ::core::fmt::Debug { pub trait $label_trait_name: Send + Sync + ::core::fmt::Debug + $crate::label::DynEq + $crate::label::DynHash {
$($trait_extra_methods)* $($trait_extra_methods)*
@ -129,12 +115,6 @@ macro_rules! define_label {
///`. ///`.
fn dyn_clone(&self) -> $crate::label::Box<dyn $label_trait_name>; fn dyn_clone(&self) -> $crate::label::Box<dyn $label_trait_name>;
/// Casts this value to a form where it can be compared with other type-erased values.
fn as_dyn_eq(&self) -> &dyn $crate::label::DynEq;
/// Feeds this value into the given [`Hasher`].
fn dyn_hash(&self, state: &mut dyn ::core::hash::Hasher);
/// Returns an [`Interned`] value corresponding to `self`. /// Returns an [`Interned`] value corresponding to `self`.
fn intern(&self) -> $crate::intern::Interned<dyn $label_trait_name> fn intern(&self) -> $crate::intern::Interned<dyn $label_trait_name>
where Self: Sized { where Self: Sized {
@ -151,15 +131,6 @@ macro_rules! define_label {
(**self).dyn_clone() (**self).dyn_clone()
} }
/// Casts this value to a form where it can be compared with other type-erased values.
fn as_dyn_eq(&self) -> &dyn $crate::label::DynEq {
(**self).as_dyn_eq()
}
fn dyn_hash(&self, state: &mut dyn ::core::hash::Hasher) {
(**self).dyn_hash(state);
}
fn intern(&self) -> Self { fn intern(&self) -> Self {
*self *self
} }
@ -167,7 +138,7 @@ macro_rules! define_label {
impl PartialEq for dyn $label_trait_name { impl PartialEq for dyn $label_trait_name {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.as_dyn_eq().dyn_eq(other.as_dyn_eq()) self.dyn_eq(other)
} }
} }
@ -188,7 +159,7 @@ macro_rules! define_label {
use ::core::ptr; use ::core::ptr;
// Test that both the type id and pointer address are equivalent. // Test that both the type id and pointer address are equivalent.
self.as_dyn_eq().type_id() == other.as_dyn_eq().type_id() self.type_id() == other.type_id()
&& ptr::addr_eq(ptr::from_ref::<Self>(self), ptr::from_ref::<Self>(other)) && ptr::addr_eq(ptr::from_ref::<Self>(self), ptr::from_ref::<Self>(other))
} }
@ -196,7 +167,7 @@ macro_rules! define_label {
use ::core::{hash::Hash, ptr}; use ::core::{hash::Hash, ptr};
// Hash the type id... // Hash the type id...
self.as_dyn_eq().type_id().hash(state); self.type_id().hash(state);
// ...and the pointer address. // ...and the pointer address.
// Cast to a unit `()` first to discard any pointer metadata. // Cast to a unit `()` first to discard any pointer metadata.

View File

@ -147,15 +147,6 @@ impl<T> SystemSet for SystemTypeSet<T> {
fn dyn_clone(&self) -> Box<dyn SystemSet> { fn dyn_clone(&self) -> Box<dyn SystemSet> {
Box::new(*self) Box::new(*self)
} }
fn as_dyn_eq(&self) -> &dyn DynEq {
self
}
fn dyn_hash(&self, mut state: &mut dyn Hasher) {
TypeId::of::<Self>().hash(&mut state);
self.hash(&mut state);
}
} }
/// A [`SystemSet`] implicitly created when using /// A [`SystemSet`] implicitly created when using
@ -178,15 +169,6 @@ impl SystemSet for AnonymousSet {
fn dyn_clone(&self) -> Box<dyn SystemSet> { fn dyn_clone(&self) -> Box<dyn SystemSet> {
Box::new(*self) Box::new(*self)
} }
fn as_dyn_eq(&self) -> &dyn DynEq {
self
}
fn dyn_hash(&self, mut state: &mut dyn Hasher) {
TypeId::of::<Self>().hash(&mut state);
self.hash(&mut state);
}
} }
/// Types that can be converted into a [`SystemSet`]. /// Types that can be converted into a [`SystemSet`].

View File

@ -1675,7 +1675,7 @@ unsafe impl<'a> SystemParam for &'a Bundles {
/// Component change ticks that are more recent than `last_run` will be detected by the system. /// Component change ticks that are more recent than `last_run` will be detected by the system.
/// Those can be read by calling [`last_changed`](crate::change_detection::DetectChanges::last_changed) /// Those can be read by calling [`last_changed`](crate::change_detection::DetectChanges::last_changed)
/// on a [`Mut<T>`](crate::change_detection::Mut) or [`ResMut<T>`](ResMut). /// on a [`Mut<T>`](crate::change_detection::Mut) or [`ResMut<T>`](ResMut).
#[derive(Debug)] #[derive(Debug, Clone, Copy)]
pub struct SystemChangeTick { pub struct SystemChangeTick {
last_run: Tick, last_run: Tick,
this_run: Tick, this_run: Tick,
@ -2510,10 +2510,7 @@ impl DynSystemParamState {
} }
/// Allows a [`SystemParam::State`] to be used as a trait object for implementing [`DynSystemParam`]. /// Allows a [`SystemParam::State`] to be used as a trait object for implementing [`DynSystemParam`].
trait DynParamState: Sync + Send { trait DynParamState: Sync + Send + Any {
/// Casts the underlying `ParamState<T>` to an `Any` so it can be downcast.
fn as_any_mut(&mut self) -> &mut dyn Any;
/// For the specified [`Archetype`], registers the components accessed by this [`SystemParam`] (if applicable).a /// For the specified [`Archetype`], registers the components accessed by this [`SystemParam`] (if applicable).a
/// ///
/// # Safety /// # Safety
@ -2544,10 +2541,6 @@ trait DynParamState: Sync + Send {
struct ParamState<T: SystemParam>(T::State); struct ParamState<T: SystemParam>(T::State);
impl<T: SystemParam + 'static> DynParamState for ParamState<T> { impl<T: SystemParam + 'static> DynParamState for ParamState<T> {
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
unsafe fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta) { unsafe fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta) {
// SAFETY: The caller ensures that `archetype` is from the World the state was initialized from in `init_state`. // SAFETY: The caller ensures that `archetype` is from the World the state was initialized from in `init_state`.
unsafe { T::new_archetype(&mut self.0, archetype, system_meta) }; unsafe { T::new_archetype(&mut self.0, archetype, system_meta) };
@ -2597,18 +2590,11 @@ unsafe impl SystemParam for DynSystemParam<'_, '_> {
change_tick: Tick, change_tick: Tick,
) -> Self::Item<'world, 'state> { ) -> Self::Item<'world, 'state> {
// SAFETY: // SAFETY:
// - `state.0` is a boxed `ParamState<T>`, and its implementation of `as_any_mut` returns `self`. // - `state.0` is a boxed `ParamState<T>`.
// - The state was obtained from `SystemParamBuilder::build()`, which registers all [`World`] accesses used // - The state was obtained from `SystemParamBuilder::build()`, which registers all [`World`] accesses used
// by [`SystemParam::get_param`] with the provided [`system_meta`](SystemMeta). // by [`SystemParam::get_param`] with the provided [`system_meta`](SystemMeta).
// - The caller ensures that the provided world is the same and has the required access. // - The caller ensures that the provided world is the same and has the required access.
unsafe { unsafe { DynSystemParam::new(state.0.as_mut(), world, system_meta.clone(), change_tick) }
DynSystemParam::new(
state.0.as_any_mut(),
world,
system_meta.clone(),
change_tick,
)
}
} }
unsafe fn new_archetype( unsafe fn new_archetype(

View File

@ -58,7 +58,6 @@ pub fn derive_label(
input: syn::DeriveInput, input: syn::DeriveInput,
trait_name: &str, trait_name: &str,
trait_path: &syn::Path, trait_path: &syn::Path,
dyn_eq_path: &syn::Path,
) -> TokenStream { ) -> TokenStream {
if let syn::Data::Union(_) = &input.data { if let syn::Data::Union(_) = &input.data {
let message = format!("Cannot derive {trait_name} for unions."); let message = format!("Cannot derive {trait_name} for unions.");
@ -89,16 +88,6 @@ pub fn derive_label(
fn dyn_clone(&self) -> alloc::boxed::Box<dyn #trait_path> { fn dyn_clone(&self) -> alloc::boxed::Box<dyn #trait_path> {
alloc::boxed::Box::new(::core::clone::Clone::clone(self)) alloc::boxed::Box::new(::core::clone::Clone::clone(self))
} }
fn as_dyn_eq(&self) -> &dyn #dyn_eq_path {
self
}
fn dyn_hash(&self, mut state: &mut dyn ::core::hash::Hasher) {
let ty_id = ::core::any::TypeId::of::<Self>();
::core::hash::Hash::hash(&ty_id, &mut state);
::core::hash::Hash::hash(self, &mut state);
}
} }
}; };
} }

View File

@ -80,12 +80,10 @@ pub fn derive_render_label(input: TokenStream) -> TokenStream {
trait_path trait_path
.segments .segments
.push(format_ident!("render_graph").into()); .push(format_ident!("render_graph").into());
let mut dyn_eq_path = trait_path.clone();
trait_path trait_path
.segments .segments
.push(format_ident!("RenderLabel").into()); .push(format_ident!("RenderLabel").into());
dyn_eq_path.segments.push(format_ident!("DynEq").into()); derive_label(input, "RenderLabel", &trait_path)
derive_label(input, "RenderLabel", &trait_path, &dyn_eq_path)
} }
/// Derive macro generating an impl of the trait `RenderSubGraph`. /// Derive macro generating an impl of the trait `RenderSubGraph`.
@ -98,10 +96,8 @@ pub fn derive_render_sub_graph(input: TokenStream) -> TokenStream {
trait_path trait_path
.segments .segments
.push(format_ident!("render_graph").into()); .push(format_ident!("render_graph").into());
let mut dyn_eq_path = trait_path.clone();
trait_path trait_path
.segments .segments
.push(format_ident!("RenderSubGraph").into()); .push(format_ident!("RenderSubGraph").into());
dyn_eq_path.segments.push(format_ident!("DynEq").into()); derive_label(input, "RenderSubGraph", &trait_path)
derive_label(input, "RenderSubGraph", &trait_path, &dyn_eq_path)
} }

View File

@ -0,0 +1,8 @@
---
title: Interned labels cleanup
pull_requests: [18984]
---
- `DynEq::as_any` has been removed. Use `&value as &dyn Any` instead.
- `DynHash::as_dyn_eq` has been removed. Use `&value as &dyn DynEq` instead.
- `as_dyn_eq` has been removed from 'label' types such as `ScheduleLabel` and `SystemSet`. Call `DynEq::dyn_eq` directly on the label instead.