diff --git a/Cargo.toml b/Cargo.toml index ad0ca5a293..8599622c09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -348,6 +348,9 @@ ios_simulator = ["bevy_internal/ios_simulator"] # Enable built in global state machines bevy_state = ["bevy_internal/bevy_state"] +# Enable function reflection +reflect_functions = ["bevy_internal/reflect_functions"] + [dependencies] bevy_internal = { path = "crates/bevy_internal", version = "0.15.0-dev", default-features = false } @@ -2158,6 +2161,7 @@ wasm = false name = "function_reflection" path = "examples/reflection/function_reflection.rs" doc-scrape-examples = true +required-features = ["reflect_functions"] [package.metadata.example.function_reflection] name = "Function Reflection" diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index 821350c24c..88dd68974d 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -195,6 +195,9 @@ ios_simulator = ["bevy_pbr?/ios_simulator", "bevy_render?/ios_simulator"] # Enable built in global state machines bevy_state = ["dep:bevy_state"] +# Enable function reflection +reflect_functions = ["bevy_reflect/functions"] + [dependencies] # bevy bevy_a11y = { path = "../bevy_a11y", version = "0.15.0-dev" } diff --git a/crates/bevy_reflect/Cargo.toml b/crates/bevy_reflect/Cargo.toml index 8cdd32204f..82f0a78c3f 100644 --- a/crates/bevy_reflect/Cargo.toml +++ b/crates/bevy_reflect/Cargo.toml @@ -19,6 +19,8 @@ smallvec = ["dep:smallvec"] uuid = ["dep:uuid"] # When enabled, allows documentation comments to be accessed via reflection documentation = ["bevy_reflect_derive/documentation"] +# Enables function reflection +functions = ["bevy_reflect_derive/functions"] [dependencies] # bevy diff --git a/crates/bevy_reflect/compile_fail/Cargo.toml b/crates/bevy_reflect/compile_fail/Cargo.toml index dd1a6ef66c..f8a8a41d67 100644 --- a/crates/bevy_reflect/compile_fail/Cargo.toml +++ b/crates/bevy_reflect/compile_fail/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" publish = false [dependencies] -bevy_reflect = { path = "../" } +bevy_reflect = { path = "../", features = ["functions"] } [dev-dependencies] compile_fail_utils = { path = "../../../tools/compile_fail_utils" } diff --git a/crates/bevy_reflect/derive/Cargo.toml b/crates/bevy_reflect/derive/Cargo.toml index 76e897a9ef..5bf77a701a 100644 --- a/crates/bevy_reflect/derive/Cargo.toml +++ b/crates/bevy_reflect/derive/Cargo.toml @@ -15,6 +15,8 @@ proc-macro = true default = [] # When enabled, allows documentation comments to be processed by the reflection macros documentation = [] +# Enables macro logic related to function reflection +functions = [] [dependencies] bevy_macro_utils = { path = "../../bevy_macro_utils", version = "0.15.0-dev" } diff --git a/crates/bevy_reflect/derive/src/impls/enums.rs b/crates/bevy_reflect/derive/src/impls/enums.rs index 2d479ac2b9..2dac509217 100644 --- a/crates/bevy_reflect/derive/src/impls/enums.rs +++ b/crates/bevy_reflect/derive/src/impls/enums.rs @@ -1,6 +1,6 @@ use crate::derive_data::{EnumVariantFields, ReflectEnum, StructField}; use crate::enum_utility::{EnumVariantOutputData, TryApplyVariantBuilder, VariantBuilder}; -use crate::impls::{impl_function_traits, impl_type_path, impl_typed}; +use crate::impls::{impl_type_path, impl_typed}; use bevy_macro_utils::fq_std::{FQAny, FQBox, FQOption, FQResult}; use proc_macro2::{Ident, Span}; use quote::quote; @@ -65,7 +65,11 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> proc_macro2::TokenStream let type_path_impl = impl_type_path(reflect_enum.meta()); - let function_impls = impl_function_traits(reflect_enum.meta(), &where_clause_options); + #[cfg(not(feature = "functions"))] + let function_impls = None::; + #[cfg(feature = "functions")] + let function_impls = + crate::impls::impl_function_traits(reflect_enum.meta(), &where_clause_options); let get_type_registration_impl = reflect_enum.get_type_registration(&where_clause_options); diff --git a/crates/bevy_reflect/derive/src/impls/mod.rs b/crates/bevy_reflect/derive/src/impls/mod.rs index 276101bf8b..85f50d1a20 100644 --- a/crates/bevy_reflect/derive/src/impls/mod.rs +++ b/crates/bevy_reflect/derive/src/impls/mod.rs @@ -1,4 +1,5 @@ mod enums; +#[cfg(feature = "functions")] mod func; mod structs; mod tuple_structs; @@ -6,6 +7,7 @@ mod typed; mod values; pub(crate) use enums::impl_enum; +#[cfg(feature = "functions")] pub(crate) use func::impl_function_traits; pub(crate) use structs::impl_struct; pub(crate) use tuple_structs::impl_tuple_struct; diff --git a/crates/bevy_reflect/derive/src/impls/structs.rs b/crates/bevy_reflect/derive/src/impls/structs.rs index 52f5b96d5a..2ac44136aa 100644 --- a/crates/bevy_reflect/derive/src/impls/structs.rs +++ b/crates/bevy_reflect/derive/src/impls/structs.rs @@ -1,4 +1,4 @@ -use crate::impls::{impl_function_traits, impl_type_path, impl_typed}; +use crate::impls::{impl_type_path, impl_typed}; use crate::utility::ident_or_index; use crate::ReflectStruct; use bevy_macro_utils::fq_std::{FQAny, FQBox, FQDefault, FQOption, FQResult}; @@ -54,7 +54,11 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenS let type_path_impl = impl_type_path(reflect_struct.meta()); - let function_impls = impl_function_traits(reflect_struct.meta(), &where_clause_options); + #[cfg(not(feature = "functions"))] + let function_impls = None::; + #[cfg(feature = "functions")] + let function_impls = + crate::impls::impl_function_traits(reflect_struct.meta(), &where_clause_options); let get_type_registration_impl = reflect_struct.get_type_registration(&where_clause_options); diff --git a/crates/bevy_reflect/derive/src/impls/tuple_structs.rs b/crates/bevy_reflect/derive/src/impls/tuple_structs.rs index 559f63343c..4401f65e70 100644 --- a/crates/bevy_reflect/derive/src/impls/tuple_structs.rs +++ b/crates/bevy_reflect/derive/src/impls/tuple_structs.rs @@ -1,4 +1,4 @@ -use crate::impls::{impl_function_traits, impl_type_path, impl_typed}; +use crate::impls::{impl_type_path, impl_typed}; use crate::ReflectStruct; use bevy_macro_utils::fq_std::{FQAny, FQBox, FQDefault, FQOption, FQResult}; use quote::{quote, ToTokens}; @@ -46,7 +46,11 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> proc_macro2:: let type_path_impl = impl_type_path(reflect_struct.meta()); - let function_impls = impl_function_traits(reflect_struct.meta(), &where_clause_options); + #[cfg(not(feature = "functions"))] + let function_impls = None::; + #[cfg(feature = "functions")] + let function_impls = + crate::impls::impl_function_traits(reflect_struct.meta(), &where_clause_options); let (impl_generics, ty_generics, where_clause) = reflect_struct .meta() diff --git a/crates/bevy_reflect/derive/src/impls/values.rs b/crates/bevy_reflect/derive/src/impls/values.rs index b7eedca212..92c14bc1df 100644 --- a/crates/bevy_reflect/derive/src/impls/values.rs +++ b/crates/bevy_reflect/derive/src/impls/values.rs @@ -1,4 +1,4 @@ -use crate::impls::{impl_function_traits, impl_type_path, impl_typed}; +use crate::impls::{impl_type_path, impl_typed}; use crate::utility::WhereClauseOptions; use crate::ReflectMeta; use bevy_macro_utils::fq_std::{FQAny, FQBox, FQClone, FQOption, FQResult}; @@ -33,7 +33,10 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> proc_macro2::TokenStream { let type_path_impl = impl_type_path(meta); - let function_impls = impl_function_traits(meta, &where_clause_options); + #[cfg(not(feature = "functions"))] + let function_impls = None::; + #[cfg(feature = "functions")] + let function_impls = crate::impls::impl_function_traits(meta, &where_clause_options); let (impl_generics, ty_generics, where_clause) = type_path.generics().split_for_impl(); let where_reflect_clause = where_clause_options.extend_where_clause(where_clause); diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index 6db72df193..0d957ccdf4 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -1,4 +1,3 @@ -use crate::func::macros::impl_function_traits; use crate::{ self as bevy_reflect, utility::reflect_hasher, ApplyError, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, TypePathTable, @@ -359,7 +358,9 @@ impl Array for DynamicArray { } impl_type_path!((in bevy_reflect) DynamicArray); -impl_function_traits!(DynamicArray); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(DynamicArray); + /// An iterator over an [`Array`]. pub struct ArrayIter<'a> { array: &'a dyn Array, diff --git a/crates/bevy_reflect/src/enums/dynamic_enum.rs b/crates/bevy_reflect/src/enums/dynamic_enum.rs index 9b3dea9601..ff39e6ef41 100644 --- a/crates/bevy_reflect/src/enums/dynamic_enum.rs +++ b/crates/bevy_reflect/src/enums/dynamic_enum.rs @@ -1,6 +1,5 @@ use bevy_reflect_derive::impl_type_path; -use crate::func::macros::impl_function_traits; use crate::{ self as bevy_reflect, enum_debug, enum_hash, enum_partial_eq, ApplyError, DynamicStruct, DynamicTuple, Enum, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Struct, Tuple, @@ -428,4 +427,5 @@ impl Reflect for DynamicEnum { } impl_type_path!((in bevy_reflect) DynamicEnum); -impl_function_traits!(DynamicEnum); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(DynamicEnum); diff --git a/crates/bevy_reflect/src/impls/smallvec.rs b/crates/bevy_reflect/src/impls/smallvec.rs index 00e0cc9544..a0f1f38b09 100644 --- a/crates/bevy_reflect/src/impls/smallvec.rs +++ b/crates/bevy_reflect/src/impls/smallvec.rs @@ -3,7 +3,6 @@ use smallvec::{Array as SmallArray, SmallVec}; use std::any::Any; -use crate::func::macros::impl_function_traits; use crate::utility::GenericTypeInfoCell; use crate::{ self as bevy_reflect, ApplyError, FromReflect, FromType, GetTypeRegistration, List, ListInfo, @@ -188,4 +187,5 @@ where } } -impl_function_traits!(SmallVec; where T::Item: FromReflect + TypePath); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(SmallVec; where T::Item: FromReflect + TypePath); diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 4c1a828405..cef07d75a4 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -1,4 +1,3 @@ -use crate::func::macros::impl_function_traits; use crate::std_traits::ReflectDefault; use crate::utility::{ reflect_hasher, GenericTypeInfoCell, GenericTypePathCell, NonGenericTypeInfoCell, @@ -398,7 +397,8 @@ impl_reflect_for_veclike!( Vec::pop, [T] ); -impl_function_traits!(Vec; ); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(Vec; ); impl_reflect_for_veclike!( ::alloc::collections::VecDeque, @@ -408,7 +408,8 @@ impl_reflect_for_veclike!( VecDeque::pop_back, VecDeque:: ); -impl_function_traits!(VecDeque; ); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(VecDeque; ); macro_rules! impl_reflect_for_hashmap { ($ty:path) => { @@ -638,7 +639,8 @@ macro_rules! impl_reflect_for_hashmap { impl_reflect_for_hashmap!(::std::collections::HashMap); impl_type_path!(::std::collections::hash_map::RandomState); impl_type_path!(::std::collections::HashMap); -impl_function_traits!(::std::collections::HashMap; +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(::std::collections::HashMap; < K: FromReflect + TypePath + GetTypeRegistration + Eq + Hash, V: FromReflect + TypePath + GetTypeRegistration, @@ -649,7 +651,8 @@ impl_function_traits!(::std::collections::HashMap; impl_reflect_for_hashmap!(bevy_utils::hashbrown::HashMap); impl_type_path!(::bevy_utils::hashbrown::hash_map::DefaultHashBuilder); impl_type_path!(::bevy_utils::hashbrown::HashMap); -impl_function_traits!(::bevy_utils::hashbrown::HashMap; +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(::bevy_utils::hashbrown::HashMap; < K: FromReflect + TypePath + GetTypeRegistration + Eq + Hash, V: FromReflect + TypePath + GetTypeRegistration, @@ -869,7 +872,8 @@ where } impl_type_path!(::std::collections::BTreeMap); -impl_function_traits!(::std::collections::BTreeMap; +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(::std::collections::BTreeMap; < K: FromReflect + TypePath + GetTypeRegistration + Eq + Ord, V: FromReflect + TypePath + GetTypeRegistration @@ -1035,7 +1039,8 @@ impl GetTypeRegistr } } -impl_function_traits!([T; N]; [const N: usize]); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!([T; N]; [const N: usize]); impl_reflect! { #[type_path = "core::option"] @@ -1194,7 +1199,8 @@ impl FromReflect for Cow<'static, str> { } } -impl_function_traits!(Cow<'static, str>); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(Cow<'static, str>); impl TypePath for [T] where @@ -1374,7 +1380,8 @@ impl FromReflect for Co } } -impl_function_traits!(Cow<'static, [T]>; ); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(Cow<'static, [T]>; ); impl Reflect for &'static str { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { @@ -1482,7 +1489,8 @@ impl FromReflect for &'static str { } } -impl_function_traits!(&'static str); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(&'static str); impl Reflect for &'static Path { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { @@ -1589,7 +1597,8 @@ impl FromReflect for &'static Path { } } -impl_function_traits!(&'static Path); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(&'static Path); impl Reflect for Cow<'static, Path> { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { @@ -1706,7 +1715,8 @@ impl GetTypeRegistration for Cow<'static, Path> { } } -impl_function_traits!(Cow<'static, Path>); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(Cow<'static, Path>); #[cfg(test)] mod tests { diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index dcd77bb214..f41a230045 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -476,6 +476,7 @@ mod array; mod fields; mod from_reflect; +#[cfg(feature = "functions")] pub mod func; mod list; mod map; @@ -517,6 +518,9 @@ pub mod prelude { ReflectDeserialize, ReflectFromReflect, ReflectPath, ReflectSerialize, Struct, TupleStruct, TypePath, }; + + #[cfg(feature = "functions")] + pub use crate::func::IntoFunction; } pub use array::*; diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index c73baab329..68921d4817 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -4,7 +4,6 @@ use std::hash::{Hash, Hasher}; use bevy_reflect_derive::impl_type_path; -use crate::func::macros::impl_function_traits; use crate::utility::reflect_hasher; use crate::{ self as bevy_reflect, ApplyError, FromReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, @@ -370,7 +369,8 @@ impl Reflect for DynamicList { } impl_type_path!((in bevy_reflect) DynamicList); -impl_function_traits!(DynamicList); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(DynamicList); impl Debug for DynamicList { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index 844be9a247..6c94b284e4 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -4,7 +4,6 @@ use std::fmt::{Debug, Formatter}; use bevy_reflect_derive::impl_type_path; use bevy_utils::{Entry, HashMap}; -use crate::func::macros::impl_function_traits; use crate::{ self as bevy_reflect, ApplyError, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, TypePathTable, @@ -418,7 +417,8 @@ impl Reflect for DynamicMap { } impl_type_path!((in bevy_reflect) DynamicMap); -impl_function_traits!(DynamicMap); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(DynamicMap); impl Debug for DynamicMap { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { diff --git a/crates/bevy_reflect/src/struct_trait.rs b/crates/bevy_reflect/src/struct_trait.rs index 92cba76baa..24bb44e6c2 100644 --- a/crates/bevy_reflect/src/struct_trait.rs +++ b/crates/bevy_reflect/src/struct_trait.rs @@ -1,5 +1,4 @@ use crate::attributes::{impl_custom_attribute_methods, CustomAttributes}; -use crate::func::macros::impl_function_traits; use crate::{ self as bevy_reflect, ApplyError, NamedField, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, TypePathTable, @@ -500,7 +499,8 @@ impl Reflect for DynamicStruct { } impl_type_path!((in bevy_reflect) DynamicStruct); -impl_function_traits!(DynamicStruct); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(DynamicStruct); impl Debug for DynamicStruct { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index 4e96d50f20..c151921ef6 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -710,30 +710,33 @@ macro_rules! impl_type_path_tuple { all_tuples!(impl_type_path_tuple, 0, 12, P); -macro_rules! impl_get_ownership_tuple { +#[cfg(feature = "functions")] +const _: () = { + macro_rules! impl_get_ownership_tuple { ($($name: ident),*) => { $crate::func::args::impl_get_ownership!(($($name,)*); <$($name),*>); }; } -all_tuples!(impl_get_ownership_tuple, 0, 12, P); + all_tuples!(impl_get_ownership_tuple, 0, 12, P); -macro_rules! impl_from_arg_tuple { + macro_rules! impl_from_arg_tuple { ($($name: ident),*) => { $crate::func::args::impl_from_arg!(($($name,)*); <$($name: FromReflect + TypePath + GetTypeRegistration),*>); }; } -all_tuples!(impl_from_arg_tuple, 0, 12, P); + all_tuples!(impl_from_arg_tuple, 0, 12, P); -macro_rules! impl_into_return_tuple { + macro_rules! impl_into_return_tuple { ($($name: ident),+) => { $crate::func::impl_into_return!(($($name,)*); <$($name: FromReflect + TypePath + GetTypeRegistration),*>); }; } -// The unit type (i.e. `()`) is special-cased, so we skip implementing it here. -all_tuples!(impl_into_return_tuple, 1, 12, P); + // The unit type (i.e. `()`) is special-cased, so we skip implementing it here. + all_tuples!(impl_into_return_tuple, 1, 12, P); +}; #[cfg(test)] mod tests { diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index 87c87fb376..9bb32d00de 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -1,7 +1,6 @@ use bevy_reflect_derive::impl_type_path; use crate::attributes::{impl_custom_attribute_methods, CustomAttributes}; -use crate::func::macros::impl_function_traits; use crate::{ self as bevy_reflect, ApplyError, DynamicTuple, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Tuple, TypeInfo, TypePath, TypePathTable, UnnamedField, @@ -409,7 +408,8 @@ impl Reflect for DynamicTupleStruct { } impl_type_path!((in bevy_reflect) DynamicTupleStruct); -impl_function_traits!(DynamicTupleStruct); +#[cfg(feature = "functions")] +crate::func::macros::impl_function_traits!(DynamicTupleStruct); impl Debug for DynamicTupleStruct { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { diff --git a/docs/cargo_features.md b/docs/cargo_features.md index 09873c89ee..568048759b 100644 --- a/docs/cargo_features.md +++ b/docs/cargo_features.md @@ -75,6 +75,7 @@ The default feature set enables most of the expected features of a game engine, |pbr_multi_layer_material_textures|Enable support for multi-layer material textures in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs| |pbr_transmission_textures|Enable support for transmission-related textures in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs| |pnm|PNM image format support, includes pam, pbm, pgm and ppm| +|reflect_functions|Enable function reflection| |serialize|Enable serialization support through serde| |shader_format_glsl|Enable support for shaders in GLSL| |shader_format_spirv|Enable support for shaders in SPIR-V|