diff --git a/crates/bevy_a11y/Cargo.toml b/crates/bevy_a11y/Cargo.toml index 759cf3e7875c4..f5eaa290d4d4c 100644 --- a/crates/bevy_a11y/Cargo.toml +++ b/crates/bevy_a11y/Cargo.toml @@ -28,15 +28,11 @@ serialize = ["dep:serde", "bevy_ecs/serialize", "accesskit/serde"] ## Allows access to the `std` crate. Enabling this feature will prevent compilation ## on `no_std` targets, but provides access to certain additional features on ## supported platforms. -std = ["bevy_app/std", "bevy_ecs/std", "bevy_reflect/std"] +std = ["bevy_app/std", "bevy_ecs/std"] ## `critical-section` provides the building blocks for synchronization primitives ## on all platforms, including `no_std`. -critical-section = [ - "bevy_app/critical-section", - "bevy_ecs/critical-section", - "bevy_reflect?/critical-section", -] +critical-section = ["bevy_app/critical-section", "bevy_ecs/critical-section"] [dependencies] # bevy diff --git a/crates/bevy_app/Cargo.toml b/crates/bevy_app/Cargo.toml index f46db94db36bc..08483860d08d8 100644 --- a/crates/bevy_app/Cargo.toml +++ b/crates/bevy_app/Cargo.toml @@ -43,7 +43,6 @@ error_panic_hook = [] ## on `no_std` targets, but provides access to certain additional features on ## supported platforms. std = [ - "bevy_reflect?/std", "bevy_ecs/std", "dep:ctrlc", "downcast-rs/std", @@ -58,7 +57,6 @@ critical-section = [ "bevy_tasks/critical-section", "bevy_ecs/critical-section", "bevy_platform/critical-section", - "bevy_reflect?/critical-section", ] ## Enables use of browser APIs. @@ -66,7 +64,6 @@ critical-section = [ web = [ "bevy_platform/web", "bevy_tasks/web", - "bevy_reflect?/web", "dep:wasm-bindgen", "dep:web-sys", "dep:console_error_panic_hook", diff --git a/crates/bevy_asset/Cargo.toml b/crates/bevy_asset/Cargo.toml index 07a45a3f6d210..7b5727d97c96e 100644 --- a/crates/bevy_asset/Cargo.toml +++ b/crates/bevy_asset/Cargo.toml @@ -84,9 +84,6 @@ bevy_app = { path = "../bevy_app", version = "0.16.0-dev", default-features = fa bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, features = [ "web", ] } -bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-features = false, features = [ - "web", -] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] notify-debouncer-full = { version = "0.5.0", default-features = false, optional = true } diff --git a/crates/bevy_audio/Cargo.toml b/crates/bevy_audio/Cargo.toml index 84060fe26b484..f2b5b37ddce2a 100644 --- a/crates/bevy_audio/Cargo.toml +++ b/crates/bevy_audio/Cargo.toml @@ -33,9 +33,6 @@ rodio = { version = "0.20", default-features = false, features = [ bevy_app = { path = "../bevy_app", version = "0.16.0-dev", default-features = false, features = [ "web", ] } -bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-features = false, features = [ - "web", -] } [features] mp3 = ["rodio/mp3"] diff --git a/crates/bevy_color/Cargo.toml b/crates/bevy_color/Cargo.toml index 9b6d7d8cf6b8d..5c2737d770ca3 100644 --- a/crates/bevy_color/Cargo.toml +++ b/crates/bevy_color/Cargo.toml @@ -25,20 +25,14 @@ encase = { version = "0.10", default-features = false, optional = true } [features] default = ["std", "bevy_reflect", "encase"] -std = [ - "alloc", - "bevy_math/std", - "serde?/std", - "wgpu-types?/std", - "bevy_reflect?/std", -] +std = ["alloc", "bevy_math/std", "serde?/std", "wgpu-types?/std"] alloc = ["bevy_math/alloc", "serde?/alloc"] serialize = ["serde", "bevy_math/serialize"] bevy_reflect = ["dep:bevy_reflect"] wgpu-types = ["dep:wgpu-types"] encase = ["dep:encase", "std"] libm = ["bevy_math/libm"] -critical-section = ["bevy_reflect?/critical-section"] +critical-section = [] [lints] workspace = true diff --git a/crates/bevy_ecs/Cargo.toml b/crates/bevy_ecs/Cargo.toml index 97cdcee0824b7..a8ee97389102e 100644 --- a/crates/bevy_ecs/Cargo.toml +++ b/crates/bevy_ecs/Cargo.toml @@ -72,7 +72,6 @@ async_executor = ["std", "bevy_tasks/async_executor"] ## on `no_std` targets, but provides access to certain additional features on ## supported platforms. std = [ - "bevy_reflect?/std", "bevy_tasks/std", "bevy_utils/std", "bitflags/std", @@ -92,7 +91,6 @@ std = [ critical-section = [ "bevy_tasks/critical-section", "bevy_platform/critical-section", - "bevy_reflect?/critical-section", ] [dependencies] diff --git a/crates/bevy_input/Cargo.toml b/crates/bevy_input/Cargo.toml index 570273a00ac59..97adb0c17b315 100644 --- a/crates/bevy_input/Cargo.toml +++ b/crates/bevy_input/Cargo.toml @@ -43,7 +43,6 @@ std = [ "bevy_ecs/std", "bevy_math/std", "bevy_utils/std", - "bevy_reflect/std", "bevy_platform/std", ] @@ -52,7 +51,6 @@ std = [ critical-section = [ "bevy_app/critical-section", "bevy_ecs/critical-section", - "bevy_reflect?/critical-section", "bevy_platform/critical-section", ] diff --git a/crates/bevy_input_focus/Cargo.toml b/crates/bevy_input_focus/Cargo.toml index 0b2ca538307e7..1956eab2c3b66 100644 --- a/crates/bevy_input_focus/Cargo.toml +++ b/crates/bevy_input_focus/Cargo.toml @@ -41,7 +41,6 @@ std = [ "bevy_app/std", "bevy_ecs/std", "bevy_math/std", - "bevy_reflect/std", "bevy_input/std", "bevy_window/std", ] @@ -51,7 +50,6 @@ std = [ critical-section = [ "bevy_app/critical-section", "bevy_ecs/critical-section", - "bevy_reflect?/critical-section", "bevy_input/critical-section", ] diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index 28d234f2b4e3e..7918793d56f3a 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -295,7 +295,6 @@ std = [ "bevy_input_focus?/std", "bevy_math/std", "bevy_platform/std", - "bevy_reflect/std", "bevy_state?/std", "bevy_time/std", "bevy_transform/std", @@ -314,7 +313,6 @@ critical-section = [ "bevy_input/critical-section", "bevy_input_focus?/critical-section", "bevy_platform/critical-section", - "bevy_reflect/critical-section", "bevy_state?/critical-section", "bevy_time/critical-section", "bevy_utils/critical-section", @@ -342,12 +340,7 @@ async_executor = [ # Enables use of browser APIs. # Note this is currently only applicable on `wasm32` architectures. -web = [ - "bevy_app/web", - "bevy_platform/web", - "bevy_reflect/web", - "bevy_tasks/web", -] +web = ["bevy_app/web", "bevy_platform/web", "bevy_tasks/web"] [dependencies] # bevy (no_std) diff --git a/crates/bevy_math/Cargo.toml b/crates/bevy_math/Cargo.toml index 7aae1ec74be45..77c30737b5d38 100644 --- a/crates/bevy_math/Cargo.toml +++ b/crates/bevy_math/Cargo.toml @@ -50,7 +50,6 @@ std = [ "approx?/std", "rand?/std", "rand_distr?/std", - "bevy_reflect?/std", ] alloc = [ "itertools/use_alloc", diff --git a/crates/bevy_reflect/Cargo.toml b/crates/bevy_reflect/Cargo.toml index bb72226ab85a7..f3b51298e5255 100644 --- a/crates/bevy_reflect/Cargo.toml +++ b/crates/bevy_reflect/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["bevy"] rust-version = "1.85.0" [features] -default = ["std", "smallvec", "debug"] +default = ["smallvec", "debug"] # Features @@ -26,7 +26,7 @@ functions = ["bevy_reflect_derive/functions"] debug = ["debug_stack"] ## When enabled, keeps track of the current serialization/deserialization context for better error messages -debug_stack = ["std"] +debug_stack = ["bevy_platform/std"] # Integrations @@ -37,7 +37,7 @@ glam = ["dep:glam"] hashbrown = ["dep:hashbrown"] ## Adds reflection support to `petgraph` types. -petgraph = ["dep:petgraph", "std"] +petgraph = ["dep:petgraph"] ## Adds reflection support to `smallvec` types. smallvec = ["dep:smallvec"] @@ -48,33 +48,8 @@ uuid = ["dep:uuid"] ## Adds reflection support to `wgpu-types` types. wgpu-types = ["dep:wgpu-types"] -# Platform Compatibility - -## Allows access to the `std` crate. Enabling this feature will prevent compilation -## on `no_std` targets, but provides access to certain additional features on -## supported platforms. -std = [ - "bevy_utils/std", - "erased-serde/std", - "downcast-rs/std", - "serde/std", - "glam?/std", - "smol_str?/std", - "uuid?/std", - "bevy_platform/std", - "wgpu-types?/std", -] - -## `critical-section` provides the building blocks for synchronization primitives -## on all platforms, including `no_std`. -critical-section = [ - "bevy_platform/critical-section", - "bevy_utils/critical-section", -] - -## Enables use of browser APIs. -## Note this is currently only applicable on `wasm32` architectures. -web = ["bevy_platform/web", "uuid?/js"] +## Adds reflection support to `smol_str` types. +smol_str = ["dep:smol_str"] [dependencies] # bevy @@ -105,13 +80,15 @@ assert_type_match = "0.1.1" smallvec = { version = "1.11", default-features = false, optional = true } glam = { version = "0.29.3", default-features = false, features = [ "serde", + "nostd-libm", ], optional = true } -petgraph = { version = "0.7", features = ["serde-1"], optional = true } +petgraph = { version = "0.7", features = [ + "serde-1", +], default-features = false, optional = true } smol_str = { version = "0.2.0", default-features = false, features = [ "serde", ], optional = true } uuid = { version = "1.13.1", default-features = false, optional = true, features = [ - "v4", "serde", ] } variadics_please = "1.1" diff --git a/crates/bevy_reflect/src/impls/smallvec.rs b/crates/bevy_reflect/src/impls/smallvec.rs index 942bcbe83f17c..7386a648f2ab9 100644 --- a/crates/bevy_reflect/src/impls/smallvec.rs +++ b/crates/bevy_reflect/src/impls/smallvec.rs @@ -234,5 +234,4 @@ where } } -#[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(SmallVec; where T::Item: FromReflect + MaybeTyped + TypePath); +crate::impls::maybe_impl_functions_traits!(SmallVec; where T::Item: FromReflect + MaybeTyped + TypePath); diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 6a752d187775e..13379fa3936cc 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -31,9 +31,6 @@ use core::{ panic::Location, }; -#[cfg(feature = "std")] -use std::path::Path; - impl_reflect_opaque!(bool( Clone, Debug, @@ -186,16 +183,6 @@ impl_reflect_opaque!(::alloc::string::String( Deserialize, Default )); -#[cfg(feature = "std")] -impl_reflect_opaque!(::std::path::PathBuf( - Clone, - Debug, - Hash, - PartialEq, - Serialize, - Deserialize, - Default -)); impl_reflect_opaque!(::core::any::TypeId(Clone, Debug, Hash, PartialEq,)); impl_reflect_opaque!(::alloc::collections::BTreeSet(Clone)); impl_reflect_opaque!(::core::ops::Range(Clone)); @@ -317,19 +304,6 @@ impl_reflect_opaque!(::core::num::Wrapping(Clone)); impl_reflect_opaque!(::core::num::Saturating(Clone)); impl_reflect_opaque!(::bevy_platform::sync::Arc(Clone)); -// `Serialize` and `Deserialize` only for platforms supported by serde: -// https://github.com/serde-rs/serde/blob/3ffb86fc70efd3d329519e2dddfa306cc04f167c/serde/src/de/impls.rs#L1732 -#[cfg(all(any(unix, windows), feature = "std"))] -impl_reflect_opaque!(::std::ffi::OsString( - Clone, - Debug, - Hash, - PartialEq, - Serialize, - Deserialize -)); -#[cfg(all(not(any(unix, windows)), feature = "std"))] -impl_reflect_opaque!(::std::ffi::OsString(Clone, Debug, Hash, PartialEq)); impl_reflect_opaque!(::alloc::collections::BinaryHeap(Clone)); macro_rules! impl_reflect_for_atomic { @@ -337,8 +311,7 @@ macro_rules! impl_reflect_for_atomic { impl_type_path!($ty); const _: () = { - #[cfg(feature = "functions")] - crate::func::macros::impl_function_traits!($ty); + crate::impls::maybe_impl_functions_traits!($ty); impl GetTypeRegistration for $ty where @@ -351,8 +324,7 @@ macro_rules! impl_reflect_for_atomic { registration.insert::(FromType::::from_type()); // Serde only supports atomic types when the "std" feature is enabled - #[cfg(feature = "std")] - { + crate::cfg::std! { registration.insert::(FromType::::from_type()); registration.insert::(FromType::::from_type()); } @@ -701,8 +673,6 @@ macro_rules! impl_reflect_for_veclike { impl_reflect_for_veclike!(Vec, Vec::insert, Vec::remove, Vec::push, Vec::pop, [T]); impl_type_path!(::alloc::vec::Vec); -#[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(Vec; ); impl_reflect_for_veclike!( VecDeque, @@ -713,8 +683,6 @@ impl_reflect_for_veclike!( VecDeque:: ); impl_type_path!(::alloc::collections::VecDeque); -#[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(VecDeque; ); macro_rules! impl_reflect_for_hashmap { ($ty:path) => { @@ -974,45 +942,10 @@ macro_rules! impl_reflect_for_hashmap { }; } -#[cfg(feature = "std")] -impl_reflect_for_hashmap!(::std::collections::HashMap); impl_type_path!(::core::hash::BuildHasherDefault); -#[cfg(feature = "std")] -impl_type_path!(::std::collections::hash_map::RandomState); -#[cfg(feature = "std")] -impl_type_path!(::std::collections::HashMap); -#[cfg(all(feature = "functions", feature = "std"))] -crate::func::macros::impl_function_traits!(::std::collections::HashMap; - < - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, - S: TypePath + BuildHasher + Default + Send + Sync - > -); impl_reflect_for_hashmap!(bevy_platform::collections::HashMap); impl_type_path!(::bevy_platform::collections::HashMap); -#[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(::bevy_platform::collections::HashMap; - < - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, - S: TypePath + BuildHasher + Default + Send + Sync - > -); - -#[cfg(feature = "hashbrown")] -impl_reflect_for_hashmap!(hashbrown::hash_map::HashMap); -#[cfg(feature = "hashbrown")] -impl_type_path!(::hashbrown::hash_map::HashMap); -#[cfg(all(feature = "functions", feature = "hashbrown"))] -crate::func::macros::impl_function_traits!(::hashbrown::hash_map::HashMap; - < - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, - S: TypePath + BuildHasher + Default + Send + Sync - > -); macro_rules! impl_reflect_for_hashset { ($ty:path) => { @@ -1231,39 +1164,8 @@ impl_reflect_opaque!(::core::net::SocketAddr( Deserialize )); -#[cfg(feature = "std")] -impl_reflect_for_hashset!(::std::collections::HashSet); -#[cfg(feature = "std")] -impl_type_path!(::std::collections::HashSet); -#[cfg(all(feature = "functions", feature = "std"))] -crate::func::macros::impl_function_traits!(::std::collections::HashSet; - < - V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, - S: TypePath + BuildHasher + Default + Send + Sync - > -); - impl_reflect_for_hashset!(::bevy_platform::collections::HashSet); impl_type_path!(::bevy_platform::collections::HashSet); -#[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(::bevy_platform::collections::HashSet; - < - V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, - S: TypePath + BuildHasher + Default + Send + Sync - > -); - -#[cfg(feature = "hashbrown")] -impl_reflect_for_hashset!(::hashbrown::hash_set::HashSet); -#[cfg(feature = "hashbrown")] -impl_type_path!(::hashbrown::hash_set::HashSet); -#[cfg(all(feature = "functions", feature = "hashbrown"))] -crate::func::macros::impl_function_traits!(::hashbrown::hash_set::HashSet; - < - V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, - S: TypePath + BuildHasher + Default + Send + Sync - > -); impl Map for ::alloc::collections::BTreeMap where @@ -1511,13 +1413,6 @@ where } impl_type_path!(::alloc::collections::BTreeMap); -#[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(::alloc::collections::BTreeMap; - < - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration - > -); impl Array for [T; N] { #[inline] @@ -1705,9 +1600,6 @@ impl G } } -#[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!([T; N]; [const N: usize]); - impl_reflect! { #[type_path = "core::option"] enum Option { @@ -1857,9 +1749,6 @@ impl FromReflect for Cow<'static, str> { } } -#[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(Cow<'static, str>); - impl TypePath for [T] where [T]: ToOwned, @@ -2046,9 +1935,6 @@ impl FromR } } -#[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(Cow<'static, [T]>; ); - impl PartialReflect for &'static str { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) @@ -2180,11 +2066,19 @@ impl FromReflect for &'static str { } } -#[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(&'static str); +impl_type_path!(::alloc::borrow::Cow<'a: 'static, T: ToOwned + ?Sized>); + +impl TypePath for &'static Location<'static> { + fn type_path() -> &'static str { + "core::panic::Location" + } -#[cfg(feature = "std")] -impl PartialReflect for &'static Path { + fn short_type_path() -> &'static str { + "Location" + } +} + +impl PartialReflect for &'static Location<'static> { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) } @@ -2262,8 +2156,7 @@ impl PartialReflect for &'static Path { } } -#[cfg(feature = "std")] -impl Reflect for &'static Path { +impl Reflect for &'static Location<'static> { fn into_any(self: Box) -> Box { self } @@ -2294,16 +2187,14 @@ impl Reflect for &'static Path { } } -#[cfg(feature = "std")] -impl Typed for &'static Path { +impl Typed for &'static Location<'static> { fn type_info() -> &'static TypeInfo { static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::())) } } -#[cfg(feature = "std")] -impl GetTypeRegistration for &'static Path { +impl GetTypeRegistration for &'static Location<'static> { fn get_type_registration() -> TypeRegistration { let mut registration = TypeRegistration::of::(); registration.insert::(FromType::::from_type()); @@ -2312,308 +2203,398 @@ impl GetTypeRegistration for &'static Path { } } -#[cfg(feature = "std")] -impl FromReflect for &'static Path { +impl FromReflect for &'static Location<'static> { fn from_reflect(reflect: &dyn PartialReflect) -> Option { reflect.try_downcast_ref::().copied() } } -#[cfg(all(feature = "functions", feature = "std"))] -crate::func::macros::impl_function_traits!(&'static Path); +crate::impls::maybe_impl_functions_traits!(Vec; ); -#[cfg(feature = "std")] -impl PartialReflect for Cow<'static, Path> { - fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { - Some(::type_info()) - } +crate::impls::maybe_impl_functions_traits!(VecDeque; ); - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } +crate::impls::maybe_impl_functions_traits!(::bevy_platform::collections::HashMap; + < + K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + S: TypePath + BuildHasher + Default + Send + Sync + > +); - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } +crate::impls::maybe_impl_functions_traits!(::bevy_platform::collections::HashSet; + < + V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, + S: TypePath + BuildHasher + Default + Send + Sync + > +); - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } +crate::impls::maybe_impl_functions_traits!(::alloc::collections::BTreeMap; + < + K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, + V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + > +); - fn try_into_reflect(self: Box) -> Result, Box> { - Ok(self) - } +crate::impls::maybe_impl_functions_traits!([T; N]; [const N: usize]); - fn try_as_reflect(&self) -> Option<&dyn Reflect> { - Some(self) - } +crate::impls::maybe_impl_functions_traits!(Cow<'static, str>); - fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> { - Some(self) - } +crate::impls::maybe_impl_functions_traits!(Cow<'static, [T]>; ); - fn reflect_kind(&self) -> ReflectKind { - ReflectKind::Opaque - } +crate::impls::maybe_impl_functions_traits!(&'static str); - fn reflect_ref(&self) -> ReflectRef { - ReflectRef::Opaque(self) - } +crate::cfg::std! { + use std::path::Path; - fn reflect_mut(&mut self) -> ReflectMut { - ReflectMut::Opaque(self) + impl_reflect_opaque!(::std::path::PathBuf( + Clone, + Debug, + Hash, + PartialEq, + Serialize, + Deserialize, + Default + )); + + // `Serialize` and `Deserialize` only for platforms supported by serde: + // https://github.com/serde-rs/serde/blob/3ffb86fc70efd3d329519e2dddfa306cc04f167c/serde/src/de/impls.rs#L1732 + crate::cfg::switch! { + #[cfg(any(unix, windows))] => { + impl_reflect_opaque!(::std::ffi::OsString( + Clone, + Debug, + Hash, + PartialEq, + Serialize, + Deserialize + )); + } + _ => { + impl_reflect_opaque!(::std::ffi::OsString(Clone, Debug, Hash, PartialEq)); + } } - fn reflect_owned(self: Box) -> ReflectOwned { - ReflectOwned::Opaque(self) - } + impl_reflect_for_hashmap!(::std::collections::HashMap); + impl_type_path!(::std::collections::hash_map::RandomState); + impl_type_path!(::std::collections::HashMap); - fn reflect_clone(&self) -> Result, ReflectCloneError> { - Ok(Box::new(self.clone())) - } + impl_reflect_for_hashset!(::std::collections::HashSet); + impl_type_path!(::std::collections::HashSet); - fn reflect_hash(&self) -> Option { - let mut hasher = reflect_hasher(); - Hash::hash(&Any::type_id(self), &mut hasher); - Hash::hash(self, &mut hasher); - Some(hasher.finish()) - } + impl PartialReflect for &'static Path { + fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { + Some(::type_info()) + } - fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option { - if let Some(value) = value.try_downcast_ref::() { - Some(PartialEq::eq(self, value)) - } else { - Some(false) + #[inline] + fn into_partial_reflect(self: Box) -> Box { + self } - } - fn debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self, f) - } + fn as_partial_reflect(&self) -> &dyn PartialReflect { + self + } - fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> { - if let Some(value) = value.try_downcast_ref::() { - self.clone_from(value); - Ok(()) - } else { - Err(ApplyError::MismatchedTypes { - from_type: value.reflect_type_path().into(), - to_type: ::reflect_type_path(self).into(), - }) + fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { + self } - } -} -#[cfg(feature = "std")] -impl Reflect for Cow<'static, Path> { - fn into_any(self: Box) -> Box { - self - } + fn try_into_reflect(self: Box) -> Result, Box> { + Ok(self) + } - fn as_any(&self) -> &dyn Any { - self - } + fn try_as_reflect(&self) -> Option<&dyn Reflect> { + Some(self) + } - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } + fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> { + Some(self) + } - fn into_reflect(self: Box) -> Box { - self - } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Opaque + } - fn as_reflect(&self) -> &dyn Reflect { - self - } + fn reflect_ref(&self) -> ReflectRef { + ReflectRef::Opaque(self) + } - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } + fn reflect_mut(&mut self) -> ReflectMut { + ReflectMut::Opaque(self) + } - fn set(&mut self, value: Box) -> Result<(), Box> { - *self = value.take()?; - Ok(()) - } -} + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Opaque(self) + } -#[cfg(feature = "std")] -impl Typed for Cow<'static, Path> { - fn type_info() -> &'static TypeInfo { - static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); - CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::())) - } -} + fn reflect_clone(&self) -> Result, ReflectCloneError> { + Ok(Box::new(*self)) + } -#[cfg(feature = "std")] -impl_type_path!(::std::path::Path); -impl_type_path!(::alloc::borrow::Cow<'a: 'static, T: ToOwned + ?Sized>); + fn reflect_hash(&self) -> Option { + let mut hasher = reflect_hasher(); + Hash::hash(&Any::type_id(self), &mut hasher); + Hash::hash(self, &mut hasher); + Some(hasher.finish()) + } -#[cfg(feature = "std")] -impl FromReflect for Cow<'static, Path> { - fn from_reflect(reflect: &dyn PartialReflect) -> Option { - Some(reflect.try_downcast_ref::()?.clone()) - } -} + fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option { + if let Some(value) = value.try_downcast_ref::() { + Some(PartialEq::eq(self, value)) + } else { + Some(false) + } + } -#[cfg(feature = "std")] -impl GetTypeRegistration for Cow<'static, Path> { - fn get_type_registration() -> TypeRegistration { - let mut registration = TypeRegistration::of::(); - registration.insert::(FromType::::from_type()); - registration.insert::(FromType::::from_type()); - registration.insert::(FromType::::from_type()); - registration.insert::(FromType::::from_type()); - registration + fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> { + if let Some(value) = value.try_downcast_ref::() { + self.clone_from(value); + Ok(()) + } else { + Err(ApplyError::MismatchedTypes { + from_type: value.reflect_type_path().into(), + to_type: ::reflect_type_path(self).into(), + }) + } + } } -} -#[cfg(all(feature = "functions", feature = "std"))] -crate::func::macros::impl_function_traits!(Cow<'static, Path>); + impl Reflect for &'static Path { + fn into_any(self: Box) -> Box { + self + } -impl TypePath for &'static Location<'static> { - fn type_path() -> &'static str { - "core::panic::Location" - } + fn as_any(&self) -> &dyn Any { + self + } - fn short_type_path() -> &'static str { - "Location" - } -} + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } -impl PartialReflect for &'static Location<'static> { - fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { - Some(::type_info()) - } + fn into_reflect(self: Box) -> Box { + self + } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } + fn as_reflect(&self) -> &dyn Reflect { + self + } - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } + fn as_reflect_mut(&mut self) -> &mut dyn Reflect { + self + } - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self + fn set(&mut self, value: Box) -> Result<(), Box> { + *self = value.take()?; + Ok(()) + } } - fn try_into_reflect(self: Box) -> Result, Box> { - Ok(self) + impl Typed for &'static Path { + fn type_info() -> &'static TypeInfo { + static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); + CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::())) + } } - fn try_as_reflect(&self) -> Option<&dyn Reflect> { - Some(self) + impl GetTypeRegistration for &'static Path { + fn get_type_registration() -> TypeRegistration { + let mut registration = TypeRegistration::of::(); + registration.insert::(FromType::::from_type()); + registration.insert::(FromType::::from_type()); + registration + } } - fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> { - Some(self) + impl FromReflect for &'static Path { + fn from_reflect(reflect: &dyn PartialReflect) -> Option { + reflect.try_downcast_ref::().copied() + } } - fn reflect_kind(&self) -> ReflectKind { - ReflectKind::Opaque - } + impl PartialReflect for Cow<'static, Path> { + fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { + Some(::type_info()) + } - fn reflect_ref(&self) -> ReflectRef { - ReflectRef::Opaque(self) - } + #[inline] + fn into_partial_reflect(self: Box) -> Box { + self + } - fn reflect_mut(&mut self) -> ReflectMut { - ReflectMut::Opaque(self) - } + fn as_partial_reflect(&self) -> &dyn PartialReflect { + self + } - fn reflect_owned(self: Box) -> ReflectOwned { - ReflectOwned::Opaque(self) - } + fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { + self + } - fn reflect_clone(&self) -> Result, ReflectCloneError> { - Ok(Box::new(*self)) - } + fn try_into_reflect(self: Box) -> Result, Box> { + Ok(self) + } - fn reflect_hash(&self) -> Option { - let mut hasher = reflect_hasher(); - Hash::hash(&Any::type_id(self), &mut hasher); - Hash::hash(self, &mut hasher); - Some(hasher.finish()) - } + fn try_as_reflect(&self) -> Option<&dyn Reflect> { + Some(self) + } - fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option { - if let Some(value) = value.try_downcast_ref::() { - Some(PartialEq::eq(self, value)) - } else { - Some(false) + fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> { + Some(self) + } + + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Opaque + } + + fn reflect_ref(&self) -> ReflectRef { + ReflectRef::Opaque(self) + } + + fn reflect_mut(&mut self) -> ReflectMut { + ReflectMut::Opaque(self) + } + + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Opaque(self) + } + + fn reflect_clone(&self) -> Result, ReflectCloneError> { + Ok(Box::new(self.clone())) + } + + fn reflect_hash(&self) -> Option { + let mut hasher = reflect_hasher(); + Hash::hash(&Any::type_id(self), &mut hasher); + Hash::hash(self, &mut hasher); + Some(hasher.finish()) + } + + fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option { + if let Some(value) = value.try_downcast_ref::() { + Some(PartialEq::eq(self, value)) + } else { + Some(false) + } + } + + fn debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self, f) + } + + fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> { + if let Some(value) = value.try_downcast_ref::() { + self.clone_from(value); + Ok(()) + } else { + Err(ApplyError::MismatchedTypes { + from_type: value.reflect_type_path().into(), + to_type: ::reflect_type_path(self).into(), + }) + } } } - fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> { - if let Some(value) = value.try_downcast_ref::() { - self.clone_from(value); + impl Reflect for Cow<'static, Path> { + fn into_any(self: Box) -> Box { + self + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn into_reflect(self: Box) -> Box { + self + } + + fn as_reflect(&self) -> &dyn Reflect { + self + } + + fn as_reflect_mut(&mut self) -> &mut dyn Reflect { + self + } + + fn set(&mut self, value: Box) -> Result<(), Box> { + *self = value.take()?; Ok(()) - } else { - Err(ApplyError::MismatchedTypes { - from_type: value.reflect_type_path().into(), - to_type: ::reflect_type_path(self).into(), - }) } } -} -impl Reflect for &'static Location<'static> { - fn into_any(self: Box) -> Box { - self + impl Typed for Cow<'static, Path> { + fn type_info() -> &'static TypeInfo { + static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); + CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::())) + } } - fn as_any(&self) -> &dyn Any { - self - } + impl_type_path!(::std::path::Path); - fn as_any_mut(&mut self) -> &mut dyn Any { - self + impl FromReflect for Cow<'static, Path> { + fn from_reflect(reflect: &dyn PartialReflect) -> Option { + Some(reflect.try_downcast_ref::()?.clone()) + } } - fn into_reflect(self: Box) -> Box { - self + impl GetTypeRegistration for Cow<'static, Path> { + fn get_type_registration() -> TypeRegistration { + let mut registration = TypeRegistration::of::(); + registration.insert::(FromType::::from_type()); + registration.insert::(FromType::::from_type()); + registration.insert::(FromType::::from_type()); + registration.insert::(FromType::::from_type()); + registration + } } - fn as_reflect(&self) -> &dyn Reflect { - self - } + crate::impls::maybe_impl_functions_traits!(::std::collections::HashMap; + < + K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + S: TypePath + BuildHasher + Default + Send + Sync + > + ); - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } + crate::impls::maybe_impl_functions_traits!(::std::collections::HashSet; + < + V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, + S: TypePath + BuildHasher + Default + Send + Sync + > + ); - fn set(&mut self, value: Box) -> Result<(), Box> { - *self = value.take()?; - Ok(()) - } -} + crate::impls::maybe_impl_functions_traits!(&'static Path); -impl Typed for &'static Location<'static> { - fn type_info() -> &'static TypeInfo { - static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); - CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::())) - } -} + crate::impls::maybe_impl_functions_traits!(Cow<'static, Path>); -impl GetTypeRegistration for &'static Location<'static> { - fn get_type_registration() -> TypeRegistration { - let mut registration = TypeRegistration::of::(); - registration.insert::(FromType::::from_type()); - registration.insert::(FromType::::from_type()); - registration - } + crate::impls::maybe_impl_functions_traits!(&'static Location<'static>); } -impl FromReflect for &'static Location<'static> { - fn from_reflect(reflect: &dyn PartialReflect) -> Option { - reflect.try_downcast_ref::().copied() - } -} +crate::cfg::hashbrown! { + impl_reflect_for_hashmap!(hashbrown::hash_map::HashMap); + impl_type_path!(::hashbrown::hash_map::HashMap); -#[cfg(all(feature = "functions", feature = "std"))] -crate::func::macros::impl_function_traits!(&'static Location<'static>); + impl_reflect_for_hashset!(::hashbrown::hash_set::HashSet); + impl_type_path!(::hashbrown::hash_set::HashSet); + + crate::impls::maybe_impl_functions_traits!(::hashbrown::hash_map::HashMap; + < + K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + S: TypePath + BuildHasher + Default + Send + Sync + > + ); + + crate::impls::maybe_impl_functions_traits!(::hashbrown::hash_set::HashSet; + < + V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, + S: TypePath + BuildHasher + Default + Send + Sync + > + ); +} #[cfg(test)] mod tests { @@ -2880,9 +2861,10 @@ mod tests { assert_impl_all!(std::collections::HashMap: Reflect); assert_impl_all!(bevy_platform::collections::HashMap: Reflect); - // We specify `foldhash::fast::RandomState` directly here since without the `default-hasher` - // feature, hashbrown uses an empty enum to force users to specify their own - #[cfg(feature = "hashbrown")] - assert_impl_all!(hashbrown::HashMap: Reflect); + crate::cfg::hashbrown! { + // We specify `foldhash::fast::RandomState` directly here since without the `default-hasher` + // feature, hashbrown uses an empty enum to force users to specify their own + assert_impl_all!(hashbrown::HashMap: Reflect); + } } } diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 58e9b8714f0e1..a03690caffbbe 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -559,8 +559,73 @@ #![no_std] -#[cfg(feature = "std")] -extern crate std; +/// Configuration information for this crate. +pub mod cfg { + pub(crate) use bevy_platform::cfg::*; + + pub use bevy_platform::cfg::std; + + define_alias! { + #[cfg(feature = "documentation")] => { + /// When enabled, allows documentation comments to be accessed via reflection + documentation + } + + #[cfg(feature = "functions")] => { + /// Enables function reflection + functions + } + + #[cfg(feature = "debug")] => { + /// Enables features useful for debugging reflection + debug + } + + #[cfg(feature = "debug_stack")] => { + /// When enabled, keeps track of the current serialization/deserialization context for better error messages + debug_stack + } + + #[cfg(feature = "glam")] => { + /// Adds reflection support to `glam` types. + glam + } + + #[cfg(feature = "hashbrown")] => { + /// Adds reflection support to `hashbrown` types. + hashbrown + } + + #[cfg(feature = "petgraph")] => { + /// Adds reflection support to `petgraph` types. + petgraph + } + + #[cfg(feature = "smallvec")] => { + /// Adds reflection support to `smallvec` types. + smallvec + } + + #[cfg(feature = "uuid")] => { + /// Adds reflection support to `uuid` types. + uuid + } + + #[cfg(feature = "wgpu-types")] => { + /// Adds reflection support to `wgpu-types` types. + wgpu_types + } + + #[cfg(feature = "smol_str")] => { + /// Adds reflection support to `smol_str` types. + smol_str + } + } +} + +cfg::std! { + extern crate std; +} extern crate alloc; @@ -589,21 +654,42 @@ mod type_path; mod type_registry; mod impls { + // This simplifies implementations by consolidating conditional compilation. + crate::cfg::switch! { + crate::cfg::functions => { + use crate::func::macros::impl_function_traits as maybe_impl_functions_traits; + } + _ => { + use bevy_platform::cfg::disabled as maybe_impl_functions_traits; + } + } + mod foldhash; mod std; - #[cfg(feature = "glam")] - mod glam; - #[cfg(feature = "petgraph")] - mod petgraph; - #[cfg(feature = "smallvec")] - mod smallvec; - #[cfg(feature = "smol_str")] - mod smol_str; - #[cfg(feature = "uuid")] - mod uuid; - #[cfg(feature = "wgpu-types")] - mod wgpu_types; + crate::cfg::glam! { + mod glam; + } + + crate::cfg::petgraph! { + mod petgraph; + } + + crate::cfg::smallvec! { + mod smallvec; + } + + crate::cfg::smol_str! { + mod smol_str; + } + + crate::cfg::uuid! { + mod uuid; + } + + crate::cfg::wgpu_types! { + mod wgpu_types; + } } pub mod attributes; @@ -2138,8 +2224,7 @@ mod tests { assert!(info.is::()); // List (SmallVec) - #[cfg(feature = "smallvec")] - { + crate::cfg::smallvec! { type MySmallVec = smallvec::SmallVec<[String; 2]>; let info = MySmallVec::type_info().as_list().unwrap(); @@ -2153,7 +2238,7 @@ mod tests { let value: &dyn Reflect = &value; let info = value.reflect_type_info(); assert!(info.is::()); - } + }; // Array type MyArray = [usize; 3]; @@ -2299,10 +2384,7 @@ mod tests { dynamic_array.set_represented_type(Some(type_info)); } - #[cfg(feature = "documentation")] - mod docstrings { - use super::*; - + crate::cfg::documentation! { #[test] fn should_not_contain_docs() { // Regular comments do not count as doc comments, @@ -3359,9 +3441,7 @@ bevy_reflect::tests::Test { ); } - #[cfg(feature = "glam")] - mod glam { - use super::*; + crate::cfg::glam! { use ::glam::{quat, vec3, Quat, Vec3}; #[test] diff --git a/crates/bevy_reflect/src/serde/de/error_utils.rs b/crates/bevy_reflect/src/serde/de/error_utils.rs index d570c47f0c369..0bc464baf990c 100644 --- a/crates/bevy_reflect/src/serde/de/error_utils.rs +++ b/crates/bevy_reflect/src/serde/de/error_utils.rs @@ -1,17 +1,17 @@ use core::fmt::Display; use serde::de::Error; -#[cfg(feature = "debug_stack")] -use std::thread_local; +crate::cfg::debug_stack! { + use std::thread_local; -#[cfg(feature = "debug_stack")] -thread_local! { - /// The thread-local [`TypeInfoStack`] used for debugging. - /// - /// [`TypeInfoStack`]: crate::type_info_stack::TypeInfoStack - pub(super) static TYPE_INFO_STACK: core::cell::RefCell = const { core::cell::RefCell::new( - crate::type_info_stack::TypeInfoStack::new() - ) }; + thread_local! { + /// The thread-local [`TypeInfoStack`] used for debugging. + /// + /// [`TypeInfoStack`]: crate::type_info_stack::TypeInfoStack + pub(super) static TYPE_INFO_STACK: core::cell::RefCell = const { core::cell::RefCell::new( + crate::type_info_stack::TypeInfoStack::new() + ) }; + } } /// A helper function for generating a custom deserialization error message. @@ -21,9 +21,12 @@ thread_local! { /// /// [type info stack]: crate::type_info_stack::TypeInfoStack pub(super) fn make_custom_error(msg: impl Display) -> E { - #[cfg(feature = "debug_stack")] - return TYPE_INFO_STACK - .with_borrow(|stack| E::custom(format_args!("{} (stack: {:?})", msg, stack))); - #[cfg(not(feature = "debug_stack"))] - return E::custom(msg); + crate::cfg::switch! { + crate::cfg::debug_stack => { + TYPE_INFO_STACK.with_borrow(|stack| E::custom(format_args!("{} (stack: {:?})", msg, stack))) + } + _ => { + E::custom(msg) + } + } } diff --git a/crates/bevy_reflect/src/serde/de/mod.rs b/crates/bevy_reflect/src/serde/de/mod.rs index e82b60bcee5c8..2a8c9a1537b40 100644 --- a/crates/bevy_reflect/src/serde/de/mod.rs +++ b/crates/bevy_reflect/src/serde/de/mod.rs @@ -519,10 +519,17 @@ mod tests { let error = reflect_deserializer .deserialize(&mut deserializer) .unwrap_err(); - #[cfg(feature = "debug_stack")] - assert_eq!(error, ron::Error::Message("type `core::ops::RangeInclusive` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data` (stack: `core::ops::RangeInclusive`)".to_string())); - #[cfg(not(feature = "debug_stack"))] - assert_eq!(error, ron::Error::Message("type `core::ops::RangeInclusive` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string())); + + let expected_error = crate::cfg::switch! {{ + crate::cfg::debug_stack => { + "type `core::ops::RangeInclusive` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data` (stack: `core::ops::RangeInclusive`)" + } + _ => { + "type `core::ops::RangeInclusive` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data`" + } + }}; + + assert_eq!(error, ron::Error::Message(expected_error.to_string())); } #[test] @@ -664,16 +671,16 @@ mod tests { .deserialize(&mut deserializer) .unwrap_err(); - #[cfg(feature = "debug_stack")] - assert_eq!( - error, - ron::Error::Message("my custom deserialize error (stack: `i32`)".to_string()) - ); - #[cfg(not(feature = "debug_stack"))] - assert_eq!( - error, - ron::Error::Message("my custom deserialize error".to_string()) - ); + let expected_error = crate::cfg::switch! {{ + crate::cfg::debug_stack => { + "my custom deserialize error (stack: `i32`)" + } + _ => { + "my custom deserialize error" + } + }}; + + assert_eq!(error, ron::Error::Message(expected_error.to_string())); } #[test] @@ -762,13 +769,11 @@ mod tests { assert!(::from_reflect(dynamic_output.as_partial_reflect()).is_none()); } - #[cfg(feature = "functions")] - mod functions { - use super::*; - use crate::func::DynamicFunction; - + crate::cfg::functions! { #[test] fn should_not_deserialize_function() { + use crate::func::DynamicFunction; + #[derive(Reflect)] #[reflect(from_reflect = false)] struct MyStruct { @@ -779,7 +784,7 @@ mod tests { registry.register::(); let input = r#"{ - "bevy_reflect::serde::de::tests::functions::MyStruct": ( + "bevy_reflect::serde::de::tests::MyStruct": ( func: (), ), }"#; @@ -791,29 +796,20 @@ mod tests { .deserialize(&mut ron_deserializer) .unwrap_err(); - #[cfg(feature = "debug_stack")] - assert_eq!( - error, - ron::Error::Message( - "no registration found for type `bevy_reflect::DynamicFunction` (stack: `bevy_reflect::serde::de::tests::functions::MyStruct`)" - .to_string() - ) - ); + let expected_error = crate::cfg::switch! {{ + crate::cfg::debug_stack => { + "no registration found for type `bevy_reflect::DynamicFunction` (stack: `bevy_reflect::serde::de::tests::MyStruct`)" + } + _ => { + "no registration found for type `bevy_reflect::DynamicFunction`" + } + }}; - #[cfg(not(feature = "debug_stack"))] - assert_eq!( - error, - ron::Error::Message( - "no registration found for type `bevy_reflect::DynamicFunction`".to_string() - ) - ); + assert_eq!(error, ron::Error::Message(expected_error.to_string())); } } - #[cfg(feature = "debug_stack")] - mod debug_stack { - use super::*; - + crate::cfg::debug_stack! { #[test] fn should_report_context_in_errors() { #[derive(Reflect)] @@ -838,7 +834,7 @@ mod tests { registry.register::(); registry.register::>(); - let input = r#"{"bevy_reflect::serde::de::tests::debug_stack::Foo":(bar:(some_other_field:Some(123),baz:(value:[(start:0.0,end:1.0)])))}"#; + let input = r#"{"bevy_reflect::serde::de::tests::Foo":(bar:(some_other_field:Some(123),baz:(value:[(start:0.0,end:1.0)])))}"#; let mut deserializer = ron::de::Deserializer::from_str(input).unwrap(); let reflect_deserializer = ReflectDeserializer::new(®istry); let error = reflect_deserializer @@ -847,7 +843,7 @@ mod tests { assert_eq!( error, ron::Error::Message( - "type `core::ops::RangeInclusive` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data` (stack: `bevy_reflect::serde::de::tests::debug_stack::Foo` -> `bevy_reflect::serde::de::tests::debug_stack::Bar` -> `bevy_reflect::serde::de::tests::debug_stack::Baz` -> `alloc::vec::Vec>` -> `core::ops::RangeInclusive`)".to_string() + "type `core::ops::RangeInclusive` did not register the `ReflectDeserialize` type data. For certain types, this may need to be registered manually using `register_type_data` (stack: `bevy_reflect::serde::de::tests::Foo` -> `bevy_reflect::serde::de::tests::Bar` -> `bevy_reflect::serde::de::tests::Baz` -> `alloc::vec::Vec>` -> `core::ops::RangeInclusive`)".to_string() ) ); } diff --git a/crates/bevy_reflect/src/serde/ser/error_utils.rs b/crates/bevy_reflect/src/serde/ser/error_utils.rs index d252e7f591d69..4f4a801de56aa 100644 --- a/crates/bevy_reflect/src/serde/ser/error_utils.rs +++ b/crates/bevy_reflect/src/serde/ser/error_utils.rs @@ -1,17 +1,17 @@ use core::fmt::Display; use serde::ser::Error; -#[cfg(feature = "debug_stack")] -use std::thread_local; +crate::cfg::debug_stack! { + use std::thread_local; -#[cfg(feature = "debug_stack")] -thread_local! { - /// The thread-local [`TypeInfoStack`] used for debugging. - /// - /// [`TypeInfoStack`]: crate::type_info_stack::TypeInfoStack - pub(super) static TYPE_INFO_STACK: core::cell::RefCell = const { core::cell::RefCell::new( - crate::type_info_stack::TypeInfoStack::new() - ) }; + thread_local! { + /// The thread-local [`TypeInfoStack`] used for debugging. + /// + /// [`TypeInfoStack`]: crate::type_info_stack::TypeInfoStack + pub(super) static TYPE_INFO_STACK: core::cell::RefCell = const { core::cell::RefCell::new( + crate::type_info_stack::TypeInfoStack::new() + ) }; + } } /// A helper function for generating a custom serialization error message. @@ -21,9 +21,12 @@ thread_local! { /// /// [type info stack]: crate::type_info_stack::TypeInfoStack pub(super) fn make_custom_error(msg: impl Display) -> E { - #[cfg(feature = "debug_stack")] - return TYPE_INFO_STACK - .with_borrow(|stack| E::custom(format_args!("{} (stack: {:?})", msg, stack))); - #[cfg(not(feature = "debug_stack"))] - return E::custom(msg); + crate::cfg::switch! { + crate::cfg::debug_stack => { + TYPE_INFO_STACK.with_borrow(|stack| E::custom(format_args!("{} (stack: {:?})", msg, stack))) + } + _ => { + E::custom(msg) + } + } } diff --git a/crates/bevy_reflect/src/serde/ser/mod.rs b/crates/bevy_reflect/src/serde/ser/mod.rs index 25399e1d711e5..d13b62f6902d4 100644 --- a/crates/bevy_reflect/src/serde/ser/mod.rs +++ b/crates/bevy_reflect/src/serde/ser/mod.rs @@ -24,8 +24,6 @@ mod tests { serde::{ReflectSerializer, ReflectSerializerProcessor}, PartialReflect, Reflect, ReflectSerialize, Struct, TypeRegistry, }; - #[cfg(feature = "functions")] - use alloc::boxed::Box; use alloc::{ string::{String, ToString}, vec, @@ -442,22 +440,17 @@ mod tests { let serializer = ReflectSerializer::new(&value, ®istry); let error = ron::ser::to_string(&serializer).unwrap_err(); - #[cfg(feature = "debug_stack")] - assert_eq!( - error, - ron::Error::Message( + + let expected_error = crate::cfg::switch! {{ + crate::cfg::debug_stack => { "type `core::ops::RangeInclusive` is not registered in the type registry (stack: `core::ops::RangeInclusive`)" - .to_string(), - ) - ); - #[cfg(not(feature = "debug_stack"))] - assert_eq!( - error, - ron::Error::Message( + } + _ => { "type `core::ops::RangeInclusive` is not registered in the type registry" - .to_string(), - ) - ); + } + }}; + + assert_eq!(error, ron::Error::Message(expected_error.to_string())); } #[test] @@ -468,20 +461,17 @@ mod tests { let serializer = ReflectSerializer::new(&value, ®istry); let error = ron::ser::to_string(&serializer).unwrap_err(); - #[cfg(feature = "debug_stack")] - assert_eq!( - error, - ron::Error::Message( - "type `core::ops::RangeInclusive` did not register the `ReflectSerialize` or `ReflectSerializeWithRegistry` type data. For certain types, this may need to be registered manually using `register_type_data` (stack: `core::ops::RangeInclusive`)".to_string() - ) - ); - #[cfg(not(feature = "debug_stack"))] - assert_eq!( - error, - ron::Error::Message( - "type `core::ops::RangeInclusive` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`".to_string() - ) - ); + + let expected_error = crate::cfg::switch! {{ + crate::cfg::debug_stack => { + "type `core::ops::RangeInclusive` did not register the `ReflectSerialize` or `ReflectSerializeWithRegistry` type data. For certain types, this may need to be registered manually using `register_type_data` (stack: `core::ops::RangeInclusive`)" + } + _ => { + "type `core::ops::RangeInclusive` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`" + } + }}; + + assert_eq!(error, ron::Error::Message(expected_error.to_string())); } #[test] @@ -638,23 +628,21 @@ mod tests { let serializer = ReflectSerializer::with_processor(&value, ®istry, &processor); let error = ron::ser::to_string_pretty(&serializer, PrettyConfig::default()).unwrap_err(); - #[cfg(feature = "debug_stack")] - assert_eq!( - error, - ron::Error::Message("my custom serialize error (stack: `i32`)".to_string()) - ); - #[cfg(not(feature = "debug_stack"))] - assert_eq!( - error, - ron::Error::Message("my custom serialize error".to_string()) - ); + let expected_error = crate::cfg::switch! {{ + crate::cfg::debug_stack => { + "my custom serialize error (stack: `i32`)" + } + _ => { + "my custom serialize error" + } + }}; + + assert_eq!(error, ron::Error::Message(expected_error.to_string())); } - #[cfg(feature = "functions")] - mod functions { - use super::*; + crate::cfg::functions! { use crate::func::{DynamicFunction, IntoFunction}; - use alloc::string::ToString; + use alloc::boxed::Box; #[test] fn should_not_serialize_function() { @@ -673,24 +661,20 @@ mod tests { let error = ron::ser::to_string(&serializer).unwrap_err(); - #[cfg(feature = "debug_stack")] - assert_eq!( - error, - ron::Error::Message("functions cannot be serialized (stack: `bevy_reflect::serde::ser::tests::functions::MyStruct`)".to_string()) - ); + let expected_error = crate::cfg::switch! {{ + crate::cfg::debug_stack => { + "functions cannot be serialized (stack: `bevy_reflect::serde::ser::tests::MyStruct`)" + } + _ => { + "functions cannot be serialized" + } + }}; - #[cfg(not(feature = "debug_stack"))] - assert_eq!( - error, - ron::Error::Message("functions cannot be serialized".to_string()) - ); + assert_eq!(error, ron::Error::Message(expected_error.to_string())); } } - #[cfg(feature = "debug_stack")] - mod debug_stack { - use super::*; - + crate::cfg::debug_stack! { #[test] fn should_report_context_in_errors() { #[derive(Reflect)] @@ -725,7 +709,7 @@ mod tests { assert_eq!( error, ron::Error::Message( - "type `core::ops::RangeInclusive` is not registered in the type registry (stack: `bevy_reflect::serde::ser::tests::debug_stack::Foo` -> `bevy_reflect::serde::ser::tests::debug_stack::Bar` -> `bevy_reflect::serde::ser::tests::debug_stack::Baz` -> `alloc::vec::Vec>` -> `core::ops::RangeInclusive`)".to_string() + "type `core::ops::RangeInclusive` is not registered in the type registry (stack: `bevy_reflect::serde::ser::tests::Foo` -> `bevy_reflect::serde::ser::tests::Bar` -> `bevy_reflect::serde::ser::tests::Baz` -> `alloc::vec::Vec>` -> `core::ops::RangeInclusive`)".to_string() ) ); } diff --git a/crates/bevy_reflect/src/serde/ser/serializer.rs b/crates/bevy_reflect/src/serde/ser/serializer.rs index afe6b56b1dfaf..b41fcaac78ba6 100644 --- a/crates/bevy_reflect/src/serde/ser/serializer.rs +++ b/crates/bevy_reflect/src/serde/ser/serializer.rs @@ -234,12 +234,11 @@ impl Serialize for TypedReflectSerializer<'_, P> where S: Serializer, { - #[cfg(feature = "debug_stack")] - { + crate::cfg::debug_stack! { if let Some(info) = self.value.get_represented_type_info() { TYPE_INFO_STACK.with_borrow_mut(|stack| stack.push(info)); } - } + }; // First, check if our processor wants to serialize this type // This takes priority over any other serialization operations diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index 31ad67fdcf937..fe90d1a5149a6 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -733,14 +733,13 @@ all_tuples!( P ); -#[cfg(feature = "functions")] -const _: () = { +crate::cfg::functions! { macro_rules! impl_get_ownership_tuple { - ($(#[$meta:meta])* $($name: ident),*) => { - $(#[$meta])* - $crate::func::args::impl_get_ownership!(($($name,)*); <$($name),*>); - }; -} + ($(#[$meta:meta])* $($name: ident),*) => { + $(#[$meta])* + $crate::func::args::impl_get_ownership!(($($name,)*); <$($name),*>); + }; + } all_tuples!( #[doc(fake_variadic)] @@ -751,11 +750,11 @@ const _: () = { ); macro_rules! impl_from_arg_tuple { - ($(#[$meta:meta])* $($name: ident),*) => { - $(#[$meta])* - $crate::func::args::impl_from_arg!(($($name,)*); <$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*>); - }; -} + ($(#[$meta:meta])* $($name: ident),*) => { + $(#[$meta])* + $crate::func::args::impl_from_arg!(($($name,)*); <$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*>); + }; + } all_tuples!( #[doc(fake_variadic)] @@ -766,11 +765,11 @@ const _: () = { ); macro_rules! impl_into_return_tuple { - ($(#[$meta:meta])* $($name: ident),+) => { - $(#[$meta])* - $crate::func::impl_into_return!(($($name,)*); <$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*>); - }; -} + ($(#[$meta:meta])* $($name: ident),+) => { + $(#[$meta])* + $crate::func::impl_into_return!(($($name,)*); <$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*>); + }; + } // The unit type (i.e. `()`) is special-cased, so we skip implementing it here. all_tuples!( @@ -780,7 +779,7 @@ const _: () = { 12, P ); -}; +} #[cfg(test)] mod tests { diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index aa6b6e239cbfd..6c8e9704b3680 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -147,9 +147,6 @@ bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features bevy_platform = { path = "../bevy_platform", version = "0.16.0-dev", default-features = false, features = [ "web", ] } -bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-features = false, features = [ - "web", -] } [target.'cfg(all(target_arch = "wasm32", target_feature = "atomics"))'.dependencies] send_wrapper = "0.6.0" diff --git a/crates/bevy_state/Cargo.toml b/crates/bevy_state/Cargo.toml index 1ae52fa571670..74e6c25852295 100644 --- a/crates/bevy_state/Cargo.toml +++ b/crates/bevy_state/Cargo.toml @@ -28,13 +28,7 @@ bevy_app = ["dep:bevy_app"] ## Allows access to the `std` crate. Enabling this feature will prevent compilation ## on `no_std` targets, but provides access to certain additional features on ## supported platforms. -std = [ - "bevy_ecs/std", - "bevy_utils/std", - "bevy_reflect?/std", - "bevy_app?/std", - "bevy_platform/std", -] +std = ["bevy_ecs/std", "bevy_utils/std", "bevy_app?/std", "bevy_platform/std"] ## `critical-section` provides the building blocks for synchronization primitives ## on all platforms, including `no_std`. @@ -42,7 +36,6 @@ critical-section = [ "bevy_ecs/critical-section", "bevy_utils/critical-section", "bevy_app?/critical-section", - "bevy_reflect?/critical-section", "bevy_platform/critical-section", ] diff --git a/crates/bevy_time/Cargo.toml b/crates/bevy_time/Cargo.toml index 520782b51990c..98a0dafb14ed4 100644 --- a/crates/bevy_time/Cargo.toml +++ b/crates/bevy_time/Cargo.toml @@ -30,7 +30,6 @@ serialize = ["dep:serde", "bevy_ecs/serialize", "bevy_platform/serialize"] ## supported platforms. std = [ "serde?/std", - "bevy_reflect?/std", "bevy_ecs/std", "bevy_app/std", "bevy_platform/std", @@ -42,7 +41,6 @@ std = [ critical-section = [ "bevy_ecs/critical-section", "bevy_platform/critical-section", - "bevy_reflect?/critical-section", "bevy_app/critical-section", ] diff --git a/crates/bevy_transform/Cargo.toml b/crates/bevy_transform/Cargo.toml index 348db148ce66a..49ae2ca16ef38 100644 --- a/crates/bevy_transform/Cargo.toml +++ b/crates/bevy_transform/Cargo.toml @@ -72,7 +72,6 @@ std = [ "bevy_log", "bevy_ecs?/std", "bevy_math/std", - "bevy_reflect?/std", "bevy_tasks/std", "bevy_utils/std", "serde?/std", @@ -84,7 +83,6 @@ critical-section = [ "bevy_app?/critical-section", "bevy_ecs?/critical-section", "bevy_tasks/critical-section", - "bevy_reflect?/critical-section", ] ## Allows access to the `alloc` crate. diff --git a/crates/bevy_window/Cargo.toml b/crates/bevy_window/Cargo.toml index b2b6d730fe129..5c9350f6d458c 100644 --- a/crates/bevy_window/Cargo.toml +++ b/crates/bevy_window/Cargo.toml @@ -39,7 +39,6 @@ std = [ "bevy_ecs/std", "bevy_input/std", "bevy_math/std", - "bevy_reflect?/std", "serde?/std", "raw-window-handle/std", "bevy_platform/std", diff --git a/crates/bevy_winit/Cargo.toml b/crates/bevy_winit/Cargo.toml index 5665a96029551..0325c3330734b 100644 --- a/crates/bevy_winit/Cargo.toml +++ b/crates/bevy_winit/Cargo.toml @@ -77,9 +77,6 @@ bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features bevy_platform = { path = "../bevy_platform", version = "0.16.0-dev", default-features = false, features = [ "web", ] } -bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-features = false, features = [ - "web", -] } [lints] workspace = true