From ebeb7e2de77cff5d9aab49437806d63542248143 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sat, 17 Aug 2024 11:17:44 -0700 Subject: [PATCH 1/8] Remove DynamicFunction and IntoFunction --- benches/benches/bevy_reflect/function.rs | 6 +- .../bevy_reflect/compile_fail/tests/func.rs | 2 +- .../arguments_fail.rs | 8 +- .../tests/into_closure/closure_fail.rs | 18 ++ .../return_fail.rs | 10 +- .../tests/into_function/closure_fail.rs | 19 -- crates/bevy_reflect/src/func/args/arg.rs | 9 +- crates/bevy_reflect/src/func/args/from_arg.rs | 6 +- crates/bevy_reflect/src/func/args/info.rs | 12 +- crates/bevy_reflect/src/func/args/list.rs | 4 +- crates/bevy_reflect/src/func/args/mod.rs | 6 +- .../bevy_reflect/src/func/args/ownership.rs | 4 +- .../src/func/closures/dynamic_closure.rs | 16 +- .../src/func/closures/dynamic_closure_mut.rs | 12 +- .../src/func/closures/into_closure.rs | 3 - crates/bevy_reflect/src/func/error.rs | 8 +- crates/bevy_reflect/src/func/function.rs | 292 ------------------ crates/bevy_reflect/src/func/info.rs | 14 +- crates/bevy_reflect/src/func/into_function.rs | 180 ----------- crates/bevy_reflect/src/func/mod.rs | 25 +- crates/bevy_reflect/src/func/registry.rs | 29 +- crates/bevy_reflect/src/func/return_type.rs | 9 +- crates/bevy_reflect/src/lib.rs | 2 +- examples/reflection/function_reflection.rs | 28 +- 24 files changed, 103 insertions(+), 619 deletions(-) rename crates/bevy_reflect/compile_fail/tests/{into_function => into_closure}/arguments_fail.rs (72%) create mode 100644 crates/bevy_reflect/compile_fail/tests/into_closure/closure_fail.rs rename crates/bevy_reflect/compile_fail/tests/{into_function => into_closure}/return_fail.rs (59%) delete mode 100644 crates/bevy_reflect/compile_fail/tests/into_function/closure_fail.rs delete mode 100644 crates/bevy_reflect/src/func/function.rs delete mode 100644 crates/bevy_reflect/src/func/into_function.rs diff --git a/benches/benches/bevy_reflect/function.rs b/benches/benches/bevy_reflect/function.rs index 79b01a2c0f255..3d9754c63bfd5 100644 --- a/benches/benches/bevy_reflect/function.rs +++ b/benches/benches/bevy_reflect/function.rs @@ -24,7 +24,7 @@ fn typed(c: &mut Criterion) { fn into(c: &mut Criterion) { c.benchmark_group("into") .bench_function("function", |b| { - b.iter(|| add.into_function()); + b.iter(|| add.into_closure()); }) .bench_function("closure", |b| { let capture = 25; @@ -36,7 +36,7 @@ fn into(c: &mut Criterion) { fn call(c: &mut Criterion) { c.benchmark_group("call") .bench_function("function", |b| { - let add = add.into_function(); + let add = add.into_closure(); b.iter_batched( || ArgList::new().push_owned(75_i32).push_owned(25_i32), |args| add.call(args), @@ -56,7 +56,7 @@ fn call(c: &mut Criterion) { fn clone(c: &mut Criterion) { c.benchmark_group("clone").bench_function("function", |b| { - let add = add.into_function(); + let add = add.into_closure(); b.iter(|| add.clone()); }); } diff --git a/crates/bevy_reflect/compile_fail/tests/func.rs b/crates/bevy_reflect/compile_fail/tests/func.rs index 51ec8397a7972..cd83f8759e8ad 100644 --- a/crates/bevy_reflect/compile_fail/tests/func.rs +++ b/crates/bevy_reflect/compile_fail/tests/func.rs @@ -1,3 +1,3 @@ fn main() -> compile_fail_utils::ui_test::Result<()> { - compile_fail_utils::test("reflect_into_function", "tests/into_function") + compile_fail_utils::test("reflect_into_closure", "tests/into_closure") } diff --git a/crates/bevy_reflect/compile_fail/tests/into_function/arguments_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_closure/arguments_fail.rs similarity index 72% rename from crates/bevy_reflect/compile_fail/tests/into_function/arguments_fail.rs rename to crates/bevy_reflect/compile_fail/tests/into_closure/arguments_fail.rs index 9187e874ec823..143b2fa49e635 100644 --- a/crates/bevy_reflect/compile_fail/tests/into_function/arguments_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/into_closure/arguments_fail.rs @@ -1,6 +1,6 @@ #![allow(unused)] -use bevy_reflect::func::IntoFunction; +use bevy_reflect::func::IntoClosure; use bevy_reflect::Reflect; fn pass(_: i32) {} @@ -30,11 +30,11 @@ struct Foo; fn argument_not_reflect(foo: Foo) {} fn main() { - let _ = pass.into_function(); + let _ = pass.into_closure(); - let _ = too_many_arguments.into_function(); + let _ = too_many_arguments.into_closure(); //~^ E0599 - let _ = argument_not_reflect.into_function(); + let _ = argument_not_reflect.into_closure(); //~^ E0599 } diff --git a/crates/bevy_reflect/compile_fail/tests/into_closure/closure_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_closure/closure_fail.rs new file mode 100644 index 0000000000000..747fc48321012 --- /dev/null +++ b/crates/bevy_reflect/compile_fail/tests/into_closure/closure_fail.rs @@ -0,0 +1,18 @@ +#![allow(unused)] + +use bevy_reflect::func::{DynamicClosure, IntoClosure}; +use bevy_reflect::Reflect; + +fn main() { + let value = String::from("Hello, World!"); + let closure_capture_owned = move || println!("{}", value); + + // Pass: + let _: DynamicClosure<'static> = closure_capture_owned.into_closure(); + + let value = String::from("Hello, World!"); + let closure_capture_reference = || println!("{}", value); + //~^ ERROR: `value` does not live long enough + + let _: DynamicClosure<'static> = closure_capture_reference.into_closure(); +} diff --git a/crates/bevy_reflect/compile_fail/tests/into_function/return_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_closure/return_fail.rs similarity index 59% rename from crates/bevy_reflect/compile_fail/tests/into_function/return_fail.rs rename to crates/bevy_reflect/compile_fail/tests/into_closure/return_fail.rs index d73a3406b306b..373b8be86c97d 100644 --- a/crates/bevy_reflect/compile_fail/tests/into_function/return_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/into_closure/return_fail.rs @@ -1,6 +1,6 @@ #![allow(unused)] -use bevy_reflect::func::IntoFunction; +use bevy_reflect::func::IntoClosure; use bevy_reflect::Reflect; fn pass() -> i32 { @@ -22,13 +22,13 @@ fn return_with_invalid_lifetime<'a, 'b>(a: &'a String, b: &'b String) -> &'b Str } fn main() { - let _ = pass.into_function(); + let _ = pass.into_closure(); - let _ = return_not_reflect.into_function(); + let _ = return_not_reflect.into_closure(); //~^ E0599 - let _ = return_with_lifetime_pass.into_function(); + let _ = return_with_lifetime_pass.into_closure(); - let _ = return_with_invalid_lifetime.into_function(); + let _ = return_with_invalid_lifetime.into_closure(); //~^ E0599 } diff --git a/crates/bevy_reflect/compile_fail/tests/into_function/closure_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_function/closure_fail.rs deleted file mode 100644 index 15316677ca5e0..0000000000000 --- a/crates/bevy_reflect/compile_fail/tests/into_function/closure_fail.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![allow(unused)] - -use bevy_reflect::func::IntoFunction; -use bevy_reflect::Reflect; - -fn main() { - let value = String::from("Hello, World!"); - let closure_capture_owned = move || println!("{}", value); - - let _ = closure_capture_owned.into_function(); - //~^ E0277 - - let value = String::from("Hello, World!"); - let closure_capture_reference = || println!("{}", value); - - let _ = closure_capture_reference.into_function(); - // ↑ This should be an error (E0277) but `compile_fail_utils` fails to pick it up - // when the `closure_capture_owned` test is present -} diff --git a/crates/bevy_reflect/src/func/args/arg.rs b/crates/bevy_reflect/src/func/args/arg.rs index aa0d12b02781b..b769439e88a9e 100644 --- a/crates/bevy_reflect/src/func/args/arg.rs +++ b/crates/bevy_reflect/src/func/args/arg.rs @@ -2,10 +2,8 @@ use crate::func::args::{ArgError, FromArg, Ownership}; use crate::{PartialReflect, Reflect, TypePath}; use std::ops::Deref; -/// Represents an argument that can be passed to a [`DynamicFunction`], [`DynamicClosure`], -/// or [`DynamicClosureMut`]. +/// Represents an argument that can be passed to a [`DynamicClosure`] or [`DynamicClosureMut`]. /// -/// [`DynamicFunction`]: crate::func::DynamicFunction /// [`DynamicClosure`]: crate::func::DynamicClosure /// [`DynamicClosureMut`]: crate::func::DynamicClosureMut #[derive(Debug)] @@ -181,9 +179,10 @@ impl<'a> Arg<'a> { } } -/// Represents an argument that can be passed to a [`DynamicFunction`]. +/// Represents an argument that can be passed to a [`DynamicClosure`] or [`DynamicClosureMut`]. /// -/// [`DynamicFunction`]: crate::func::DynamicFunction +/// [`DynamicClosure`]: crate::func::DynamicClosure +/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut #[derive(Debug)] pub enum ArgValue<'a> { Owned(Box), diff --git a/crates/bevy_reflect/src/func/args/from_arg.rs b/crates/bevy_reflect/src/func/args/from_arg.rs index 9478650165914..757c55e94d881 100644 --- a/crates/bevy_reflect/src/func/args/from_arg.rs +++ b/crates/bevy_reflect/src/func/args/from_arg.rs @@ -3,16 +3,16 @@ use crate::func::args::{Arg, ArgError}; /// A trait for types that can be created from an [`Arg`]. /// /// This trait exists so that types can be automatically converted into an [`Arg`] -/// by [`IntoFunction`] so they can be passed to a [`DynamicFunction`] in an [`ArgList`]. +/// so they can be put into an [`ArgList`] and passed to a [`DynamicClosure`] or [`DynamicClosureMut`]. /// /// This trait is used instead of a blanket [`From`] implementation due to coherence issues: /// we can't implement `From` for both `T` and `&T`/`&mut T`. /// /// This trait is automatically implemented when using the `Reflect` [derive macro]. /// -/// [`IntoFunction`]: crate::func::IntoFunction -/// [`DynamicFunction`]: crate::func::DynamicFunction /// [`ArgList`]: crate::func::args::ArgList +/// [`DynamicClosure`]: crate::func::DynamicClosure +/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut /// [derive macro]: derive@crate::Reflect pub trait FromArg { /// The type to convert into. diff --git a/crates/bevy_reflect/src/func/args/info.rs b/crates/bevy_reflect/src/func/args/info.rs index f55643dcc70e6..ff5cc7bcf4ee0 100644 --- a/crates/bevy_reflect/src/func/args/info.rs +++ b/crates/bevy_reflect/src/func/args/info.rs @@ -3,11 +3,9 @@ use alloc::borrow::Cow; use crate::func::args::{GetOwnership, Ownership}; use crate::TypePath; -/// Type information for an [`Arg`] used in a [`DynamicFunction`], [`DynamicClosure`], -/// or [`DynamicClosureMut`]. +/// Type information for an [`Arg`] used in a [`DynamicClosure`] or [`DynamicClosureMut`]. /// /// [`Arg`]: crate::func::args::Arg -/// [`DynamicFunction`]: crate::func::function::DynamicFunction /// [`DynamicClosure`]: crate::func::closures::DynamicClosure /// [`DynamicClosureMut`]: crate::func::closures::DynamicClosureMut #[derive(Debug, Clone)] @@ -57,14 +55,14 @@ impl ArgInfo { /// This is because the name needs to be manually set using [`Self::with_name`] /// since the name can't be inferred from the function type alone. /// - /// For [`DynamicFunctions`] created using [`IntoFunction`] - /// or [`DynamicClosures`] created using [`IntoClosure`], + /// For [`DynamicClosures`] created using [`IntoClosure`] + /// and [`DynamicClosureMuts`] created using [`IntoClosureMut`], /// the name will always be `None`. /// - /// [`DynamicFunctions`]: crate::func::DynamicFunction - /// [`IntoFunction`]: crate::func::IntoFunction /// [`DynamicClosures`]: crate::func::DynamicClosure /// [`IntoClosure`]: crate::func::IntoClosure + /// [`DynamicClosureMuts`]: crate::func::DynamicClosureMut + /// [`IntoClosureMut`]: crate::func::IntoClosureMut pub fn name(&self) -> Option<&str> { self.name.as_deref() } diff --git a/crates/bevy_reflect/src/func/args/list.rs b/crates/bevy_reflect/src/func/args/list.rs index 481df444f21c5..81711a528d46f 100644 --- a/crates/bevy_reflect/src/func/args/list.rs +++ b/crates/bevy_reflect/src/func/args/list.rs @@ -3,8 +3,7 @@ use crate::func::ArgError; use crate::{PartialReflect, Reflect, TypePath}; use std::collections::VecDeque; -/// A list of arguments that can be passed to a [`DynamicFunction`], [`DynamicClosure`], -/// or [`DynamicClosureMut`]. +/// A list of arguments that can be passed to a [`DynamicClosure`] or [`DynamicClosureMut`]. /// /// # Example /// @@ -27,7 +26,6 @@ use std::collections::VecDeque; /// ``` /// /// [arguments]: Arg -/// [`DynamicFunction`]: crate::func::DynamicFunction /// [`DynamicClosure`]: crate::func::DynamicClosure /// [`DynamicClosureMut`]: crate::func::DynamicClosureMut #[derive(Default, Debug)] diff --git a/crates/bevy_reflect/src/func/args/mod.rs b/crates/bevy_reflect/src/func/args/mod.rs index 57237b70e8207..a0c1d505749f3 100644 --- a/crates/bevy_reflect/src/func/args/mod.rs +++ b/crates/bevy_reflect/src/func/args/mod.rs @@ -1,7 +1,7 @@ -//! Argument types and utilities for working with [`DynamicFunctions`] and [`DynamicClosures`]. +//! Argument types and utilities for working with [`DynamicClosure`] and [`DynamicClosureMut`]. //! -//! [`DynamicFunctions`]: crate::func::DynamicFunction -//! [`DynamicClosures`]: crate::func::DynamicClosure +//! [`DynamicClosure`]: crate::func::DynamicClosure +//! [`DynamicClosureMut`]: crate::func::DynamicClosureMut pub use arg::*; pub use error::*; diff --git a/crates/bevy_reflect/src/func/args/ownership.rs b/crates/bevy_reflect/src/func/args/ownership.rs index e12ca5440a307..b9395c742f404 100644 --- a/crates/bevy_reflect/src/func/args/ownership.rs +++ b/crates/bevy_reflect/src/func/args/ownership.rs @@ -2,12 +2,12 @@ use core::fmt::{Display, Formatter}; /// A trait for getting the ownership of a type. /// -/// This trait exists so that [`IntoFunction`] can automatically generate +/// This trait exists so that [`TypedFunction`] can automatically generate /// [`FunctionInfo`] containing the proper [`Ownership`] for its [argument] types. /// /// This trait is automatically implemented when using the `Reflect` [derive macro]. /// -/// [`IntoFunction`]: crate::func::IntoFunction +/// [`TypedFunction`]: crate::func::TypedFunction /// [`FunctionInfo`]: crate::func::FunctionInfo /// [argument]: crate::func::args::Arg /// [derive macro]: derive@crate::Reflect diff --git a/crates/bevy_reflect/src/func/closures/dynamic_closure.rs b/crates/bevy_reflect/src/func/closures/dynamic_closure.rs index f49645f70f4a7..0bb773595631a 100644 --- a/crates/bevy_reflect/src/func/closures/dynamic_closure.rs +++ b/crates/bevy_reflect/src/func/closures/dynamic_closure.rs @@ -1,8 +1,6 @@ use crate::func::args::{ArgInfo, ArgList}; use crate::func::info::FunctionInfo; -use crate::func::{ - DynamicClosureMut, DynamicFunction, FunctionResult, IntoClosure, IntoClosureMut, ReturnInfo, -}; +use crate::func::{DynamicClosureMut, FunctionResult, IntoClosure, IntoClosureMut, ReturnInfo}; use alloc::borrow::Cow; use core::fmt::{Debug, Formatter}; use std::sync::Arc; @@ -13,8 +11,6 @@ use std::sync::Arc; /// For closures that need to capture their environment mutably, /// see [`DynamicClosureMut`]. /// -/// This type can be seen as a superset of [`DynamicFunction`]. -/// /// See the [module-level documentation] for more information. /// /// You will generally not need to construct this manually. @@ -168,16 +164,6 @@ impl<'env> Clone for DynamicClosure<'env> { } } -impl From for DynamicClosure<'static> { - #[inline] - fn from(func: DynamicFunction) -> Self { - Self { - info: func.info, - func: func.func, - } - } -} - impl<'env> IntoClosure<'env, ()> for DynamicClosure<'env> { #[inline] fn into_closure(self) -> DynamicClosure<'env> { diff --git a/crates/bevy_reflect/src/func/closures/dynamic_closure_mut.rs b/crates/bevy_reflect/src/func/closures/dynamic_closure_mut.rs index b85521d939ba1..11f46de63602f 100644 --- a/crates/bevy_reflect/src/func/closures/dynamic_closure_mut.rs +++ b/crates/bevy_reflect/src/func/closures/dynamic_closure_mut.rs @@ -3,7 +3,7 @@ use core::fmt::{Debug, Formatter}; use crate::func::args::{ArgInfo, ArgList}; use crate::func::info::FunctionInfo; -use crate::func::{DynamicClosure, DynamicFunction, FunctionResult, IntoClosureMut, ReturnInfo}; +use crate::func::{DynamicClosure, FunctionResult, IntoClosureMut, ReturnInfo}; /// A dynamic representation of a Rust closure. /// @@ -199,16 +199,6 @@ impl<'env> Debug for DynamicClosureMut<'env> { } } -impl From for DynamicClosureMut<'static> { - #[inline] - fn from(func: DynamicFunction) -> Self { - Self { - info: func.info, - func: Box::new(move |args| (func.func)(args)), - } - } -} - impl<'env> From> for DynamicClosureMut<'env> { #[inline] fn from(closure: DynamicClosure<'env>) -> Self { diff --git a/crates/bevy_reflect/src/func/closures/into_closure.rs b/crates/bevy_reflect/src/func/closures/into_closure.rs index f3cba4a5d1b8d..ef7bfbe7ba854 100644 --- a/crates/bevy_reflect/src/func/closures/into_closure.rs +++ b/crates/bevy_reflect/src/func/closures/into_closure.rs @@ -5,11 +5,8 @@ use crate::func::{DynamicClosure, ReflectFn, TypedFunction}; /// This trait is automatically implemented for any type that implements /// [`ReflectFn`] and [`TypedFunction`]. /// -/// This trait can be seen as a supertrait of [`IntoFunction`]. -/// /// See the [module-level documentation] for more information. /// -/// [`IntoFunction`]: crate::func::IntoFunction /// [module-level documentation]: crate::func pub trait IntoClosure<'env, Marker> { /// Converts [`Self`] into a [`DynamicClosure`]. diff --git a/crates/bevy_reflect/src/func/error.rs b/crates/bevy_reflect/src/func/error.rs index 30ef98b0a80d0..464ef83ee2cc3 100644 --- a/crates/bevy_reflect/src/func/error.rs +++ b/crates/bevy_reflect/src/func/error.rs @@ -3,10 +3,10 @@ use crate::func::Return; use alloc::borrow::Cow; use thiserror::Error; -/// An error that occurs when calling a [`DynamicFunction`] or [`DynamicClosure`]. +/// An error that occurs when calling a [`DynamicClosure`] or [`DynamicClosureMut`]. /// -/// [`DynamicFunction`]: crate::func::DynamicFunction /// [`DynamicClosure`]: crate::func::DynamicClosure +/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut #[derive(Debug, Error, PartialEq)] pub enum FunctionError { /// An error occurred while converting an argument. @@ -17,13 +17,13 @@ pub enum FunctionError { ArgCountMismatch { expected: usize, received: usize }, } -/// The result of calling a dynamic [`DynamicFunction`] or [`DynamicClosure`]. +/// The result of calling a dynamic [`DynamicClosure`] or [`DynamicClosureMut`]. /// /// Returns `Ok(value)` if the function was called successfully, /// where `value` is the [`Return`] value of the function. /// -/// [`DynamicFunction`]: crate::func::DynamicFunction /// [`DynamicClosure`]: crate::func::DynamicClosure +/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut pub type FunctionResult<'a> = Result, FunctionError>; /// An error that occurs when registering a function into a [`FunctionRegistry`]. diff --git a/crates/bevy_reflect/src/func/function.rs b/crates/bevy_reflect/src/func/function.rs deleted file mode 100644 index 28c1ae3ad848e..0000000000000 --- a/crates/bevy_reflect/src/func/function.rs +++ /dev/null @@ -1,292 +0,0 @@ -use alloc::borrow::Cow; -use core::fmt::{Debug, Formatter}; -use std::sync::Arc; - -use crate::func::args::{ArgInfo, ArgList}; -use crate::func::info::FunctionInfo; -use crate::func::{ - DynamicClosure, DynamicClosureMut, FunctionResult, IntoClosure, IntoClosureMut, IntoFunction, - ReturnInfo, -}; - -/// A dynamic representation of a Rust function. -/// -/// For our purposes, a "function" is just a callable that may not reference its environment. -/// -/// This includes: -/// - Functions and methods defined with the `fn` keyword -/// - Closures that do not capture their environment -/// - Closures that take ownership of captured variables -/// -/// To handle closures that capture references to their environment, see [`DynamicClosure`]. -/// -/// See the [module-level documentation] for more information. -/// -/// You will generally not need to construct this manually. -/// Instead, many functions and closures can be automatically converted using the [`IntoFunction`] trait. -/// -/// # Example -/// -/// Most of the time, a [`DynamicFunction`] can be created using the [`IntoFunction`] trait: -/// -/// ``` -/// # use bevy_reflect::func::args::ArgList; -/// # use bevy_reflect::func::{DynamicFunction, IntoFunction}; -/// fn add(a: i32, b: i32) -> i32 { -/// a + b -/// } -/// -/// // Convert the function into a dynamic function using `IntoFunction::into_function` -/// let mut func: DynamicFunction = add.into_function(); -/// -/// // Dynamically call the function: -/// let args = ArgList::default().push_owned(25_i32).push_owned(75_i32); -/// let value = func.call(args).unwrap().unwrap_owned(); -/// -/// // Check the result: -/// assert_eq!(value.try_downcast_ref::(), Some(&100)); -/// ``` -/// -/// However, in some cases, these functions may need to be created manually: -/// -/// ``` -/// # use bevy_reflect::func::{ArgList, DynamicFunction, FunctionInfo, IntoFunction, Return, ReturnInfo}; -/// # use bevy_reflect::func::args::ArgInfo; -/// fn append(value: String, list: &mut Vec) -> &mut String { -/// list.push(value); -/// list.last_mut().unwrap() -/// } -/// -/// // Due to the return value being a reference that is not tied to the first argument, -/// // this will fail to compile: -/// // let mut func: DynamicFunction = append.into_function(); -/// -/// // Instead, we need to define the function manually. -/// // We start by defining the shape of the function: -/// let info = FunctionInfo::named("append") -/// .with_arg::("value") -/// .with_arg::<&mut Vec>("list") -/// .with_return::<&mut String>(); -/// -/// // Then we define the dynamic function, which will be used to call our `append` function: -/// let mut func = DynamicFunction::new(|mut args| { -/// // Arguments are removed from the list in order: -/// let arg0 = args.take::()?; -/// let arg1 = args.take::<&mut Vec>()?; -/// -/// // Then we can call our function and return the result: -/// Ok(Return::Mut(append(arg0, arg1))) -/// }, info); -/// -/// let mut list = Vec::::new(); -/// -/// // Dynamically call the function: -/// let args = ArgList::default().push_owned("Hello, World".to_string()).push_mut(&mut list); -/// let value = func.call(args).unwrap().unwrap_mut(); -/// -/// // Mutate the return value: -/// value.try_downcast_mut::().unwrap().push_str("!!!"); -/// -/// // Check the result: -/// assert_eq!(list, vec!["Hello, World!!!"]); -/// ``` -/// -/// [module-level documentation]: crate::func -pub struct DynamicFunction { - pub(super) info: FunctionInfo, - pub(super) func: Arc Fn(ArgList<'a>) -> FunctionResult<'a> + Send + Sync + 'static>, -} - -impl DynamicFunction { - /// Create a new dynamic [`DynamicFunction`]. - /// - /// The given function can be used to call out to a regular function, closure, or method. - /// - /// It's important that the function signature matches the provided [`FunctionInfo`]. - /// This info may be used by consumers of the function for validation and debugging. - pub fn new Fn(ArgList<'a>) -> FunctionResult<'a> + Send + Sync + 'static>( - func: F, - info: FunctionInfo, - ) -> Self { - Self { - info, - func: Arc::new(func), - } - } - - /// Set the name of the function. - /// - /// For [`DynamicFunctions`] created using [`IntoFunction`], - /// the default name will always be the full path to the function as returned by [`std::any::type_name`]. - /// - /// [`DynamicFunctions`]: DynamicFunction - pub fn with_name(mut self, name: impl Into>) -> Self { - self.info = self.info.with_name(name); - self - } - - /// Set the arguments of the function. - /// - /// It's important that the arguments match the intended function signature, - /// as this can be used by consumers of the function for validation and debugging. - pub fn with_args(mut self, args: Vec) -> Self { - self.info = self.info.with_args(args); - self - } - - /// Set the return information of the function. - pub fn with_return_info(mut self, return_info: ReturnInfo) -> Self { - self.info = self.info.with_return_info(return_info); - self - } - - /// Call the function with the given arguments. - /// - /// # Example - /// - /// ``` - /// # use bevy_reflect::func::{IntoFunction, ArgList}; - /// fn add(a: i32, b: i32) -> i32 { - /// a + b - /// } - /// - /// let func = add.into_function(); - /// let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); - /// let result = func.call(args).unwrap().unwrap_owned(); - /// assert_eq!(result.try_take::().unwrap(), 100); - /// ``` - pub fn call<'a>(&self, args: ArgList<'a>) -> FunctionResult<'a> { - (self.func)(args) - } - - /// Returns the function info. - pub fn info(&self) -> &FunctionInfo { - &self.info - } - - /// The [name] of the function. - /// - /// If this [`DynamicFunction`] was created using [`IntoFunction`], - /// then the name will default to one of the following: - /// - If the function was anonymous (e.g. `|a: i32, b: i32| { a + b }`), - /// then the name will be `None` - /// - If the function was named (e.g. `fn add(a: i32, b: i32) -> i32 { a + b }`), - /// then the name will be the full path to the function as returned by [`std::any::type_name`]. - /// - /// This can be overridden using [`with_name`]. - /// - /// [name]: FunctionInfo::name - /// [`with_name`]: Self::with_name - pub fn name(&self) -> Option<&Cow<'static, str>> { - self.info.name() - } -} - -/// Outputs the function signature. -/// -/// This takes the format: `DynamicFunction(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type})`. -/// -/// Names for arguments are optional and will default to `_` if not provided. -impl Debug for DynamicFunction { - fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - let name = self.info.name().unwrap_or(&Cow::Borrowed("_")); - write!(f, "DynamicFunction(fn {name}(")?; - - for (index, arg) in self.info.args().iter().enumerate() { - let name = arg.name().unwrap_or("_"); - let ty = arg.type_path(); - write!(f, "{name}: {ty}")?; - - if index + 1 < self.info.args().len() { - write!(f, ", ")?; - } - } - - let ret = self.info.return_info().type_path(); - write!(f, ") -> {ret})") - } -} - -impl Clone for DynamicFunction { - fn clone(&self) -> Self { - Self { - info: self.info.clone(), - func: Arc::clone(&self.func), - } - } -} - -impl IntoFunction<()> for DynamicFunction { - #[inline] - fn into_function(self) -> DynamicFunction { - self - } -} - -impl IntoClosure<'_, ()> for DynamicFunction { - #[inline] - fn into_closure(self) -> DynamicClosure<'static> { - DynamicClosure::from(self) - } -} - -impl IntoClosureMut<'_, ()> for DynamicFunction { - #[inline] - fn into_closure_mut(self) -> DynamicClosureMut<'static> { - DynamicClosureMut::from(self) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::func::Return; - - #[test] - fn should_overwrite_function_name() { - fn foo() {} - - let func = foo.into_function().with_name("my_function"); - assert_eq!(func.info().name().unwrap(), "my_function"); - } - - #[test] - fn should_convert_dynamic_function_with_into_function() { - fn make_function, M>(f: F) -> DynamicFunction { - f.into_function() - } - - let function: DynamicFunction = make_function(|| {}); - let _: DynamicFunction = make_function(function); - } - - #[test] - fn should_allow_manual_function_construction() { - #[allow(clippy::ptr_arg)] - fn get(index: usize, list: &Vec) -> &String { - &list[index] - } - - let func = DynamicFunction::new( - |mut args| { - let list = args.pop::<&Vec>()?; - let index = args.pop::()?; - Ok(Return::Ref(get(index, list))) - }, - FunctionInfo::anonymous() - .with_name("get") - .with_arg::("index") - .with_arg::<&Vec>("list") - .with_return::<&String>(), - ); - - let list = vec![String::from("foo")]; - let value = func - .call(ArgList::new().push_owned(0_usize).push_ref(&list)) - .unwrap() - .unwrap_ref() - .try_downcast_ref::() - .unwrap(); - assert_eq!(value, "foo"); - } -} diff --git a/crates/bevy_reflect/src/func/info.rs b/crates/bevy_reflect/src/func/info.rs index 6b4c03ed6a126..7d263cde889ed 100644 --- a/crates/bevy_reflect/src/func/info.rs +++ b/crates/bevy_reflect/src/func/info.rs @@ -5,13 +5,13 @@ use bevy_utils::all_tuples; use crate::func::args::{ArgInfo, GetOwnership, Ownership}; use crate::TypePath; -/// Type information for a [`DynamicFunction`] or [`DynamicClosure`]. +/// Type information for a [`DynamicClosure`] or [`DynamicClosureMut`]. /// /// This information can be retrieved from certain functions and closures /// using the [`TypedFunction`] trait. /// -/// [`DynamicFunction`]: crate::func::DynamicFunction /// [`DynamicClosure`]: crate::func::DynamicClosure +/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut #[derive(Debug, Clone)] pub struct FunctionInfo { name: Option>, @@ -105,13 +105,13 @@ impl FunctionInfo { /// The name of the function. /// - /// For [`DynamicFunctions`] created using [`IntoFunction`] or [`DynamicClosures`] created using [`IntoClosure`], + /// For [`DynamicClosures`] created using [`IntoClosure`] or [`DynamicClosureMuts`] created using [`IntoClosureMut`], /// the name will always be the full path to the function as returned by [`std::any::type_name`]. /// - /// [`DynamicFunctions`]: crate::func::DynamicFunction - /// [`IntoFunction`]: crate::func::IntoFunction /// [`DynamicClosures`]: crate::func::DynamicClosure /// [`IntoClosure`]: crate::func::IntoClosure + /// [`DynamicClosureMuts`]: crate::func::DynamicClosureMut + /// [`IntoClosureMut`]: crate::func::IntoClosureMut pub fn name(&self) -> Option<&Cow<'static, str>> { self.name.as_ref() } @@ -132,10 +132,10 @@ impl FunctionInfo { } } -/// Information about the return type of a [`DynamicFunction`] or [`DynamicClosure`]. +/// Information about the return type of a [`DynamicClosure`] or [`DynamicClosureMut`]. /// -/// [`DynamicFunction`]: crate::func::DynamicFunction /// [`DynamicClosure`]: crate::func::DynamicClosure +/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut #[derive(Debug, Clone)] pub struct ReturnInfo { type_path: &'static str, diff --git a/crates/bevy_reflect/src/func/into_function.rs b/crates/bevy_reflect/src/func/into_function.rs deleted file mode 100644 index 965661aa7ac9a..0000000000000 --- a/crates/bevy_reflect/src/func/into_function.rs +++ /dev/null @@ -1,180 +0,0 @@ -use std::panic::{RefUnwindSafe, UnwindSafe}; - -use crate::func::function::DynamicFunction; -use crate::func::{ReflectFn, TypedFunction}; - -/// A trait for types that can be converted into a [`DynamicFunction`]. -/// -/// This trait is automatically implemented for many standard Rust functions -/// that also implement [`ReflectFn`] and [`TypedFunction`]. -/// -/// To handle types such as closures that capture references to their environment, -/// see [`IntoClosure`] instead. -/// -/// See the [module-level documentation] for more information. -/// -/// [`IntoClosure`]: crate::func::IntoClosure -/// [module-level documentation]: crate::func -pub trait IntoFunction { - /// Converts [`Self`] into a [`DynamicFunction`]. - fn into_function(self) -> DynamicFunction; -} - -impl IntoFunction<(Marker1, Marker2)> for F -where - F: ReflectFn<'static, Marker1> - + TypedFunction - // Ideally, we'd only implement `IntoFunction` on actual function types - // (i.e. functions that do not capture their environment at all), - // but this would only work if users first explicitly coerced their functions - // to a function pointer like `(add as fn(i32, i32) -> i32).into_function()`, - // which is certainly not the best user experience. - // So as a compromise, we'll stick to allowing any type that implements - // `ReflectFn` and `TypedFunction`, but also add the following trait bounds - // that all `fn` types implement: - + Clone - + Copy - + Send - + Sync - + Unpin - + UnwindSafe - + RefUnwindSafe - + 'static, -{ - fn into_function(self) -> DynamicFunction { - // Note that to further guarantee that `self` is a true `fn` type, - // we could add a compile time assertion that `F` is zero-sized. - // However, we don't do this because it would prevent users from - // converting function pointers into `DynamicFunction`s. - - DynamicFunction::new(move |args| self.reflect_call(args), Self::function_info()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate as bevy_reflect; - use crate::func::ArgList; - use bevy_reflect_derive::Reflect; - - #[test] - fn should_create_dynamic_function_from_function() { - fn add(a: i32, b: i32) -> i32 { - a + b - } - - let func = add.into_function(); - let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); - let result = func.call(args).unwrap().unwrap_owned(); - assert_eq!(result.try_downcast_ref::(), Some(&100)); - } - - #[test] - fn should_create_dynamic_function_from_function_pointer() { - fn add(a: i32, b: i32) -> i32 { - a + b - } - - let func = (add as fn(i32, i32) -> i32).into_function(); - let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); - let result = func.call(args).unwrap().unwrap_owned(); - assert_eq!(result.try_downcast_ref::(), Some(&100)); - } - - #[test] - fn should_create_dynamic_function_from_anonymous_function() { - let func = (|a: i32, b: i32| a + b).into_function(); - let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); - let result = func.call(args).unwrap().unwrap_owned(); - assert_eq!(result.try_downcast_ref::(), Some(&100)); - } - - #[test] - fn should_create_dynamic_function_from_method() { - #[derive(Reflect, Debug, PartialEq)] - struct Foo(i32); - - impl Foo { - pub fn add(&self, other: &Foo) -> Foo { - Foo(self.0 + other.0) - } - } - - let foo_a = Foo(25); - let foo_b = Foo(75); - - let func = Foo::add.into_function(); - let args = ArgList::new().push_ref(&foo_a).push_ref(&foo_b); - let result = func.call(args).unwrap().unwrap_owned(); - assert_eq!(result.try_downcast_ref::(), Some(&Foo(100))); - } - - #[test] - fn should_allow_zero_args() { - fn foo() -> String { - String::from("Hello, World!") - } - - let func = foo.into_function(); - let args = ArgList::new(); - let result = func.call(args).unwrap().unwrap_owned(); - assert_eq!( - result.try_downcast_ref::(), - Some(&String::from("Hello, World!")) - ); - } - - #[test] - fn should_allow_unit_return() { - fn foo(_: i32) {} - - let func = foo.into_function(); - let args = ArgList::new().push_owned(123_i32); - let result = func.call(args).unwrap(); - assert!(result.is_unit()); - } - - #[test] - fn should_allow_reference_return() { - fn foo<'a>(value: &'a i32, _: String, _: &bool) -> &'a i32 { - value - } - - let value: i32 = 123; - let func = foo.into_function(); - let args = ArgList::new() - .push_ref(&value) - .push_owned(String::from("Hello, World!")) - .push_ref(&true); - let result = func.call(args).unwrap().unwrap_ref(); - assert_eq!(result.try_downcast_ref::(), Some(&123)); - } - - #[test] - fn should_allow_mutable_reference_return() { - fn foo<'a>(value: &'a mut i32, _: String, _: &bool) -> &'a mut i32 { - value - } - - let mut value: i32 = 123; - let func = foo.into_function(); - let args = ArgList::new() - .push_mut(&mut value) - .push_owned(String::from("Hello, World!")) - .push_ref(&true); - let result = func.call(args).unwrap().unwrap_mut(); - assert_eq!(result.try_downcast_mut::(), Some(&mut 123)); - } - - #[test] - fn should_default_with_function_type_name() { - fn foo() {} - - let func = foo.into_function(); - assert_eq!( - func.info().name().unwrap(), - "bevy_reflect::func::into_function::tests::should_default_with_function_type_name::foo" - ); - } -} diff --git a/crates/bevy_reflect/src/func/mod.rs b/crates/bevy_reflect/src/func/mod.rs index 172c1a0409474..e1881cf8ec1d6 100644 --- a/crates/bevy_reflect/src/func/mod.rs +++ b/crates/bevy_reflect/src/func/mod.rs @@ -1,10 +1,10 @@ //! Reflection-based dynamic functions. //! //! This module provides a way to pass around and call functions dynamically -//! using the [`DynamicFunction`], [`DynamicClosure`], and [`DynamicClosureMut`] types. +//! using the [`DynamicClosure`] and [`DynamicClosureMut`] types. //! //! Many simple functions and closures can be automatically converted to these types -//! using the [`IntoFunction`], [`IntoClosure`], and [`IntoClosureMut`] traits, respectively. +//! using the [`IntoClosure`] and [`IntoClosureMut`] traits, respectively. //! //! Once this dynamic representation is created, it can be called with a set of arguments provided //! via an [`ArgList`]. @@ -17,12 +17,12 @@ //! ``` //! # use bevy_reflect::PartialReflect; //! # use bevy_reflect::func::args::ArgList; -//! # use bevy_reflect::func::{DynamicFunction, FunctionResult, IntoFunction, Return}; +//! # use bevy_reflect::func::{DynamicClosure, FunctionResult, IntoClosure, Return}; //! fn add(a: i32, b: i32) -> i32 { //! a + b //! } //! -//! let mut func: DynamicFunction = add.into_function(); +//! let mut func: DynamicClosure = add.into_closure(); //! let args: ArgList = ArgList::default() //! // Pushing a known type with owned ownership //! .push_owned(25_i32) @@ -69,8 +69,7 @@ //! functions are a subset of immutable closures which are a subset of mutable closures. //! //! This means that, in terms of traits, you could imagine that any type that implements -//! [`IntoFunction`], also implements [`IntoClosure`] and [`IntoClosureMut`]. -//! And every type that implements [`IntoClosure`] also implements [`IntoClosureMut`]. +//! [`IntoClosure`] also implements [`IntoClosureMut`]. //! //! # Valid Signatures //! @@ -93,7 +92,7 @@ //! namely the [lack of variadic generics] and certain [coherence issues]. //! //! For other functions that don't conform to one of the above signatures, -//! [`DynamicFunction`] and [`DynamicClosure`] can instead be created manually. +//! [`DynamicClosure`] and [`DynamicClosureMut`] can instead be created manually. //! //! [`PartialReflect`]: crate::PartialReflect //! [`Reflect`]: crate::Reflect @@ -103,9 +102,7 @@ pub use args::{ArgError, ArgList, ArgValue}; pub use closures::*; pub use error::*; -pub use function::*; pub use info::*; -pub use into_function::*; pub use reflect_fn::*; pub use reflect_fn_mut::*; pub use registry::*; @@ -114,9 +111,7 @@ pub use return_type::*; pub mod args; mod closures; mod error; -mod function; mod info; -mod into_function; pub(crate) mod macros; mod reflect_fn; mod reflect_fn_mut; @@ -136,7 +131,7 @@ mod tests { fn should_error_on_missing_args() { fn foo(_: i32) {} - let func = foo.into_function(); + let func = foo.into_closure(); let args = ArgList::new(); let result = func.call(args); assert_eq!( @@ -152,7 +147,7 @@ mod tests { fn should_error_on_too_many_args() { fn foo() {} - let func = foo.into_function(); + let func = foo.into_closure(); let args = ArgList::new().push_owned(123_i32); let result = func.call(args); assert_eq!( @@ -168,7 +163,7 @@ mod tests { fn should_error_on_invalid_arg_type() { fn foo(_: i32) {} - let func = foo.into_function(); + let func = foo.into_closure(); let args = ArgList::new().push_owned(123_u32); let result = func.call(args); assert_eq!( @@ -185,7 +180,7 @@ mod tests { fn should_error_on_invalid_arg_ownership() { fn foo(_: &i32) {} - let func = foo.into_function(); + let func = foo.into_closure(); let args = ArgList::new().push_owned(123_i32); let result = func.call(args); assert_eq!( diff --git a/crates/bevy_reflect/src/func/registry.rs b/crates/bevy_reflect/src/func/registry.rs index f1297a925a392..dfa6c8571b814 100644 --- a/crates/bevy_reflect/src/func/registry.rs +++ b/crates/bevy_reflect/src/func/registry.rs @@ -11,12 +11,9 @@ use crate::func::{DynamicClosure, FunctionRegistrationError, IntoClosure}; /// This is the function-equivalent to the [`TypeRegistry`]. /// /// All functions and closures are stored as `'static` closures via [`DynamicClosure<'static>`]. -/// [`DynamicClosure`] is used instead of [`DynamicFunction`] as it can represent both functions and closures, -/// allowing registered functions to contain captured environment data. /// /// [reflected functions]: crate::func /// [`TypeRegistry`]: crate::TypeRegistry -/// [`DynamicFunction`]: crate::func::DynamicFunction #[derive(Default)] pub struct FunctionRegistry { /// Maps function [names] to their respective [`DynamicClosures`]. @@ -30,7 +27,7 @@ impl FunctionRegistry { /// Attempts to register the given function. /// /// This function accepts both functions/closures that satisfy [`IntoClosure`] - /// and direct [`DynamicFunction`]/[`DynamicClosure`] instances. + /// and direct [`DynamicClosure`] instances. /// The given function will internally be stored as a [`DynamicClosure<'static>`] /// and mapped according to its [name]. /// @@ -63,7 +60,7 @@ impl FunctionRegistry { /// Functions cannot be registered more than once. /// /// ``` - /// # use bevy_reflect::func::{DynamicFunction, FunctionRegistrationError, FunctionRegistry, IntoClosure}; + /// # use bevy_reflect::func::{FunctionRegistrationError, FunctionRegistry, IntoClosure}; /// fn add(a: i32, b: i32) -> i32 { /// a + b /// } @@ -83,7 +80,7 @@ impl FunctionRegistry { /// Anonymous functions and closures should be registered using [`register_with_name`] or given a name using [`DynamicClosure::with_name`]. /// /// ``` - /// # use bevy_reflect::func::{DynamicFunction, FunctionRegistrationError, FunctionRegistry, IntoClosure}; + /// # use bevy_reflect::func::{FunctionRegistrationError, FunctionRegistry, IntoClosure}; /// /// let anonymous = || -> i32 { 123 }; /// @@ -99,7 +96,6 @@ impl FunctionRegistry { /// assert!(result.is_ok()); /// ``` /// - /// [`DynamicFunction`]: crate::func::DynamicFunction /// [name]: DynamicClosure::name /// [`register_with_name`]: Self::register_with_name /// [`overwrite_registration`]: Self::overwrite_registration @@ -125,7 +121,7 @@ impl FunctionRegistry { /// Attempts to register the given function with the given name. /// /// This function accepts both functions/closures that satisfy [`IntoClosure`] - /// and direct [`DynamicFunction`]/[`DynamicClosure`] instances. + /// and direct [`DynamicClosure`] instances. /// The given function will internally be stored as a [`DynamicClosure<'static>`] /// with its [name] set to the given name. /// @@ -193,7 +189,6 @@ impl FunctionRegistry { /// registry.register_with_name("my_function", two).unwrap(); /// ``` /// - /// [`DynamicFunction`]: crate::func::DynamicFunction /// [name]: DynamicClosure::name /// [`register`]: Self::register /// [`overwrite_registration_with_name`]: Self::overwrite_registration_with_name @@ -213,7 +208,7 @@ impl FunctionRegistry { /// Registers the given function, overwriting any existing registration. /// /// This function accepts both functions/closures that satisfy [`IntoClosure`] - /// and direct [`DynamicFunction`]/[`DynamicClosure`] instances. + /// and direct [`DynamicClosure`] instances. /// The given function will internally be stored as a [`DynamicClosure<'static>`] /// and mapped according to its [name]. /// @@ -228,7 +223,6 @@ impl FunctionRegistry { /// /// Returns the previous function with the same name, if any. /// - /// [`DynamicFunction`]: crate::func::DynamicFunction /// [name]: DynamicClosure::name /// [`overwrite_registration_with_name`]: Self::overwrite_registration_with_name /// [`register`]: Self::register @@ -251,7 +245,7 @@ impl FunctionRegistry { /// Registers the given function, overwriting any existing registration. /// /// This function accepts both functions/closures that satisfy [`IntoClosure`] - /// and direct [`DynamicFunction`]/[`DynamicClosure`] instances. + /// and direct [`DynamicClosure`] instances. /// The given function will internally be stored as a [`DynamicClosure<'static>`] /// with its [name] set to the given name. /// @@ -264,7 +258,6 @@ impl FunctionRegistry { /// /// Returns the previous function with the same name, if any. /// - /// [`DynamicFunction`]: crate::func::DynamicFunction /// [name]: DynamicClosure::name /// [`register_with_name`]: Self::register_with_name /// [`overwrite_registration`]: Self::overwrite_registration @@ -347,7 +340,7 @@ impl FunctionRegistryArc { #[cfg(test)] mod tests { use super::*; - use crate::func::{ArgList, IntoFunction}; + use crate::func::{ArgList, IntoClosure}; #[test] fn should_register_function() { @@ -392,7 +385,7 @@ mod tests { 123 } - let function = foo.into_function().with_name("custom_name"); + let function = foo.into_closure().with_name("custom_name"); let mut registry = FunctionRegistry::default(); registry.register(function).unwrap(); @@ -431,7 +424,7 @@ mod tests { let mut registry = FunctionRegistry::default(); registry.register(foo).unwrap(); - let result = registry.register(bar.into_function().with_name(name)); + let result = registry.register(bar.into_closure().with_name(name)); assert!(matches!( result, @@ -459,7 +452,7 @@ mod tests { let mut registry = FunctionRegistry::default(); registry.register(foo).unwrap(); registry - .overwrite_registration(bar.into_function().with_name(name)) + .overwrite_registration(bar.into_closure().with_name(name)) .unwrap(); assert_eq!(registry.len(), 1); @@ -473,7 +466,7 @@ mod tests { fn should_error_on_missing_name() { let foo = || -> i32 { 123 }; - let function = foo.into_function(); + let function = foo.into_closure(); let mut registry = FunctionRegistry::default(); let result = registry.register(function); diff --git a/crates/bevy_reflect/src/func/return_type.rs b/crates/bevy_reflect/src/func/return_type.rs index 02f76c974ee22..7961d932b13b4 100644 --- a/crates/bevy_reflect/src/func/return_type.rs +++ b/crates/bevy_reflect/src/func/return_type.rs @@ -1,9 +1,9 @@ use crate::PartialReflect; -/// The return type of a [`DynamicFunction`] or [`DynamicClosure`]. +/// The return type of a [`DynamicClosure`] or [`DynamicClosureMut`]. /// -/// [`DynamicFunction`]: crate::func::DynamicFunction /// [`DynamicClosure`]: crate::func::DynamicClosure +/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut #[derive(Debug)] pub enum Return<'a> { /// The function returns nothing (i.e. it returns `()`). @@ -62,14 +62,15 @@ impl<'a> Return<'a> { /// A trait for types that can be converted into a [`Return`] value. /// /// This trait exists so that types can be automatically converted into a [`Return`] -/// by [`IntoFunction`]. +/// by [`ReflectFn`] and [`ReflectFnMut`]. /// /// This trait is used instead of a blanket [`Into`] implementation due to coherence issues: /// we can't implement `Into` for both `T` and `&T`/`&mut T`. /// /// This trait is automatically implemented when using the `Reflect` [derive macro]. /// -/// [`IntoFunction`]: crate::func::IntoFunction +/// [`ReflectFn`]: crate::func::ReflectFn +/// [`ReflectFnMut`]: crate::func::ReflectFnMut /// [derive macro]: derive@crate::Reflect pub trait IntoReturn { /// Converts [`Self`] into a [`Return`] value. diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 87e770483529e..ab6dd27a17bc5 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -574,7 +574,7 @@ pub mod prelude { }; #[cfg(feature = "functions")] - pub use crate::func::IntoFunction; + pub use crate::func::{IntoClosure, IntoClosureMut}; } pub use array::*; diff --git a/examples/reflection/function_reflection.rs b/examples/reflection/function_reflection.rs index 25fe09e639db0..11965048017a4 100644 --- a/examples/reflection/function_reflection.rs +++ b/examples/reflection/function_reflection.rs @@ -7,8 +7,8 @@ //! processing deserialized reflection data, or even just storing type-erased versions of your functions. use bevy::reflect::func::{ - ArgList, DynamicClosure, DynamicClosureMut, DynamicFunction, FunctionError, FunctionInfo, - IntoClosure, IntoClosureMut, IntoFunction, Return, + ArgList, DynamicClosure, DynamicClosureMut, FunctionError, FunctionInfo, IntoClosure, + IntoClosureMut, Return, }; use bevy::reflect::{PartialReflect, Reflect}; @@ -35,12 +35,12 @@ fn main() { // However, you'll notice that we have to know the types of the arguments and return value at compile time. // This means there's not really a way to store or call these functions dynamically at runtime. // Luckily, Bevy's reflection crate comes with a set of tools for doing just that! - // We do this by first converting our function into the reflection-based `DynamicFunction` type - // using the `IntoFunction` trait. - let function: DynamicFunction = dbg!(add.into_function()); + // We do this by first converting our function into the reflection-based `DynamicClosure` type + // using the `IntoClosure` trait. + let function: DynamicClosure<'static> = dbg!(add.into_closure()); - // This time, you'll notice that `DynamicFunction` doesn't take any information about the function's arguments or return value. - // This is because `DynamicFunction` checks the types of the arguments and return value at runtime. + // This time, you'll notice that `DynamicClosure` doesn't take any information about the function's arguments or return value. + // This is because `DynamicClosure` checks the types of the arguments and return value at runtime. // Now we can generate a list of arguments: let args: ArgList = dbg!(ArgList::new().push_owned(2_i32).push_owned(2_i32)); @@ -82,7 +82,7 @@ fn main() { // As stated before, this works for many kinds of simple functions. // Functions with non-reflectable arguments or return values may not be able to be converted. - // Generic functions are also not supported (unless manually monomorphized like `foo::.into_function()`). + // Generic functions are also not supported (unless manually monomorphized like `foo::.into_closure()`). // Additionally, the lifetime of the return value is tied to the lifetime of the first argument. // However, this means that many methods (i.e. functions with a `self` parameter) are also supported: #[derive(Reflect, Default)] @@ -104,20 +104,20 @@ fn main() { let mut data = Data::default(); - let set_value = dbg!(Data::set_value.into_function()); + let set_value = dbg!(Data::set_value.into_closure()); let args = dbg!(ArgList::new().push_mut(&mut data)).push_owned(String::from("Hello, world!")); dbg!(set_value.call(args).unwrap()); assert_eq!(data.value, "Hello, world!"); - let get_value = dbg!(Data::get_value.into_function()); + let get_value = dbg!(Data::get_value.into_closure()); let args = dbg!(ArgList::new().push_ref(&data)); let return_value = dbg!(get_value.call(args).unwrap()); let value: &dyn PartialReflect = return_value.unwrap_ref(); assert_eq!(value.try_downcast_ref::().unwrap(), "Hello, world!"); - // Lastly, for more complex use cases, you can always create a custom `DynamicFunction` manually. - // This is useful for functions that can't be converted via the `IntoFunction` trait. - // For example, this function doesn't implement `IntoFunction` due to the fact that + // Lastly, for more complex use cases, you can always create a custom `DynamicClosure` manually. + // This is useful for functions that can't be converted via the `IntoClosure` trait. + // For example, this function doesn't implement `IntoClosure` due to the fact that // the lifetime of the return value is not tied to the lifetime of the first argument. fn get_or_insert(value: i32, container: &mut Option) -> &i32 { if container.is_none() { @@ -127,7 +127,7 @@ fn main() { container.as_ref().unwrap() } - let get_or_insert_function = dbg!(DynamicFunction::new( + let get_or_insert_function = dbg!(DynamicClosure::new( |mut args| { // We can optionally add a check to ensure we were given the correct number of arguments. if args.len() != 2 { From b0223bbf8769460997f30ed27cb6a3286dd22034 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sat, 17 Aug 2024 11:21:25 -0700 Subject: [PATCH 2/8] Remove separate `closures` module --- crates/bevy_reflect/src/func/args/info.rs | 4 ++-- crates/bevy_reflect/src/func/closures/mod.rs | 9 --------- .../src/func/{closures => }/dynamic_closure.rs | 0 .../src/func/{closures => }/dynamic_closure_mut.rs | 0 .../src/func/{closures => }/into_closure.rs | 0 .../src/func/{closures => }/into_closure_mut.rs | 2 +- crates/bevy_reflect/src/func/mod.rs | 10 ++++++++-- 7 files changed, 11 insertions(+), 14 deletions(-) delete mode 100644 crates/bevy_reflect/src/func/closures/mod.rs rename crates/bevy_reflect/src/func/{closures => }/dynamic_closure.rs (100%) rename crates/bevy_reflect/src/func/{closures => }/dynamic_closure_mut.rs (100%) rename crates/bevy_reflect/src/func/{closures => }/into_closure.rs (100%) rename crates/bevy_reflect/src/func/{closures => }/into_closure_mut.rs (97%) diff --git a/crates/bevy_reflect/src/func/args/info.rs b/crates/bevy_reflect/src/func/args/info.rs index ff5cc7bcf4ee0..eb5e9165e7933 100644 --- a/crates/bevy_reflect/src/func/args/info.rs +++ b/crates/bevy_reflect/src/func/args/info.rs @@ -6,8 +6,8 @@ use crate::TypePath; /// Type information for an [`Arg`] used in a [`DynamicClosure`] or [`DynamicClosureMut`]. /// /// [`Arg`]: crate::func::args::Arg -/// [`DynamicClosure`]: crate::func::closures::DynamicClosure -/// [`DynamicClosureMut`]: crate::func::closures::DynamicClosureMut +/// [`DynamicClosure`]: crate::func::DynamicClosure +/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut #[derive(Debug, Clone)] pub struct ArgInfo { /// The index of the argument within its function. diff --git a/crates/bevy_reflect/src/func/closures/mod.rs b/crates/bevy_reflect/src/func/closures/mod.rs deleted file mode 100644 index cdba3bab061c8..0000000000000 --- a/crates/bevy_reflect/src/func/closures/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub use dynamic_closure::*; -pub use dynamic_closure_mut::*; -pub use into_closure::*; -pub use into_closure_mut::*; - -mod dynamic_closure; -mod dynamic_closure_mut; -mod into_closure; -mod into_closure_mut; diff --git a/crates/bevy_reflect/src/func/closures/dynamic_closure.rs b/crates/bevy_reflect/src/func/dynamic_closure.rs similarity index 100% rename from crates/bevy_reflect/src/func/closures/dynamic_closure.rs rename to crates/bevy_reflect/src/func/dynamic_closure.rs diff --git a/crates/bevy_reflect/src/func/closures/dynamic_closure_mut.rs b/crates/bevy_reflect/src/func/dynamic_closure_mut.rs similarity index 100% rename from crates/bevy_reflect/src/func/closures/dynamic_closure_mut.rs rename to crates/bevy_reflect/src/func/dynamic_closure_mut.rs diff --git a/crates/bevy_reflect/src/func/closures/into_closure.rs b/crates/bevy_reflect/src/func/into_closure.rs similarity index 100% rename from crates/bevy_reflect/src/func/closures/into_closure.rs rename to crates/bevy_reflect/src/func/into_closure.rs diff --git a/crates/bevy_reflect/src/func/closures/into_closure_mut.rs b/crates/bevy_reflect/src/func/into_closure_mut.rs similarity index 97% rename from crates/bevy_reflect/src/func/closures/into_closure_mut.rs rename to crates/bevy_reflect/src/func/into_closure_mut.rs index 96359fcedcc61..ed0f7480bb977 100644 --- a/crates/bevy_reflect/src/func/closures/into_closure_mut.rs +++ b/crates/bevy_reflect/src/func/into_closure_mut.rs @@ -10,7 +10,7 @@ use crate::func::{DynamicClosureMut, ReflectFnMut, TypedFunction}; /// See the [module-level documentation] for more information. /// /// [`ReflectFn`]: crate::func::ReflectFn -/// [`IntoClosure`]: crate::func::closures::IntoClosure +/// [`IntoClosure`]: crate::func::IntoClosure /// [module-level documentation]: crate::func pub trait IntoClosureMut<'env, Marker> { /// Converts [`Self`] into a [`DynamicClosureMut`]. diff --git a/crates/bevy_reflect/src/func/mod.rs b/crates/bevy_reflect/src/func/mod.rs index e1881cf8ec1d6..58c80421284fc 100644 --- a/crates/bevy_reflect/src/func/mod.rs +++ b/crates/bevy_reflect/src/func/mod.rs @@ -100,18 +100,24 @@ //! [coherence issues]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#coherence-leak-check pub use args::{ArgError, ArgList, ArgValue}; -pub use closures::*; +pub use dynamic_closure::*; +pub use dynamic_closure_mut::*; pub use error::*; pub use info::*; +pub use into_closure::*; +pub use into_closure_mut::*; pub use reflect_fn::*; pub use reflect_fn_mut::*; pub use registry::*; pub use return_type::*; pub mod args; -mod closures; +mod dynamic_closure; +mod dynamic_closure_mut; mod error; mod info; +mod into_closure; +mod into_closure_mut; pub(crate) mod macros; mod reflect_fn; mod reflect_fn_mut; From f14db59c8789c838599f7fa11d2a1498190ed3c7 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sat, 17 Aug 2024 11:34:46 -0700 Subject: [PATCH 3/8] Replace DynamicClosure(Mut) with DynamicCallable(Mut) --- benches/benches/bevy_reflect/function.rs | 12 +- crates/bevy_app/src/app.rs | 24 ++-- crates/bevy_app/src/sub_app.rs | 4 +- .../bevy_reflect/compile_fail/tests/func.rs | 2 +- .../arguments_fail.rs | 8 +- .../closure_fail.rs | 6 +- .../return_fail.rs | 10 +- crates/bevy_reflect/src/func/args/arg.rs | 12 +- crates/bevy_reflect/src/func/args/from_arg.rs | 6 +- crates/bevy_reflect/src/func/args/info.rs | 18 +-- crates/bevy_reflect/src/func/args/list.rs | 6 +- crates/bevy_reflect/src/func/args/mod.rs | 6 +- .../bevy_reflect/src/func/dynamic_closure.rs | 62 +++++----- .../src/func/dynamic_closure_mut.rs | 66 +++++------ crates/bevy_reflect/src/func/error.rs | 12 +- crates/bevy_reflect/src/func/info.rs | 22 ++-- crates/bevy_reflect/src/func/into_closure.rs | 22 ++-- .../bevy_reflect/src/func/into_closure_mut.rs | 30 ++--- crates/bevy_reflect/src/func/mod.rs | 20 ++-- crates/bevy_reflect/src/func/registry.rs | 110 +++++++++--------- crates/bevy_reflect/src/func/return_type.rs | 6 +- crates/bevy_reflect/src/lib.rs | 2 +- examples/reflection/function_reflection.rs | 42 +++---- 23 files changed, 254 insertions(+), 254 deletions(-) rename crates/bevy_reflect/compile_fail/tests/{into_closure => into_callable}/arguments_fail.rs (72%) rename crates/bevy_reflect/compile_fail/tests/{into_closure => into_callable}/closure_fail.rs (61%) rename crates/bevy_reflect/compile_fail/tests/{into_closure => into_callable}/return_fail.rs (59%) diff --git a/benches/benches/bevy_reflect/function.rs b/benches/benches/bevy_reflect/function.rs index 3d9754c63bfd5..bc06be65939d4 100644 --- a/benches/benches/bevy_reflect/function.rs +++ b/benches/benches/bevy_reflect/function.rs @@ -1,4 +1,4 @@ -use bevy_reflect::func::{ArgList, IntoClosure, TypedFunction}; +use bevy_reflect::func::{ArgList, IntoCallable, TypedFunction}; use bevy_reflect::prelude::*; use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; @@ -24,19 +24,19 @@ fn typed(c: &mut Criterion) { fn into(c: &mut Criterion) { c.benchmark_group("into") .bench_function("function", |b| { - b.iter(|| add.into_closure()); + b.iter(|| add.into_callable()); }) .bench_function("closure", |b| { let capture = 25; let closure = |a: i32| a + capture; - b.iter(|| closure.into_closure()); + b.iter(|| closure.into_callable()); }); } fn call(c: &mut Criterion) { c.benchmark_group("call") .bench_function("function", |b| { - let add = add.into_closure(); + let add = add.into_callable(); b.iter_batched( || ArgList::new().push_owned(75_i32).push_owned(25_i32), |args| add.call(args), @@ -45,7 +45,7 @@ fn call(c: &mut Criterion) { }) .bench_function("closure", |b| { let capture = 25; - let add = (|a: i32| a + capture).into_closure(); + let add = (|a: i32| a + capture).into_callable(); b.iter_batched( || ArgList::new().push_owned(75_i32), |args| add.call(args), @@ -56,7 +56,7 @@ fn call(c: &mut Criterion) { fn clone(c: &mut Criterion) { c.benchmark_group("clone").bench_function("function", |b| { - let add = add.into_closure(); + let add = add.into_callable(); b.iter(|| add.clone()); }); } diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index d1fa331a23101..12dbb5ebefc11 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -605,16 +605,16 @@ impl App { /// Registers the given function into the [`AppFunctionRegistry`] resource. /// - /// The given function will internally be stored as a [`DynamicClosure`] + /// The given function will internally be stored as a [`DynamicCallable`] /// and mapped according to its [name]. /// /// Because the function must have a name, /// anonymous functions (e.g. `|a: i32, b: i32| { a + b }`) and closures must instead - /// be registered using [`register_function_with_name`] or converted to a [`DynamicClosure`] - /// and named using [`DynamicClosure::with_name`]. + /// be registered using [`register_function_with_name`] or converted to a [`DynamicCallable`] + /// and named using [`DynamicCallable::with_name`]. /// Failure to do so will result in a panic. /// - /// Only types that implement [`IntoClosure`] may be registered via this method. + /// Only types that implement [`IntoCallable`] may be registered via this method. /// /// See [`FunctionRegistry::register`] for more information. /// @@ -650,7 +650,7 @@ impl App { /// .register_function(add); /// ``` /// - /// Anonymous functions and closures should be registered using [`register_function_with_name`] or given a name using [`DynamicClosure::with_name`]. + /// Anonymous functions and closures should be registered using [`register_function_with_name`] or given a name using [`DynamicCallable::with_name`]. /// /// ```should_panic /// use bevy_app::App; @@ -660,15 +660,15 @@ impl App { /// ``` /// /// [`register_function_with_name`]: Self::register_function_with_name - /// [`DynamicClosure`]: bevy_reflect::func::DynamicClosure + /// [`DynamicCallable`]: bevy_reflect::func::DynamicCallable /// [name]: bevy_reflect::func::FunctionInfo::name - /// [`DynamicClosure::with_name`]: bevy_reflect::func::DynamicClosure::with_name - /// [`IntoClosure`]: bevy_reflect::func::IntoClosure + /// [`DynamicCallable::with_name`]: bevy_reflect::func::DynamicCallable::with_name + /// [`IntoCallable`]: bevy_reflect::func::IntoCallable /// [`FunctionRegistry::register`]: bevy_reflect::func::FunctionRegistry::register #[cfg(feature = "reflect_functions")] pub fn register_function(&mut self, function: F) -> &mut Self where - F: bevy_reflect::func::IntoClosure<'static, Marker> + 'static, + F: bevy_reflect::func::IntoCallable<'static, Marker> + 'static, { self.main_mut().register_function(function); self @@ -689,7 +689,7 @@ impl App { /// For named functions (e.g. `fn add(a: i32, b: i32) -> i32 { a + b }`) where a custom name is not needed, /// it's recommended to use [`register_function`] instead as the generated name is guaranteed to be unique. /// - /// Only types that implement [`IntoClosure`] may be registered via this method. + /// Only types that implement [`IntoCallable`] may be registered via this method. /// /// See [`FunctionRegistry::register_with_name`] for more information. /// @@ -738,7 +738,7 @@ impl App { /// /// [type name]: std::any::type_name /// [`register_function`]: Self::register_function - /// [`IntoClosure`]: bevy_reflect::func::IntoClosure + /// [`IntoCallable`]: bevy_reflect::func::IntoCallable /// [`FunctionRegistry::register_with_name`]: bevy_reflect::func::FunctionRegistry::register_with_name #[cfg(feature = "reflect_functions")] pub fn register_function_with_name( @@ -747,7 +747,7 @@ impl App { function: F, ) -> &mut Self where - F: bevy_reflect::func::IntoClosure<'static, Marker> + 'static, + F: bevy_reflect::func::IntoCallable<'static, Marker> + 'static, { self.main_mut().register_function_with_name(name, function); self diff --git a/crates/bevy_app/src/sub_app.rs b/crates/bevy_app/src/sub_app.rs index fc91ca2f34d89..c12ea9f0c88bf 100644 --- a/crates/bevy_app/src/sub_app.rs +++ b/crates/bevy_app/src/sub_app.rs @@ -413,7 +413,7 @@ impl SubApp { #[cfg(feature = "reflect_functions")] pub fn register_function(&mut self, function: F) -> &mut Self where - F: bevy_reflect::func::IntoClosure<'static, Marker> + 'static, + F: bevy_reflect::func::IntoCallable<'static, Marker> + 'static, { let registry = self.world.resource_mut::(); registry.write().register(function).unwrap(); @@ -428,7 +428,7 @@ impl SubApp { function: F, ) -> &mut Self where - F: bevy_reflect::func::IntoClosure<'static, Marker> + 'static, + F: bevy_reflect::func::IntoCallable<'static, Marker> + 'static, { let registry = self.world.resource_mut::(); registry.write().register_with_name(name, function).unwrap(); diff --git a/crates/bevy_reflect/compile_fail/tests/func.rs b/crates/bevy_reflect/compile_fail/tests/func.rs index cd83f8759e8ad..64b587fc6a848 100644 --- a/crates/bevy_reflect/compile_fail/tests/func.rs +++ b/crates/bevy_reflect/compile_fail/tests/func.rs @@ -1,3 +1,3 @@ fn main() -> compile_fail_utils::ui_test::Result<()> { - compile_fail_utils::test("reflect_into_closure", "tests/into_closure") + compile_fail_utils::test("reflect_into_callable", "tests/into_callable") } diff --git a/crates/bevy_reflect/compile_fail/tests/into_closure/arguments_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_callable/arguments_fail.rs similarity index 72% rename from crates/bevy_reflect/compile_fail/tests/into_closure/arguments_fail.rs rename to crates/bevy_reflect/compile_fail/tests/into_callable/arguments_fail.rs index 143b2fa49e635..c01c39c9cfda1 100644 --- a/crates/bevy_reflect/compile_fail/tests/into_closure/arguments_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/into_callable/arguments_fail.rs @@ -1,6 +1,6 @@ #![allow(unused)] -use bevy_reflect::func::IntoClosure; +use bevy_reflect::func::IntoCallable; use bevy_reflect::Reflect; fn pass(_: i32) {} @@ -30,11 +30,11 @@ struct Foo; fn argument_not_reflect(foo: Foo) {} fn main() { - let _ = pass.into_closure(); + let _ = pass.into_callable(); - let _ = too_many_arguments.into_closure(); + let _ = too_many_arguments.into_callable(); //~^ E0599 - let _ = argument_not_reflect.into_closure(); + let _ = argument_not_reflect.into_callable(); //~^ E0599 } diff --git a/crates/bevy_reflect/compile_fail/tests/into_closure/closure_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_callable/closure_fail.rs similarity index 61% rename from crates/bevy_reflect/compile_fail/tests/into_closure/closure_fail.rs rename to crates/bevy_reflect/compile_fail/tests/into_callable/closure_fail.rs index 747fc48321012..07aa86a65be7e 100644 --- a/crates/bevy_reflect/compile_fail/tests/into_closure/closure_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/into_callable/closure_fail.rs @@ -1,6 +1,6 @@ #![allow(unused)] -use bevy_reflect::func::{DynamicClosure, IntoClosure}; +use bevy_reflect::func::{DynamicCallable, IntoCallable}; use bevy_reflect::Reflect; fn main() { @@ -8,11 +8,11 @@ fn main() { let closure_capture_owned = move || println!("{}", value); // Pass: - let _: DynamicClosure<'static> = closure_capture_owned.into_closure(); + let _: DynamicCallable<'static> = closure_capture_owned.into_callable(); let value = String::from("Hello, World!"); let closure_capture_reference = || println!("{}", value); //~^ ERROR: `value` does not live long enough - let _: DynamicClosure<'static> = closure_capture_reference.into_closure(); + let _: DynamicCallable<'static> = closure_capture_reference.into_callable(); } diff --git a/crates/bevy_reflect/compile_fail/tests/into_closure/return_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_callable/return_fail.rs similarity index 59% rename from crates/bevy_reflect/compile_fail/tests/into_closure/return_fail.rs rename to crates/bevy_reflect/compile_fail/tests/into_callable/return_fail.rs index 373b8be86c97d..5e2b8c81e219b 100644 --- a/crates/bevy_reflect/compile_fail/tests/into_closure/return_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/into_callable/return_fail.rs @@ -1,6 +1,6 @@ #![allow(unused)] -use bevy_reflect::func::IntoClosure; +use bevy_reflect::func::IntoCallable; use bevy_reflect::Reflect; fn pass() -> i32 { @@ -22,13 +22,13 @@ fn return_with_invalid_lifetime<'a, 'b>(a: &'a String, b: &'b String) -> &'b Str } fn main() { - let _ = pass.into_closure(); + let _ = pass.into_callable(); - let _ = return_not_reflect.into_closure(); + let _ = return_not_reflect.into_callable(); //~^ E0599 - let _ = return_with_lifetime_pass.into_closure(); + let _ = return_with_lifetime_pass.into_callable(); - let _ = return_with_invalid_lifetime.into_closure(); + let _ = return_with_invalid_lifetime.into_callable(); //~^ E0599 } diff --git a/crates/bevy_reflect/src/func/args/arg.rs b/crates/bevy_reflect/src/func/args/arg.rs index b769439e88a9e..7910243e3d5b2 100644 --- a/crates/bevy_reflect/src/func/args/arg.rs +++ b/crates/bevy_reflect/src/func/args/arg.rs @@ -2,10 +2,10 @@ use crate::func::args::{ArgError, FromArg, Ownership}; use crate::{PartialReflect, Reflect, TypePath}; use std::ops::Deref; -/// Represents an argument that can be passed to a [`DynamicClosure`] or [`DynamicClosureMut`]. +/// Represents an argument that can be passed to a [`DynamicCallable`] or [`DynamicCallableMut`]. /// -/// [`DynamicClosure`]: crate::func::DynamicClosure -/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut +/// [`DynamicCallable`]: crate::func::DynamicCallable +/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut #[derive(Debug)] pub struct Arg<'a> { index: usize, @@ -179,10 +179,10 @@ impl<'a> Arg<'a> { } } -/// Represents an argument that can be passed to a [`DynamicClosure`] or [`DynamicClosureMut`]. +/// Represents an argument that can be passed to a [`DynamicCallable`] or [`DynamicCallableMut`]. /// -/// [`DynamicClosure`]: crate::func::DynamicClosure -/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut +/// [`DynamicCallable`]: crate::func::DynamicCallable +/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut #[derive(Debug)] pub enum ArgValue<'a> { Owned(Box), diff --git a/crates/bevy_reflect/src/func/args/from_arg.rs b/crates/bevy_reflect/src/func/args/from_arg.rs index 757c55e94d881..90f82dedea12b 100644 --- a/crates/bevy_reflect/src/func/args/from_arg.rs +++ b/crates/bevy_reflect/src/func/args/from_arg.rs @@ -3,7 +3,7 @@ use crate::func::args::{Arg, ArgError}; /// A trait for types that can be created from an [`Arg`]. /// /// This trait exists so that types can be automatically converted into an [`Arg`] -/// so they can be put into an [`ArgList`] and passed to a [`DynamicClosure`] or [`DynamicClosureMut`]. +/// so they can be put into an [`ArgList`] and passed to a [`DynamicCallable`] or [`DynamicCallableMut`]. /// /// This trait is used instead of a blanket [`From`] implementation due to coherence issues: /// we can't implement `From` for both `T` and `&T`/`&mut T`. @@ -11,8 +11,8 @@ use crate::func::args::{Arg, ArgError}; /// This trait is automatically implemented when using the `Reflect` [derive macro]. /// /// [`ArgList`]: crate::func::args::ArgList -/// [`DynamicClosure`]: crate::func::DynamicClosure -/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut +/// [`DynamicCallable`]: crate::func::DynamicCallable +/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut /// [derive macro]: derive@crate::Reflect pub trait FromArg { /// The type to convert into. diff --git a/crates/bevy_reflect/src/func/args/info.rs b/crates/bevy_reflect/src/func/args/info.rs index eb5e9165e7933..e6ac3bdeede9a 100644 --- a/crates/bevy_reflect/src/func/args/info.rs +++ b/crates/bevy_reflect/src/func/args/info.rs @@ -3,11 +3,11 @@ use alloc::borrow::Cow; use crate::func::args::{GetOwnership, Ownership}; use crate::TypePath; -/// Type information for an [`Arg`] used in a [`DynamicClosure`] or [`DynamicClosureMut`]. +/// Type information for an [`Arg`] used in a [`DynamicCallable`] or [`DynamicCallableMut`]. /// /// [`Arg`]: crate::func::args::Arg -/// [`DynamicClosure`]: crate::func::DynamicClosure -/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut +/// [`DynamicCallable`]: crate::func::DynamicCallable +/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut #[derive(Debug, Clone)] pub struct ArgInfo { /// The index of the argument within its function. @@ -55,14 +55,14 @@ impl ArgInfo { /// This is because the name needs to be manually set using [`Self::with_name`] /// since the name can't be inferred from the function type alone. /// - /// For [`DynamicClosures`] created using [`IntoClosure`] - /// and [`DynamicClosureMuts`] created using [`IntoClosureMut`], + /// For [`DynamicCallables`] created using [`IntoCallable`] + /// and [`DynamicCallableMuts`] created using [`IntoCallableMut`], /// the name will always be `None`. /// - /// [`DynamicClosures`]: crate::func::DynamicClosure - /// [`IntoClosure`]: crate::func::IntoClosure - /// [`DynamicClosureMuts`]: crate::func::DynamicClosureMut - /// [`IntoClosureMut`]: crate::func::IntoClosureMut + /// [`DynamicCallables`]: crate::func::DynamicCallable + /// [`IntoCallable`]: crate::func::IntoCallable + /// [`DynamicCallableMuts`]: crate::func::DynamicCallableMut + /// [`IntoCallableMut`]: crate::func::IntoCallableMut pub fn name(&self) -> Option<&str> { self.name.as_deref() } diff --git a/crates/bevy_reflect/src/func/args/list.rs b/crates/bevy_reflect/src/func/args/list.rs index 81711a528d46f..a965ef636a2b9 100644 --- a/crates/bevy_reflect/src/func/args/list.rs +++ b/crates/bevy_reflect/src/func/args/list.rs @@ -3,7 +3,7 @@ use crate::func::ArgError; use crate::{PartialReflect, Reflect, TypePath}; use std::collections::VecDeque; -/// A list of arguments that can be passed to a [`DynamicClosure`] or [`DynamicClosureMut`]. +/// A list of arguments that can be passed to a [`DynamicCallable`] or [`DynamicCallableMut`]. /// /// # Example /// @@ -26,8 +26,8 @@ use std::collections::VecDeque; /// ``` /// /// [arguments]: Arg -/// [`DynamicClosure`]: crate::func::DynamicClosure -/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut +/// [`DynamicCallable`]: crate::func::DynamicCallable +/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut #[derive(Default, Debug)] pub struct ArgList<'a> { list: VecDeque>, diff --git a/crates/bevy_reflect/src/func/args/mod.rs b/crates/bevy_reflect/src/func/args/mod.rs index a0c1d505749f3..361e23d419ef6 100644 --- a/crates/bevy_reflect/src/func/args/mod.rs +++ b/crates/bevy_reflect/src/func/args/mod.rs @@ -1,7 +1,7 @@ -//! Argument types and utilities for working with [`DynamicClosure`] and [`DynamicClosureMut`]. +//! Argument types and utilities for working with [`DynamicCallable`] and [`DynamicCallableMut`]. //! -//! [`DynamicClosure`]: crate::func::DynamicClosure -//! [`DynamicClosureMut`]: crate::func::DynamicClosureMut +//! [`DynamicCallable`]: crate::func::DynamicCallable +//! [`DynamicCallableMut`]: crate::func::DynamicCallableMut pub use arg::*; pub use error::*; diff --git a/crates/bevy_reflect/src/func/dynamic_closure.rs b/crates/bevy_reflect/src/func/dynamic_closure.rs index 0bb773595631a..6302cee875cf1 100644 --- a/crates/bevy_reflect/src/func/dynamic_closure.rs +++ b/crates/bevy_reflect/src/func/dynamic_closure.rs @@ -1,6 +1,6 @@ use crate::func::args::{ArgInfo, ArgList}; use crate::func::info::FunctionInfo; -use crate::func::{DynamicClosureMut, FunctionResult, IntoClosure, IntoClosureMut, ReturnInfo}; +use crate::func::{DynamicCallableMut, FunctionResult, IntoCallable, IntoCallableMut, ReturnInfo}; use alloc::borrow::Cow; use core::fmt::{Debug, Formatter}; use std::sync::Arc; @@ -9,19 +9,19 @@ use std::sync::Arc; /// /// This type can be used to represent any Rust closure that captures its environment immutably. /// For closures that need to capture their environment mutably, -/// see [`DynamicClosureMut`]. +/// see [`DynamicCallableMut`]. /// /// See the [module-level documentation] for more information. /// /// You will generally not need to construct this manually. -/// Instead, many functions and closures can be automatically converted using the [`IntoClosure`] trait. +/// Instead, many functions and closures can be automatically converted using the [`IntoCallable`] trait. /// /// # Example /// -/// Most of the time, a [`DynamicClosure`] can be created using the [`IntoClosure`] trait: +/// Most of the time, a [`DynamicCallable`] can be created using the [`IntoCallable`] trait: /// /// ``` -/// # use bevy_reflect::func::{ArgList, DynamicClosure, FunctionInfo, IntoClosure}; +/// # use bevy_reflect::func::{ArgList, DynamicCallable, FunctionInfo, IntoCallable}; /// # /// let punct = String::from("!!!"); /// @@ -29,8 +29,8 @@ use std::sync::Arc; /// format!("{}{}", text, punct) /// }; /// -/// // Convert the closure into a dynamic closure using `IntoClosure::into_closure` -/// let mut func: DynamicClosure = punctuate.into_closure(); +/// // Convert the closure into a dynamic closure using `IntoCallable::into_callable` +/// let mut func: DynamicCallable = punctuate.into_callable(); /// /// // Dynamically call the closure: /// let text = String::from("Hello, world"); @@ -40,13 +40,13 @@ use std::sync::Arc; /// // Check the result: /// assert_eq!(value.try_take::().unwrap(), "Hello, world!!!"); /// ``` -pub struct DynamicClosure<'env> { +pub struct DynamicCallable<'env> { pub(super) info: FunctionInfo, pub(super) func: Arc Fn(ArgList<'a>) -> FunctionResult<'a> + Send + Sync + 'env>, } -impl<'env> DynamicClosure<'env> { - /// Create a new [`DynamicClosure`]. +impl<'env> DynamicCallable<'env> { + /// Create a new [`DynamicCallable`]. /// /// The given function can be used to call out to a regular function, closure, or method. /// @@ -64,13 +64,13 @@ impl<'env> DynamicClosure<'env> { /// Set the name of the closure. /// - /// For [`DynamicClosures`] created using [`IntoClosure`], + /// For [`DynamicCallable`] created using [`IntoCallable`], /// the default name will always be the full path to the closure as returned by [`std::any::type_name`]. /// /// This default name generally does not contain the actual name of the closure, only its module path. /// It is therefore recommended to set the name manually using this method. /// - /// [`DynamicClosures`]: DynamicClosure + /// [`DynamicCallable`]: DynamicCallable pub fn with_name(mut self, name: impl Into>) -> Self { self.info = self.info.with_name(name); self @@ -96,13 +96,13 @@ impl<'env> DynamicClosure<'env> { /// # Example /// /// ``` - /// # use bevy_reflect::func::{IntoClosure, ArgList}; + /// # use bevy_reflect::func::{IntoCallable, ArgList}; /// let c = 23; /// let add = |a: i32, b: i32| -> i32 { /// a + b + c /// }; /// - /// let mut func = add.into_closure().with_name("add"); + /// let mut func = add.into_callable().with_name("add"); /// let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); /// let result = func.call(args).unwrap().unwrap_owned(); /// assert_eq!(result.try_take::().unwrap(), 123); @@ -118,7 +118,7 @@ impl<'env> DynamicClosure<'env> { /// The [name] of the closure. /// - /// If this [`DynamicClosure`] was created using [`IntoClosure`], + /// If this [`DynamicCallable`] was created using [`IntoCallable`], /// then the default name will always be `None`. /// /// This can be overridden using [`with_name`]. @@ -132,13 +132,13 @@ impl<'env> DynamicClosure<'env> { /// Outputs the closure's signature. /// -/// This takes the format: `DynamicClosure(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type})`. +/// This takes the format: `DynamicCallable(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type})`. /// /// Names for arguments and the closure itself are optional and will default to `_` if not provided. -impl<'env> Debug for DynamicClosure<'env> { +impl<'env> Debug for DynamicCallable<'env> { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { let name = self.info.name().unwrap_or(&Cow::Borrowed("_")); - write!(f, "DynamicClosure(fn {name}(")?; + write!(f, "DynamicCallable(fn {name}(")?; for (index, arg) in self.info.args().iter().enumerate() { let name = arg.name().unwrap_or("_"); @@ -155,7 +155,7 @@ impl<'env> Debug for DynamicClosure<'env> { } } -impl<'env> Clone for DynamicClosure<'env> { +impl<'env> Clone for DynamicCallable<'env> { fn clone(&self) -> Self { Self { info: self.info.clone(), @@ -164,17 +164,17 @@ impl<'env> Clone for DynamicClosure<'env> { } } -impl<'env> IntoClosure<'env, ()> for DynamicClosure<'env> { +impl<'env> IntoCallable<'env, ()> for DynamicCallable<'env> { #[inline] - fn into_closure(self) -> DynamicClosure<'env> { + fn into_callable(self) -> DynamicCallable<'env> { self } } -impl<'env> IntoClosureMut<'env, ()> for DynamicClosure<'env> { +impl<'env> IntoCallableMut<'env, ()> for DynamicCallable<'env> { #[inline] - fn into_closure_mut(self) -> DynamicClosureMut<'env> { - DynamicClosureMut::from(self) + fn into_callable_mut(self) -> DynamicCallableMut<'env> { + DynamicCallableMut::from(self) } } @@ -186,20 +186,20 @@ mod tests { fn should_overwrite_closure_name() { let c = 23; let func = (|a: i32, b: i32| a + b + c) - .into_closure() + .into_callable() .with_name("my_closure"); assert_eq!(func.info().name().unwrap(), "my_closure"); } #[test] - fn should_convert_dynamic_closure_with_into_closure() { - fn make_closure<'env, F: IntoClosure<'env, M>, M>(f: F) -> DynamicClosure<'env> { - f.into_closure() + fn should_convert_dynamic_closure_with_into_callable() { + fn make_closure<'env, F: IntoCallable<'env, M>, M>(f: F) -> DynamicCallable<'env> { + f.into_callable() } let c = 23; - let closure: DynamicClosure = make_closure(|a: i32, b: i32| a + b + c); - let _: DynamicClosure = make_closure(closure); + let closure: DynamicCallable = make_closure(|a: i32, b: i32| a + b + c); + let _: DynamicCallable = make_closure(closure); } #[test] @@ -208,7 +208,7 @@ mod tests { let greet = |name: &String| -> String { format!("{}, {}!", hello, name) }; - let greet = greet.into_closure().with_name("greet"); + let greet = greet.into_callable().with_name("greet"); let clone = greet.clone(); assert_eq!(greet.name().unwrap(), "greet"); diff --git a/crates/bevy_reflect/src/func/dynamic_closure_mut.rs b/crates/bevy_reflect/src/func/dynamic_closure_mut.rs index 11f46de63602f..99823e190b7ea 100644 --- a/crates/bevy_reflect/src/func/dynamic_closure_mut.rs +++ b/crates/bevy_reflect/src/func/dynamic_closure_mut.rs @@ -3,27 +3,27 @@ use core::fmt::{Debug, Formatter}; use crate::func::args::{ArgInfo, ArgList}; use crate::func::info::FunctionInfo; -use crate::func::{DynamicClosure, FunctionResult, IntoClosureMut, ReturnInfo}; +use crate::func::{DynamicCallable, FunctionResult, IntoCallableMut, ReturnInfo}; /// A dynamic representation of a Rust closure. /// /// This type can be used to represent any Rust closure that captures its environment mutably. /// For closures that only need to capture their environment immutably, -/// consider using [`DynamicClosure`]. +/// consider using [`DynamicCallable`]. /// -/// This type can be seen as a superset of [`DynamicClosure`]. +/// This type can be seen as a superset of [`DynamicCallable`]. /// /// See the [module-level documentation] for more information. /// /// You will generally not need to construct this manually. -/// Instead, many functions and closures can be automatically converted using the [`IntoClosureMut`] trait. +/// Instead, many functions and closures can be automatically converted using the [`IntoCallableMut`] trait. /// /// # Example /// -/// Most of the time, a [`DynamicClosureMut`] can be created using the [`IntoClosureMut`] trait: +/// Most of the time, a [`DynamicCallableMut`] can be created using the [`IntoCallableMut`] trait: /// /// ``` -/// # use bevy_reflect::func::{ArgList, DynamicClosureMut, FunctionInfo, IntoClosureMut}; +/// # use bevy_reflect::func::{ArgList, DynamicCallableMut, FunctionInfo, IntoCallableMut}; /// # /// let mut list: Vec = vec![1, 2, 3]; /// @@ -34,8 +34,8 @@ use crate::func::{DynamicClosure, FunctionResult, IntoClosureMut, ReturnInfo}; /// old_value /// }; /// -/// // Convert the closure into a dynamic closure using `IntoClosureMut::into_closure_mut` -/// let mut func: DynamicClosureMut = replace.into_closure_mut(); +/// // Convert the closure into a dynamic closure using `IntoCallableMut::into_callable_mut` +/// let mut func: DynamicCallableMut = replace.into_callable_mut(); /// /// // Dynamically call the closure: /// let args = ArgList::default().push_owned(1_usize).push_owned(-2_i32); @@ -47,17 +47,17 @@ use crate::func::{DynamicClosure, FunctionResult, IntoClosureMut, ReturnInfo}; /// // Note that `func` still has a reference to `list`, /// // so we need to drop it before we can access `list` again. /// // Alternatively, we could have called the `func` using -/// // `DynamicClosureMut::call_once` to immediately consume the closure. +/// // `DynamicCallableMut::call_once` to immediately consume the closure. /// drop(func); /// assert_eq!(list, vec![1, -2, 3]); /// ``` -pub struct DynamicClosureMut<'env> { +pub struct DynamicCallableMut<'env> { info: FunctionInfo, func: Box FnMut(ArgList<'a>) -> FunctionResult<'a> + 'env>, } -impl<'env> DynamicClosureMut<'env> { - /// Create a new [`DynamicClosureMut`]. +impl<'env> DynamicCallableMut<'env> { + /// Create a new [`DynamicCallableMut`]. /// /// The given function can be used to call out to a regular function, closure, or method. /// @@ -75,13 +75,13 @@ impl<'env> DynamicClosureMut<'env> { /// Set the name of the closure. /// - /// For [`DynamicClosureMuts`] created using [`IntoClosureMut`], + /// For [`DynamicCallableMuts`] created using [`IntoCallableMut`], /// the default name will always be the full path to the closure as returned by [`std::any::type_name`]. /// /// This default name generally does not contain the actual name of the closure, only its module path. /// It is therefore recommended to set the name manually using this method. /// - /// [`DynamicClosureMuts`]: DynamicClosureMut + /// [`DynamicCallableMuts`]: DynamicCallableMut pub fn with_name(mut self, name: impl Into>) -> Self { self.info = self.info.with_name(name); self @@ -112,20 +112,20 @@ impl<'env> DynamicClosureMut<'env> { /// # Example /// /// ``` - /// # use bevy_reflect::func::{IntoClosureMut, ArgList}; + /// # use bevy_reflect::func::{IntoCallableMut, ArgList}; /// let mut total = 0; /// let add = |a: i32, b: i32| -> i32 { /// total = a + b; /// total /// }; /// - /// let mut func = add.into_closure_mut().with_name("add"); + /// let mut func = add.into_callable_mut().with_name("add"); /// let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); /// let result = func.call(args).unwrap().unwrap_owned(); /// assert_eq!(result.try_take::().unwrap(), 100); /// ``` /// - /// [`call_once`]: DynamicClosureMut::call_once + /// [`call_once`]: DynamicCallableMut::call_once pub fn call<'a>(&mut self, args: ArgList<'a>) -> FunctionResult<'a> { (self.func)(args) } @@ -138,11 +138,11 @@ impl<'env> DynamicClosureMut<'env> { /// # Example /// /// ``` - /// # use bevy_reflect::func::{IntoClosureMut, ArgList}; + /// # use bevy_reflect::func::{IntoCallableMut, ArgList}; /// let mut count = 0; /// let increment = |amount: i32| count += amount; /// - /// let increment_function = increment.into_closure_mut(); + /// let increment_function = increment.into_callable_mut(); /// let args = ArgList::new().push_owned(5_i32); /// /// // We need to drop `increment_function` here so that we @@ -162,7 +162,7 @@ impl<'env> DynamicClosureMut<'env> { /// The [name] of the closure. /// - /// If this [`DynamicClosureMut`] was created using [`IntoClosureMut`], + /// If this [`DynamicCallableMut`] was created using [`IntoCallableMut`], /// then the default name will always be `None`. /// /// This can be overridden using [`with_name`]. @@ -176,13 +176,13 @@ impl<'env> DynamicClosureMut<'env> { /// Outputs the closure's signature. /// -/// This takes the format: `DynamicClosureMut(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type})`. +/// This takes the format: `DynamicCallableMut(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type})`. /// /// Names for arguments and the closure itself are optional and will default to `_` if not provided. -impl<'env> Debug for DynamicClosureMut<'env> { +impl<'env> Debug for DynamicCallableMut<'env> { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { let name = self.info.name().unwrap_or(&Cow::Borrowed("_")); - write!(f, "DynamicClosureMut(fn {name}(")?; + write!(f, "DynamicCallableMut(fn {name}(")?; for (index, arg) in self.info.args().iter().enumerate() { let name = arg.name().unwrap_or("_"); @@ -199,9 +199,9 @@ impl<'env> Debug for DynamicClosureMut<'env> { } } -impl<'env> From> for DynamicClosureMut<'env> { +impl<'env> From> for DynamicCallableMut<'env> { #[inline] - fn from(closure: DynamicClosure<'env>) -> Self { + fn from(closure: DynamicCallable<'env>) -> Self { Self { info: closure.info, func: Box::new(move |args| (closure.func)(args)), @@ -209,9 +209,9 @@ impl<'env> From> for DynamicClosureMut<'env> { } } -impl<'env> IntoClosureMut<'env, ()> for DynamicClosureMut<'env> { +impl<'env> IntoCallableMut<'env, ()> for DynamicCallableMut<'env> { #[inline] - fn into_closure_mut(self) -> DynamicClosureMut<'env> { + fn into_callable_mut(self) -> DynamicCallableMut<'env> { self } } @@ -224,19 +224,19 @@ mod tests { fn should_overwrite_closure_name() { let mut total = 0; let func = (|a: i32, b: i32| total = a + b) - .into_closure_mut() + .into_callable_mut() .with_name("my_closure"); assert_eq!(func.info().name().unwrap(), "my_closure"); } #[test] - fn should_convert_dynamic_closure_mut_with_into_closure() { - fn make_closure<'env, F: IntoClosureMut<'env, M>, M>(f: F) -> DynamicClosureMut<'env> { - f.into_closure_mut() + fn should_convert_dynamic_closure_mut_with_into_callable() { + fn make_closure<'env, F: IntoCallableMut<'env, M>, M>(f: F) -> DynamicCallableMut<'env> { + f.into_callable_mut() } let mut total = 0; - let closure: DynamicClosureMut = make_closure(|a: i32, b: i32| total = a + b); - let _: DynamicClosureMut = make_closure(closure); + let closure: DynamicCallableMut = make_closure(|a: i32, b: i32| total = a + b); + let _: DynamicCallableMut = make_closure(closure); } } diff --git a/crates/bevy_reflect/src/func/error.rs b/crates/bevy_reflect/src/func/error.rs index 464ef83ee2cc3..c6bb850627322 100644 --- a/crates/bevy_reflect/src/func/error.rs +++ b/crates/bevy_reflect/src/func/error.rs @@ -3,10 +3,10 @@ use crate::func::Return; use alloc::borrow::Cow; use thiserror::Error; -/// An error that occurs when calling a [`DynamicClosure`] or [`DynamicClosureMut`]. +/// An error that occurs when calling a [`DynamicCallable`] or [`DynamicCallableMut`]. /// -/// [`DynamicClosure`]: crate::func::DynamicClosure -/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut +/// [`DynamicCallable`]: crate::func::DynamicCallable +/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut #[derive(Debug, Error, PartialEq)] pub enum FunctionError { /// An error occurred while converting an argument. @@ -17,13 +17,13 @@ pub enum FunctionError { ArgCountMismatch { expected: usize, received: usize }, } -/// The result of calling a dynamic [`DynamicClosure`] or [`DynamicClosureMut`]. +/// The result of calling a dynamic [`DynamicCallable`] or [`DynamicCallableMut`]. /// /// Returns `Ok(value)` if the function was called successfully, /// where `value` is the [`Return`] value of the function. /// -/// [`DynamicClosure`]: crate::func::DynamicClosure -/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut +/// [`DynamicCallable`]: crate::func::DynamicCallable +/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut pub type FunctionResult<'a> = Result, FunctionError>; /// An error that occurs when registering a function into a [`FunctionRegistry`]. diff --git a/crates/bevy_reflect/src/func/info.rs b/crates/bevy_reflect/src/func/info.rs index 7d263cde889ed..f47a306396f4b 100644 --- a/crates/bevy_reflect/src/func/info.rs +++ b/crates/bevy_reflect/src/func/info.rs @@ -5,13 +5,13 @@ use bevy_utils::all_tuples; use crate::func::args::{ArgInfo, GetOwnership, Ownership}; use crate::TypePath; -/// Type information for a [`DynamicClosure`] or [`DynamicClosureMut`]. +/// Type information for a [`DynamicCallable`] or [`DynamicCallableMut`]. /// /// This information can be retrieved from certain functions and closures /// using the [`TypedFunction`] trait. /// -/// [`DynamicClosure`]: crate::func::DynamicClosure -/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut +/// [`DynamicCallable`]: crate::func::DynamicCallable +/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut #[derive(Debug, Clone)] pub struct FunctionInfo { name: Option>, @@ -105,13 +105,13 @@ impl FunctionInfo { /// The name of the function. /// - /// For [`DynamicClosures`] created using [`IntoClosure`] or [`DynamicClosureMuts`] created using [`IntoClosureMut`], + /// For [`DynamicCallables`] created using [`IntoCallable`] or [`DynamicCallableMuts`] created using [`IntoCallableMut`], /// the name will always be the full path to the function as returned by [`std::any::type_name`]. /// - /// [`DynamicClosures`]: crate::func::DynamicClosure - /// [`IntoClosure`]: crate::func::IntoClosure - /// [`DynamicClosureMuts`]: crate::func::DynamicClosureMut - /// [`IntoClosureMut`]: crate::func::IntoClosureMut + /// [`DynamicCallables`]: crate::func::DynamicCallable + /// [`IntoCallable`]: crate::func::IntoCallable + /// [`DynamicCallableMuts`]: crate::func::DynamicCallableMut + /// [`IntoCallableMut`]: crate::func::IntoCallableMut pub fn name(&self) -> Option<&Cow<'static, str>> { self.name.as_ref() } @@ -132,10 +132,10 @@ impl FunctionInfo { } } -/// Information about the return type of a [`DynamicClosure`] or [`DynamicClosureMut`]. +/// Information about the return type of a [`DynamicCallable`] or [`DynamicCallableMut`]. /// -/// [`DynamicClosure`]: crate::func::DynamicClosure -/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut +/// [`DynamicCallable`]: crate::func::DynamicCallable +/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut #[derive(Debug, Clone)] pub struct ReturnInfo { type_path: &'static str, diff --git a/crates/bevy_reflect/src/func/into_closure.rs b/crates/bevy_reflect/src/func/into_closure.rs index ef7bfbe7ba854..bf1bffadc3ec1 100644 --- a/crates/bevy_reflect/src/func/into_closure.rs +++ b/crates/bevy_reflect/src/func/into_closure.rs @@ -1,6 +1,6 @@ -use crate::func::{DynamicClosure, ReflectFn, TypedFunction}; +use crate::func::{DynamicCallable, ReflectFn, TypedFunction}; -/// A trait for types that can be converted into a [`DynamicClosure`]. +/// A trait for types that can be converted into a [`DynamicCallable`]. /// /// This trait is automatically implemented for any type that implements /// [`ReflectFn`] and [`TypedFunction`]. @@ -8,17 +8,17 @@ use crate::func::{DynamicClosure, ReflectFn, TypedFunction}; /// See the [module-level documentation] for more information. /// /// [module-level documentation]: crate::func -pub trait IntoClosure<'env, Marker> { - /// Converts [`Self`] into a [`DynamicClosure`]. - fn into_closure(self) -> DynamicClosure<'env>; +pub trait IntoCallable<'env, Marker> { + /// Converts [`Self`] into a [`DynamicCallable`]. + fn into_callable(self) -> DynamicCallable<'env>; } -impl<'env, F, Marker1, Marker2> IntoClosure<'env, (Marker1, Marker2)> for F +impl<'env, F, Marker1, Marker2> IntoCallable<'env, (Marker1, Marker2)> for F where F: ReflectFn<'env, Marker1> + TypedFunction + Send + Sync + 'env, { - fn into_closure(self) -> DynamicClosure<'env> { - DynamicClosure::new(move |args| self.reflect_call(args), Self::function_info()) + fn into_callable(self) -> DynamicCallable<'env> { + DynamicCallable::new(move |args| self.reflect_call(args), Self::function_info()) } } @@ -30,7 +30,7 @@ mod tests { #[test] fn should_create_dynamic_closure_from_closure() { let c = 23; - let func = (|a: i32, b: i32| a + b + c).into_closure(); + let func = (|a: i32, b: i32| a + b + c).into_callable(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); let result = func.call(args).unwrap().unwrap_owned(); assert_eq!(result.try_downcast_ref::(), Some(&123)); @@ -42,7 +42,7 @@ mod tests { a + b } - let func = add.into_closure(); + let func = add.into_callable(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); let result = func.call(args).unwrap().unwrap_owned(); assert_eq!(result.try_downcast_ref::(), Some(&100)); @@ -51,7 +51,7 @@ mod tests { #[test] fn should_default_closure_name_to_none() { let c = 23; - let func = (|a: i32, b: i32| a + b + c).into_closure(); + let func = (|a: i32, b: i32| a + b + c).into_callable(); assert_eq!(func.info().name(), None); } } diff --git a/crates/bevy_reflect/src/func/into_closure_mut.rs b/crates/bevy_reflect/src/func/into_closure_mut.rs index ed0f7480bb977..8e210d38446ff 100644 --- a/crates/bevy_reflect/src/func/into_closure_mut.rs +++ b/crates/bevy_reflect/src/func/into_closure_mut.rs @@ -1,28 +1,28 @@ -use crate::func::{DynamicClosureMut, ReflectFnMut, TypedFunction}; +use crate::func::{DynamicCallableMut, ReflectFnMut, TypedFunction}; -/// A trait for types that can be converted into a [`DynamicClosureMut`]. +/// A trait for types that can be converted into a [`DynamicCallableMut`]. /// /// This trait is automatically implemented for any type that implements /// [`ReflectFnMut`] and [`TypedFunction`]. /// -/// This trait can be seen as a supertrait of [`IntoClosure`]. +/// This trait can be seen as a supertrait of [`IntoCallable`]. /// /// See the [module-level documentation] for more information. /// /// [`ReflectFn`]: crate::func::ReflectFn -/// [`IntoClosure`]: crate::func::IntoClosure +/// [`IntoCallable`]: crate::func::IntoCallable /// [module-level documentation]: crate::func -pub trait IntoClosureMut<'env, Marker> { - /// Converts [`Self`] into a [`DynamicClosureMut`]. - fn into_closure_mut(self) -> DynamicClosureMut<'env>; +pub trait IntoCallableMut<'env, Marker> { + /// Converts [`Self`] into a [`DynamicCallableMut`]. + fn into_callable_mut(self) -> DynamicCallableMut<'env>; } -impl<'env, F, Marker1, Marker2> IntoClosureMut<'env, (Marker1, Marker2)> for F +impl<'env, F, Marker1, Marker2> IntoCallableMut<'env, (Marker1, Marker2)> for F where F: ReflectFnMut<'env, Marker1> + TypedFunction + 'env, { - fn into_closure_mut(mut self) -> DynamicClosureMut<'env> { - DynamicClosureMut::new( + fn into_callable_mut(mut self) -> DynamicCallableMut<'env> { + DynamicCallableMut::new( move |args| self.reflect_call_mut(args), Self::function_info(), ) @@ -32,12 +32,12 @@ where #[cfg(test)] mod tests { use super::*; - use crate::func::{ArgList, IntoClosure}; + use crate::func::{ArgList, IntoCallable}; #[test] fn should_create_dynamic_closure_mut_from_closure() { let c = 23; - let func = (|a: i32, b: i32| a + b + c).into_closure(); + let func = (|a: i32, b: i32| a + b + c).into_callable(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); let result = func.call(args).unwrap().unwrap_owned(); assert_eq!(result.try_downcast_ref::(), Some(&123)); @@ -46,7 +46,7 @@ mod tests { #[test] fn should_create_dynamic_closure_mut_from_closure_with_mutable_capture() { let mut total = 0; - let func = (|a: i32, b: i32| total = a + b).into_closure_mut(); + let func = (|a: i32, b: i32| total = a + b).into_callable_mut(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); func.call_once(args).unwrap(); assert_eq!(total, 100); @@ -58,7 +58,7 @@ mod tests { a + b } - let mut func = add.into_closure_mut(); + let mut func = add.into_callable_mut(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); let result = func.call(args).unwrap().unwrap_owned(); assert_eq!(result.try_downcast_ref::(), Some(&100)); @@ -67,7 +67,7 @@ mod tests { #[test] fn should_default_closure_name_to_none() { let mut total = 0; - let func = (|a: i32, b: i32| total = a + b).into_closure_mut(); + let func = (|a: i32, b: i32| total = a + b).into_callable_mut(); assert_eq!(func.info().name(), None); } } diff --git a/crates/bevy_reflect/src/func/mod.rs b/crates/bevy_reflect/src/func/mod.rs index 58c80421284fc..3c9ca80ec38cd 100644 --- a/crates/bevy_reflect/src/func/mod.rs +++ b/crates/bevy_reflect/src/func/mod.rs @@ -1,10 +1,10 @@ //! Reflection-based dynamic functions. //! //! This module provides a way to pass around and call functions dynamically -//! using the [`DynamicClosure`] and [`DynamicClosureMut`] types. +//! using the [`DynamicCallable`] and [`DynamicCallableMut`] types. //! //! Many simple functions and closures can be automatically converted to these types -//! using the [`IntoClosure`] and [`IntoClosureMut`] traits, respectively. +//! using the [`IntoCallable`] and [`IntoCallableMut`] traits, respectively. //! //! Once this dynamic representation is created, it can be called with a set of arguments provided //! via an [`ArgList`]. @@ -17,12 +17,12 @@ //! ``` //! # use bevy_reflect::PartialReflect; //! # use bevy_reflect::func::args::ArgList; -//! # use bevy_reflect::func::{DynamicClosure, FunctionResult, IntoClosure, Return}; +//! # use bevy_reflect::func::{DynamicCallable, FunctionResult, IntoCallable, Return}; //! fn add(a: i32, b: i32) -> i32 { //! a + b //! } //! -//! let mut func: DynamicClosure = add.into_closure(); +//! let mut func: DynamicCallable = add.into_callable(); //! let args: ArgList = ArgList::default() //! // Pushing a known type with owned ownership //! .push_owned(25_i32) @@ -69,7 +69,7 @@ //! functions are a subset of immutable closures which are a subset of mutable closures. //! //! This means that, in terms of traits, you could imagine that any type that implements -//! [`IntoClosure`] also implements [`IntoClosureMut`]. +//! [`IntoCallable`] also implements [`IntoCallableMut`]. //! //! # Valid Signatures //! @@ -92,7 +92,7 @@ //! namely the [lack of variadic generics] and certain [coherence issues]. //! //! For other functions that don't conform to one of the above signatures, -//! [`DynamicClosure`] and [`DynamicClosureMut`] can instead be created manually. +//! [`DynamicCallable`] and [`DynamicCallableMut`] can instead be created manually. //! //! [`PartialReflect`]: crate::PartialReflect //! [`Reflect`]: crate::Reflect @@ -137,7 +137,7 @@ mod tests { fn should_error_on_missing_args() { fn foo(_: i32) {} - let func = foo.into_closure(); + let func = foo.into_callable(); let args = ArgList::new(); let result = func.call(args); assert_eq!( @@ -153,7 +153,7 @@ mod tests { fn should_error_on_too_many_args() { fn foo() {} - let func = foo.into_closure(); + let func = foo.into_callable(); let args = ArgList::new().push_owned(123_i32); let result = func.call(args); assert_eq!( @@ -169,7 +169,7 @@ mod tests { fn should_error_on_invalid_arg_type() { fn foo(_: i32) {} - let func = foo.into_closure(); + let func = foo.into_callable(); let args = ArgList::new().push_owned(123_u32); let result = func.call(args); assert_eq!( @@ -186,7 +186,7 @@ mod tests { fn should_error_on_invalid_arg_ownership() { fn foo(_: &i32) {} - let func = foo.into_closure(); + let func = foo.into_callable(); let args = ArgList::new().push_owned(123_i32); let result = func.call(args); assert_eq!( diff --git a/crates/bevy_reflect/src/func/registry.rs b/crates/bevy_reflect/src/func/registry.rs index dfa6c8571b814..258ab53e32752 100644 --- a/crates/bevy_reflect/src/func/registry.rs +++ b/crates/bevy_reflect/src/func/registry.rs @@ -4,37 +4,37 @@ use std::sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}; use bevy_utils::HashMap; -use crate::func::{DynamicClosure, FunctionRegistrationError, IntoClosure}; +use crate::func::{DynamicCallable, FunctionRegistrationError, IntoCallable}; /// A registry of [reflected functions]. /// /// This is the function-equivalent to the [`TypeRegistry`]. /// -/// All functions and closures are stored as `'static` closures via [`DynamicClosure<'static>`]. +/// All functions and closures are stored as `'static` closures via [`DynamicCallable<'static>`]. /// /// [reflected functions]: crate::func /// [`TypeRegistry`]: crate::TypeRegistry #[derive(Default)] pub struct FunctionRegistry { - /// Maps function [names] to their respective [`DynamicClosures`]. + /// Maps function [names] to their respective [`DynamicCallables`]. /// - /// [names]: DynamicClosure::name - /// [`DynamicClosures`]: DynamicClosure - functions: HashMap, DynamicClosure<'static>>, + /// [names]: DynamicCallable::name + /// [`DynamicCallables`]: DynamicCallable + functions: HashMap, DynamicCallable<'static>>, } impl FunctionRegistry { /// Attempts to register the given function. /// - /// This function accepts both functions/closures that satisfy [`IntoClosure`] - /// and direct [`DynamicClosure`] instances. - /// The given function will internally be stored as a [`DynamicClosure<'static>`] + /// This function accepts both functions/closures that satisfy [`IntoCallable`] + /// and direct [`DynamicCallable`] instances. + /// The given function will internally be stored as a [`DynamicCallable<'static>`] /// and mapped according to its [name]. /// /// Because the function must have a name, /// anonymous functions (e.g. `|a: i32, b: i32| { a + b }`) and closures must instead - /// be registered using [`register_with_name`] or converted to a [`DynamicClosure`] - /// and named using [`DynamicClosure::with_name`]. + /// be registered using [`register_with_name`] or converted to a [`DynamicCallable`] + /// and named using [`DynamicCallable::with_name`]. /// Failure to do so will result in an error being returned. /// /// If a registered function with the same name already exists, @@ -60,7 +60,7 @@ impl FunctionRegistry { /// Functions cannot be registered more than once. /// /// ``` - /// # use bevy_reflect::func::{FunctionRegistrationError, FunctionRegistry, IntoClosure}; + /// # use bevy_reflect::func::{FunctionRegistrationError, FunctionRegistry, IntoCallable}; /// fn add(a: i32, b: i32) -> i32 { /// a + b /// } @@ -73,14 +73,14 @@ impl FunctionRegistry { /// /// // Note that this simply relies on the name of the function to determine uniqueness. /// // You can rename the function to register a separate instance of it. - /// let result = registry.register(add.into_closure().with_name("add2")); + /// let result = registry.register(add.into_callable().with_name("add2")); /// assert!(result.is_ok()); /// ``` /// - /// Anonymous functions and closures should be registered using [`register_with_name`] or given a name using [`DynamicClosure::with_name`]. + /// Anonymous functions and closures should be registered using [`register_with_name`] or given a name using [`DynamicCallable::with_name`]. /// /// ``` - /// # use bevy_reflect::func::{FunctionRegistrationError, FunctionRegistry, IntoClosure}; + /// # use bevy_reflect::func::{FunctionRegistrationError, FunctionRegistry, IntoCallable}; /// /// let anonymous = || -> i32 { 123 }; /// @@ -92,11 +92,11 @@ impl FunctionRegistry { /// let result = registry.register_with_name("my_crate::add", |a: i32, b: i32| a + b); /// assert!(result.is_ok()); /// - /// let result = registry.register((|a: i32, b: i32| a * b).into_closure().with_name("my_crate::mul")); + /// let result = registry.register((|a: i32, b: i32| a * b).into_callable().with_name("my_crate::mul")); /// assert!(result.is_ok()); /// ``` /// - /// [name]: DynamicClosure::name + /// [name]: DynamicCallable::name /// [`register_with_name`]: Self::register_with_name /// [`overwrite_registration`]: Self::overwrite_registration pub fn register( @@ -104,15 +104,15 @@ impl FunctionRegistry { function: F, ) -> Result<&mut Self, FunctionRegistrationError> where - F: IntoClosure<'static, Marker> + 'static, + F: IntoCallable<'static, Marker> + 'static, { - let function = function.into_closure(); + let function = function.into_callable(); let name = function .name() .ok_or(FunctionRegistrationError::MissingName)? .clone(); self.functions - .try_insert(name, function.into_closure()) + .try_insert(name, function.into_callable()) .map_err(|err| FunctionRegistrationError::DuplicateName(err.entry.key().clone()))?; Ok(self) @@ -120,9 +120,9 @@ impl FunctionRegistry { /// Attempts to register the given function with the given name. /// - /// This function accepts both functions/closures that satisfy [`IntoClosure`] - /// and direct [`DynamicClosure`] instances. - /// The given function will internally be stored as a [`DynamicClosure<'static>`] + /// This function accepts both functions/closures that satisfy [`IntoCallable`] + /// and direct [`DynamicCallable`] instances. + /// The given function will internally be stored as a [`DynamicCallable<'static>`] /// with its [name] set to the given name. /// /// For named functions (e.g. `fn add(a: i32, b: i32) -> i32 { a + b }`) where a custom name is not needed, @@ -143,7 +143,7 @@ impl FunctionRegistry { /// Another approach could be to use the [type name] of the function, /// however, it should be noted that anonymous functions do _not_ have unique type names. /// - /// This method is a convenience around calling [`IntoClosure::into_closure`] and [`DynamicClosure::with_name`] + /// This method is a convenience around calling [`IntoCallable::into_callable`] and [`DynamicCallable::with_name`] /// on the function and inserting it into the registry using the [`register`] method. /// /// # Examples @@ -189,7 +189,7 @@ impl FunctionRegistry { /// registry.register_with_name("my_function", two).unwrap(); /// ``` /// - /// [name]: DynamicClosure::name + /// [name]: DynamicCallable::name /// [`register`]: Self::register /// [`overwrite_registration_with_name`]: Self::overwrite_registration_with_name /// [type name]: std::any::type_name @@ -199,23 +199,23 @@ impl FunctionRegistry { function: F, ) -> Result<&mut Self, FunctionRegistrationError> where - F: IntoClosure<'static, Marker> + 'static, + F: IntoCallable<'static, Marker> + 'static, { - let function = function.into_closure().with_name(name); + let function = function.into_callable().with_name(name); self.register(function) } /// Registers the given function, overwriting any existing registration. /// - /// This function accepts both functions/closures that satisfy [`IntoClosure`] - /// and direct [`DynamicClosure`] instances. - /// The given function will internally be stored as a [`DynamicClosure<'static>`] + /// This function accepts both functions/closures that satisfy [`IntoCallable`] + /// and direct [`DynamicCallable`] instances. + /// The given function will internally be stored as a [`DynamicCallable<'static>`] /// and mapped according to its [name]. /// /// Because the function must have a name, /// anonymous functions (e.g. `|a: i32, b: i32| { a + b }`) and closures must instead - /// be registered using [`overwrite_registration_with_name`] or converted to a [`DynamicClosure`] - /// and named using [`DynamicClosure::with_name`]. + /// be registered using [`overwrite_registration_with_name`] or converted to a [`DynamicCallable`] + /// and named using [`DynamicCallable::with_name`]. /// Failure to do so will result in an error being returned. /// /// To avoid overwriting existing registrations, @@ -223,17 +223,17 @@ impl FunctionRegistry { /// /// Returns the previous function with the same name, if any. /// - /// [name]: DynamicClosure::name + /// [name]: DynamicCallable::name /// [`overwrite_registration_with_name`]: Self::overwrite_registration_with_name /// [`register`]: Self::register pub fn overwrite_registration( &mut self, function: F, - ) -> Result>, FunctionRegistrationError> + ) -> Result>, FunctionRegistrationError> where - F: IntoClosure<'static, Marker> + 'static, + F: IntoCallable<'static, Marker> + 'static, { - let function = function.into_closure(); + let function = function.into_callable(); let name = function .name() .ok_or(FunctionRegistrationError::MissingName)? @@ -244,32 +244,32 @@ impl FunctionRegistry { /// Registers the given function, overwriting any existing registration. /// - /// This function accepts both functions/closures that satisfy [`IntoClosure`] - /// and direct [`DynamicClosure`] instances. - /// The given function will internally be stored as a [`DynamicClosure<'static>`] + /// This function accepts both functions/closures that satisfy [`IntoCallable`] + /// and direct [`DynamicCallable`] instances. + /// The given function will internally be stored as a [`DynamicCallable<'static>`] /// with its [name] set to the given name. /// /// Functions are mapped according to their name. /// To avoid overwriting existing registrations, /// it's recommended to use the [`register_with_name`] method instead. /// - /// This method is a convenience around calling [`IntoClosure::into_closure`] and [`DynamicClosure::with_name`] + /// This method is a convenience around calling [`IntoCallable::into_callable`] and [`DynamicCallable::with_name`] /// on the function and inserting it into the registry using the [`overwrite_registration`] method. /// /// Returns the previous function with the same name, if any. /// - /// [name]: DynamicClosure::name + /// [name]: DynamicCallable::name /// [`register_with_name`]: Self::register_with_name /// [`overwrite_registration`]: Self::overwrite_registration pub fn overwrite_registration_with_name( &mut self, name: impl Into>, function: F, - ) -> Option> + ) -> Option> where - F: IntoClosure<'static, Marker> + 'static, + F: IntoCallable<'static, Marker> + 'static, { - let function = function.into_closure().with_name(name); + let function = function.into_callable().with_name(name); match self.overwrite_registration(function) { Ok(existing) => existing, Err(FunctionRegistrationError::MissingName) => { @@ -283,20 +283,20 @@ impl FunctionRegistry { /// Get a reference to a registered function or closure by [name]. /// - /// [name]: DynamicClosure::name - pub fn get(&self, name: &str) -> Option<&DynamicClosure<'static>> { + /// [name]: DynamicCallable::name + pub fn get(&self, name: &str) -> Option<&DynamicCallable<'static>> { self.functions.get(name) } /// Returns `true` if a function or closure with the given [name] is registered. /// - /// [name]: DynamicClosure::name + /// [name]: DynamicCallable::name pub fn contains(&self, name: &str) -> bool { self.functions.contains_key(name) } /// Returns an iterator over all registered functions/closures. - pub fn iter(&self) -> impl ExactSizeIterator> { + pub fn iter(&self) -> impl ExactSizeIterator> { self.functions.values() } @@ -340,7 +340,7 @@ impl FunctionRegistryArc { #[cfg(test)] mod tests { use super::*; - use crate::func::{ArgList, IntoClosure}; + use crate::func::{ArgList, IntoCallable}; #[test] fn should_register_function() { @@ -385,7 +385,7 @@ mod tests { 123 } - let function = foo.into_closure().with_name("custom_name"); + let function = foo.into_callable().with_name("custom_name"); let mut registry = FunctionRegistry::default(); registry.register(function).unwrap(); @@ -400,7 +400,7 @@ mod tests { let value = 123; let foo = move || -> i32 { value }; - let function = foo.into_closure().with_name("custom_name"); + let function = foo.into_callable().with_name("custom_name"); let mut registry = FunctionRegistry::default(); registry.register(function).unwrap(); @@ -424,7 +424,7 @@ mod tests { let mut registry = FunctionRegistry::default(); registry.register(foo).unwrap(); - let result = registry.register(bar.into_closure().with_name(name)); + let result = registry.register(bar.into_callable().with_name(name)); assert!(matches!( result, @@ -452,7 +452,7 @@ mod tests { let mut registry = FunctionRegistry::default(); registry.register(foo).unwrap(); registry - .overwrite_registration(bar.into_closure().with_name(name)) + .overwrite_registration(bar.into_callable().with_name(name)) .unwrap(); assert_eq!(registry.len(), 1); @@ -466,7 +466,7 @@ mod tests { fn should_error_on_missing_name() { let foo = || -> i32 { 123 }; - let function = foo.into_closure(); + let function = foo.into_callable(); let mut registry = FunctionRegistry::default(); let result = registry.register(function); @@ -487,6 +487,6 @@ mod tests { registry.register_with_name("foo", foo).unwrap(); let debug = format!("{:?}", registry); - assert_eq!(debug, "{DynamicClosure(fn foo() -> i32)}"); + assert_eq!(debug, "{DynamicCallable(fn foo() -> i32)}"); } } diff --git a/crates/bevy_reflect/src/func/return_type.rs b/crates/bevy_reflect/src/func/return_type.rs index 7961d932b13b4..bedc295c63e4f 100644 --- a/crates/bevy_reflect/src/func/return_type.rs +++ b/crates/bevy_reflect/src/func/return_type.rs @@ -1,9 +1,9 @@ use crate::PartialReflect; -/// The return type of a [`DynamicClosure`] or [`DynamicClosureMut`]. +/// The return type of a [`DynamicCallable`] or [`DynamicCallableMut`]. /// -/// [`DynamicClosure`]: crate::func::DynamicClosure -/// [`DynamicClosureMut`]: crate::func::DynamicClosureMut +/// [`DynamicCallable`]: crate::func::DynamicCallable +/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut #[derive(Debug)] pub enum Return<'a> { /// The function returns nothing (i.e. it returns `()`). diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index ab6dd27a17bc5..9a17c9fd43aa0 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -574,7 +574,7 @@ pub mod prelude { }; #[cfg(feature = "functions")] - pub use crate::func::{IntoClosure, IntoClosureMut}; + pub use crate::func::{IntoCallable, IntoCallableMut}; } pub use array::*; diff --git a/examples/reflection/function_reflection.rs b/examples/reflection/function_reflection.rs index 11965048017a4..5827b5b2fb816 100644 --- a/examples/reflection/function_reflection.rs +++ b/examples/reflection/function_reflection.rs @@ -7,8 +7,8 @@ //! processing deserialized reflection data, or even just storing type-erased versions of your functions. use bevy::reflect::func::{ - ArgList, DynamicClosure, DynamicClosureMut, FunctionError, FunctionInfo, IntoClosure, - IntoClosureMut, Return, + ArgList, DynamicCallable, DynamicCallableMut, FunctionError, FunctionInfo, IntoCallable, + IntoCallableMut, Return, }; use bevy::reflect::{PartialReflect, Reflect}; @@ -35,12 +35,12 @@ fn main() { // However, you'll notice that we have to know the types of the arguments and return value at compile time. // This means there's not really a way to store or call these functions dynamically at runtime. // Luckily, Bevy's reflection crate comes with a set of tools for doing just that! - // We do this by first converting our function into the reflection-based `DynamicClosure` type - // using the `IntoClosure` trait. - let function: DynamicClosure<'static> = dbg!(add.into_closure()); + // We do this by first converting our function into the reflection-based `DynamicCallable` type + // using the `IntoCallable` trait. + let function: DynamicCallable<'static> = dbg!(add.into_callable()); - // This time, you'll notice that `DynamicClosure` doesn't take any information about the function's arguments or return value. - // This is because `DynamicClosure` checks the types of the arguments and return value at runtime. + // This time, you'll notice that `DynamicCallable` doesn't take any information about the function's arguments or return value. + // This is because `DynamicCallable` checks the types of the arguments and return value at runtime. // Now we can generate a list of arguments: let args: ArgList = dbg!(ArgList::new().push_owned(2_i32).push_owned(2_i32)); @@ -56,33 +56,33 @@ fn main() { assert_eq!(value.try_take::().unwrap(), 4); // The same can also be done for closures that capture references to their environment. - // Closures that capture their environment immutably can be converted into a `DynamicClosure` - // using the `IntoClosure` trait. + // Closures that capture their environment immutably can be converted into a `DynamicCallable` + // using the `IntoCallable` trait. let minimum = 5; let clamp = |value: i32| value.max(minimum); - let function: DynamicClosure = dbg!(clamp.into_closure()); + let function: DynamicCallable = dbg!(clamp.into_callable()); let args = dbg!(ArgList::new().push_owned(2_i32)); let return_value = dbg!(function.call(args).unwrap()); let value: Box = return_value.unwrap_owned(); assert_eq!(value.try_take::().unwrap(), 5); // We can also handle closures that capture their environment mutably - // using the `IntoClosureMut` trait. + // using the `IntoCallableMut` trait. let mut count = 0; let increment = |amount: i32| count += amount; - let closure: DynamicClosureMut = dbg!(increment.into_closure_mut()); + let closure: DynamicCallableMut = dbg!(increment.into_callable_mut()); let args = dbg!(ArgList::new().push_owned(5_i32)); - // Because `DynamicClosureMut` mutably borrows `total`, + // Because `DynamicCallableMut` mutably borrows `total`, // it will need to be dropped before `total` can be accessed again. - // This can be done manually with `drop(closure)` or by using the `DynamicClosureMut::call_once` method. + // This can be done manually with `drop(closure)` or by using the `DynamicCallableMut::call_once` method. dbg!(closure.call_once(args).unwrap()); assert_eq!(count, 5); // As stated before, this works for many kinds of simple functions. // Functions with non-reflectable arguments or return values may not be able to be converted. - // Generic functions are also not supported (unless manually monomorphized like `foo::.into_closure()`). + // Generic functions are also not supported (unless manually monomorphized like `foo::.into_callable()`). // Additionally, the lifetime of the return value is tied to the lifetime of the first argument. // However, this means that many methods (i.e. functions with a `self` parameter) are also supported: #[derive(Reflect, Default)] @@ -104,20 +104,20 @@ fn main() { let mut data = Data::default(); - let set_value = dbg!(Data::set_value.into_closure()); + let set_value = dbg!(Data::set_value.into_callable()); let args = dbg!(ArgList::new().push_mut(&mut data)).push_owned(String::from("Hello, world!")); dbg!(set_value.call(args).unwrap()); assert_eq!(data.value, "Hello, world!"); - let get_value = dbg!(Data::get_value.into_closure()); + let get_value = dbg!(Data::get_value.into_callable()); let args = dbg!(ArgList::new().push_ref(&data)); let return_value = dbg!(get_value.call(args).unwrap()); let value: &dyn PartialReflect = return_value.unwrap_ref(); assert_eq!(value.try_downcast_ref::().unwrap(), "Hello, world!"); - // Lastly, for more complex use cases, you can always create a custom `DynamicClosure` manually. - // This is useful for functions that can't be converted via the `IntoClosure` trait. - // For example, this function doesn't implement `IntoClosure` due to the fact that + // Lastly, for more complex use cases, you can always create a custom `DynamicCallable` manually. + // This is useful for functions that can't be converted via the `IntoCallable` trait. + // For example, this function doesn't implement `IntoCallable` due to the fact that // the lifetime of the return value is not tied to the lifetime of the first argument. fn get_or_insert(value: i32, container: &mut Option) -> &i32 { if container.is_none() { @@ -127,7 +127,7 @@ fn main() { container.as_ref().unwrap() } - let get_or_insert_function = dbg!(DynamicClosure::new( + let get_or_insert_function = dbg!(DynamicCallable::new( |mut args| { // We can optionally add a check to ensure we were given the correct number of arguments. if args.len() != 2 { From 47913e89e9ed6623a5c51f10d1285ba4f5182b71 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 18 Aug 2024 00:17:15 -0700 Subject: [PATCH 4/8] Update documentation to use "callable" terminology --- crates/bevy_reflect/src/func/args/info.rs | 11 +- .../bevy_reflect/src/func/dynamic_closure.rs | 88 +++++++------ .../src/func/dynamic_closure_mut.rs | 89 +++++++------ crates/bevy_reflect/src/func/error.rs | 14 +-- crates/bevy_reflect/src/func/info.rs | 46 +++---- crates/bevy_reflect/src/func/into_closure.rs | 15 ++- .../bevy_reflect/src/func/into_closure_mut.rs | 20 ++- crates/bevy_reflect/src/func/mod.rs | 23 ++-- crates/bevy_reflect/src/func/reflect_fn.rs | 13 +- .../bevy_reflect/src/func/reflect_fn_mut.rs | 11 +- crates/bevy_reflect/src/func/registry.rs | 119 +++++++++--------- crates/bevy_reflect/src/func/return_type.rs | 8 +- 12 files changed, 253 insertions(+), 204 deletions(-) diff --git a/crates/bevy_reflect/src/func/args/info.rs b/crates/bevy_reflect/src/func/args/info.rs index e6ac3bdeede9a..734c12f5d8ae7 100644 --- a/crates/bevy_reflect/src/func/args/info.rs +++ b/crates/bevy_reflect/src/func/args/info.rs @@ -10,7 +10,7 @@ use crate::TypePath; /// [`DynamicCallableMut`]: crate::func::DynamicCallableMut #[derive(Debug, Clone)] pub struct ArgInfo { - /// The index of the argument within its function. + /// The index of the argument within its callable. index: usize, /// The name of the argument (if provided). name: Option>, @@ -44,7 +44,7 @@ impl ArgInfo { self } - /// The index of the argument within its function. + /// The index of the argument within its callable. pub fn index(&self) -> usize { self.index } @@ -53,7 +53,7 @@ impl ArgInfo { /// /// Note that this may return `None` even if the argument has a name. /// This is because the name needs to be manually set using [`Self::with_name`] - /// since the name can't be inferred from the function type alone. + /// since the name can't be inferred from the callable type alone. /// /// For [`DynamicCallables`] created using [`IntoCallable`] /// and [`DynamicCallableMuts`] created using [`IntoCallableMut`], @@ -72,6 +72,9 @@ impl ArgInfo { self.ownership } + /// The [type path] of the argument. + /// + /// [type path]: TypePath::type_path pub fn type_path(&self) -> &'static str { self.type_path } @@ -93,7 +96,7 @@ impl ArgInfo { /// This is primarily used for error reporting and debugging. #[derive(Debug, Clone, PartialEq, Eq)] pub enum ArgId { - /// The index of the argument within its function. + /// The index of the argument within its callable. Index(usize), /// The name of the argument. Name(Cow<'static, str>), diff --git a/crates/bevy_reflect/src/func/dynamic_closure.rs b/crates/bevy_reflect/src/func/dynamic_closure.rs index 6302cee875cf1..d307164d2e1e7 100644 --- a/crates/bevy_reflect/src/func/dynamic_closure.rs +++ b/crates/bevy_reflect/src/func/dynamic_closure.rs @@ -5,10 +5,13 @@ use alloc::borrow::Cow; use core::fmt::{Debug, Formatter}; use std::sync::Arc; -/// A dynamic representation of a Rust closure. +/// A dynamic representation of a callable. /// -/// This type can be used to represent any Rust closure that captures its environment immutably. -/// For closures that need to capture their environment mutably, +/// This type can be used to represent any callable that satisfies [`Fn`] +/// (or the reflection-based equivalent, [`ReflectFn`]). +/// That is, any function or closure that does not mutably borrow data from its environment. +/// +/// For callables that do need to capture their environment mutably, /// see [`DynamicCallableMut`]. /// /// See the [module-level documentation] for more information. @@ -23,23 +26,23 @@ use std::sync::Arc; /// ``` /// # use bevy_reflect::func::{ArgList, DynamicCallable, FunctionInfo, IntoCallable}; /// # -/// let punct = String::from("!!!"); -/// -/// let punctuate = |text: &String| -> String { -/// format!("{}{}", text, punct) -/// }; +/// fn add(a: i32, b: i32) -> i32 { +/// a + b +/// } /// -/// // Convert the closure into a dynamic closure using `IntoCallable::into_callable` -/// let mut func: DynamicCallable = punctuate.into_callable(); +/// // Convert the function into a dynamic callable using `IntoCallable::into_callable`: +/// let mut func: DynamicCallable = add.into_callable(); /// -/// // Dynamically call the closure: -/// let text = String::from("Hello, world"); -/// let args = ArgList::default().push_ref(&text); +/// // Dynamically call it: +/// let args = ArgList::default().push_owned(25_i32).push_owned(75_i32); /// let value = func.call(args).unwrap().unwrap_owned(); /// /// // Check the result: -/// assert_eq!(value.try_take::().unwrap(), "Hello, world!!!"); +/// assert_eq!(value.try_downcast_ref::(), Some(&100)); /// ``` +/// +/// [`ReflectFn`]: crate::func::ReflectFn +/// [module-level documentation]: crate::func pub struct DynamicCallable<'env> { pub(super) info: FunctionInfo, pub(super) func: Arc Fn(ArgList<'a>) -> FunctionResult<'a> + Send + Sync + 'env>, @@ -48,10 +51,11 @@ pub struct DynamicCallable<'env> { impl<'env> DynamicCallable<'env> { /// Create a new [`DynamicCallable`]. /// - /// The given function can be used to call out to a regular function, closure, or method. + /// The given function can be used to call out to any other callable, + /// including functions, closures, or methods. /// - /// It's important that the closure signature matches the provided [`FunctionInfo`]. - /// This info may be used by consumers of the function for validation and debugging. + /// It's important that the callable signature matches the provided [`FunctionInfo`]. + /// This info may be used by consumers of this callable for validation and debugging. pub fn new Fn(ArgList<'a>) -> FunctionResult<'a> + Send + Sync + 'env>( func: F, info: FunctionInfo, @@ -62,36 +66,35 @@ impl<'env> DynamicCallable<'env> { } } - /// Set the name of the closure. - /// - /// For [`DynamicCallable`] created using [`IntoCallable`], - /// the default name will always be the full path to the closure as returned by [`std::any::type_name`]. + /// Set the name of the callable. /// - /// This default name generally does not contain the actual name of the closure, only its module path. - /// It is therefore recommended to set the name manually using this method. + /// For [`DynamicCallables`] created using [`IntoCallable`], + /// the default name will always be the full path to the callable as returned by [`std::any::type_name`], + /// unless the callable is a closure, anonymous function, or function pointer, + /// in which case the name will be `None`. /// - /// [`DynamicCallable`]: DynamicCallable + /// [`DynamicCallables`]: DynamicCallable pub fn with_name(mut self, name: impl Into>) -> Self { self.info = self.info.with_name(name); self } - /// Set the arguments of the closure. + /// Set the argument information of the callable. /// - /// It's important that the arguments match the intended closure signature, - /// as this can be used by consumers of the function for validation and debugging. + /// It's important that the arguments match the intended callable signature, + /// as this can be used by consumers of this callable for validation and debugging. pub fn with_args(mut self, args: Vec) -> Self { self.info = self.info.with_args(args); self } - /// Set the return information of the closure. + /// Set the return information of the callable. pub fn with_return_info(mut self, return_info: ReturnInfo) -> Self { self.info = self.info.with_return_info(return_info); self } - /// Call the closure with the given arguments. + /// Invoke the callable with the given arguments. /// /// # Example /// @@ -111,19 +114,22 @@ impl<'env> DynamicCallable<'env> { (self.func)(args) } - /// Returns the closure info. + /// Returns the callable info. pub fn info(&self) -> &FunctionInfo { &self.info } - /// The [name] of the closure. + /// The [name] of the callable. /// - /// If this [`DynamicCallable`] was created using [`IntoCallable`], - /// then the default name will always be `None`. + /// For [`DynamicCallables`] created using [`IntoCallable`], + /// the default name will always be the full path to the callable as returned by [`std::any::type_name`], + /// unless the callable is a closure, anonymous function, or function pointer, + /// in which case the name will be `None`. /// /// This can be overridden using [`with_name`]. /// /// [name]: FunctionInfo::name + /// [`DynamicCallables`]: DynamicCallable /// [`with_name`]: Self::with_name pub fn name(&self) -> Option<&Cow<'static, str>> { self.info.name() @@ -134,7 +140,7 @@ impl<'env> DynamicCallable<'env> { /// /// This takes the format: `DynamicCallable(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type})`. /// -/// Names for arguments and the closure itself are optional and will default to `_` if not provided. +/// Names for arguments and the callable itself are optional and will default to `_` if not provided. impl<'env> Debug for DynamicCallable<'env> { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { let name = self.info.name().unwrap_or(&Cow::Borrowed("_")); @@ -183,27 +189,27 @@ mod tests { use super::*; #[test] - fn should_overwrite_closure_name() { + fn should_overwrite_callable_name() { let c = 23; let func = (|a: i32, b: i32| a + b + c) .into_callable() - .with_name("my_closure"); - assert_eq!(func.info().name().unwrap(), "my_closure"); + .with_name("my_callable"); + assert_eq!(func.info().name().unwrap(), "my_callable"); } #[test] - fn should_convert_dynamic_closure_with_into_callable() { + fn should_convert_dynamic_callable_with_into_callable() { fn make_closure<'env, F: IntoCallable<'env, M>, M>(f: F) -> DynamicCallable<'env> { f.into_callable() } let c = 23; - let closure: DynamicCallable = make_closure(|a: i32, b: i32| a + b + c); - let _: DynamicCallable = make_closure(closure); + let callable: DynamicCallable = make_closure(|a: i32, b: i32| a + b + c); + let _: DynamicCallable = make_closure(callable); } #[test] - fn should_clone_dynamic_closure() { + fn should_clone_dynamic_callable() { let hello = String::from("Hello"); let greet = |name: &String| -> String { format!("{}, {}!", hello, name) }; diff --git a/crates/bevy_reflect/src/func/dynamic_closure_mut.rs b/crates/bevy_reflect/src/func/dynamic_closure_mut.rs index 99823e190b7ea..d46ab3ff60ec6 100644 --- a/crates/bevy_reflect/src/func/dynamic_closure_mut.rs +++ b/crates/bevy_reflect/src/func/dynamic_closure_mut.rs @@ -3,13 +3,16 @@ use core::fmt::{Debug, Formatter}; use crate::func::args::{ArgInfo, ArgList}; use crate::func::info::FunctionInfo; -use crate::func::{DynamicCallable, FunctionResult, IntoCallableMut, ReturnInfo}; +use crate::func::{DynamicCallable, FunctionResult, IntoCallable, IntoCallableMut, ReturnInfo}; -/// A dynamic representation of a Rust closure. +/// A dynamic representation of a callable. /// -/// This type can be used to represent any Rust closure that captures its environment mutably. -/// For closures that only need to capture their environment immutably, -/// consider using [`DynamicCallable`]. +/// This type can be used to represent any callable that satisfies [`FnMut`] +/// (or the reflection-based equivalent, [`ReflectFnMut`]). +/// That is, any function or closure. +/// +/// For callables that do not need to capture their environment mutably, +/// it's recommended to use [`DynamicCallable`] instead. /// /// This type can be seen as a superset of [`DynamicCallable`]. /// @@ -34,10 +37,14 @@ use crate::func::{DynamicCallable, FunctionResult, IntoCallableMut, ReturnInfo}; /// old_value /// }; /// -/// // Convert the closure into a dynamic closure using `IntoCallableMut::into_callable_mut` +/// // Since this closure mutably borrows data, we can't convert it into a regular `DynamicCallable`, +/// // as doing so would result in a compile-time error: +/// // let mut func: DynamicCallable = replace.into_callable(); +/// +/// // Instead, we convert it into a dynamic callable using `IntoCallableMut::into_callable_mut`: /// let mut func: DynamicCallableMut = replace.into_callable_mut(); /// -/// // Dynamically call the closure: +/// // Dynamically call it: /// let args = ArgList::default().push_owned(1_usize).push_owned(-2_i32); /// let value = func.call(args).unwrap().unwrap_owned(); /// @@ -46,11 +53,14 @@ use crate::func::{DynamicCallable, FunctionResult, IntoCallableMut, ReturnInfo}; /// /// // Note that `func` still has a reference to `list`, /// // so we need to drop it before we can access `list` again. -/// // Alternatively, we could have called the `func` using -/// // `DynamicCallableMut::call_once` to immediately consume the closure. +/// // Alternatively, we could have invoked `func` with +/// // `DynamicCallableMut::call_once` to immediately consume it. /// drop(func); /// assert_eq!(list, vec![1, -2, 3]); /// ``` +/// +/// [`ReflectFnMut`]: crate::func::ReflectFnMut +/// [module-level documentation]: crate::func pub struct DynamicCallableMut<'env> { info: FunctionInfo, func: Box FnMut(ArgList<'a>) -> FunctionResult<'a> + 'env>, @@ -59,10 +69,11 @@ pub struct DynamicCallableMut<'env> { impl<'env> DynamicCallableMut<'env> { /// Create a new [`DynamicCallableMut`]. /// - /// The given function can be used to call out to a regular function, closure, or method. + /// The given function can be used to call out to any other callable, + /// including functions, closures, or methods. /// - /// It's important that the closure signature matches the provided [`FunctionInfo`]. - /// This info may be used by consumers of the function for validation and debugging. + /// It's important that the callable signature matches the provided [`FunctionInfo`]. + /// This info may be used by consumers of this callable for validation and debugging. pub fn new FnMut(ArgList<'a>) -> FunctionResult<'a> + 'env>( func: F, info: FunctionInfo, @@ -73,13 +84,12 @@ impl<'env> DynamicCallableMut<'env> { } } - /// Set the name of the closure. + /// Set the name of the callable. /// /// For [`DynamicCallableMuts`] created using [`IntoCallableMut`], - /// the default name will always be the full path to the closure as returned by [`std::any::type_name`]. - /// - /// This default name generally does not contain the actual name of the closure, only its module path. - /// It is therefore recommended to set the name manually using this method. + /// the default name will always be the full path to the callable as returned by [`std::any::type_name`], + /// unless the callable is a closure, anonymous function, or function pointer, + /// in which case the name will be `None`. /// /// [`DynamicCallableMuts`]: DynamicCallableMut pub fn with_name(mut self, name: impl Into>) -> Self { @@ -87,26 +97,26 @@ impl<'env> DynamicCallableMut<'env> { self } - /// Set the arguments of the closure. + /// Set the argument information of the callable. /// - /// It's important that the arguments match the intended closure signature, - /// as this can be used by consumers of the function for validation and debugging. + /// It's important that the arguments match the intended callable signature, + /// as this can be used by consumers of this callable for validation and debugging. pub fn with_args(mut self, args: Vec) -> Self { self.info = self.info.with_args(args); self } - /// Set the return information of the closure. + /// Set the return information of the callable. pub fn with_return_info(mut self, return_info: ReturnInfo) -> Self { self.info = self.info.with_return_info(return_info); self } - /// Call the closure with the given arguments. + /// Invoke the callable with the given arguments. /// - /// Variables that are captured mutably by this closure - /// won't be usable until this closure is dropped. - /// Consider using [`call_once`] if you want to consume the closure + /// Variables that are captured mutably by this callable + /// won't be usable until this callable is dropped. + /// Consider using [`call_once`] if you want to consume the callable /// immediately after calling it. /// /// # Example @@ -130,10 +140,10 @@ impl<'env> DynamicCallableMut<'env> { (self.func)(args) } - /// Call the closure with the given arguments and consume the closure. + /// Invoke the callable with the given arguments and consume it. /// - /// This is useful for closures that capture their environment mutably - /// because otherwise any captured variables would still be borrowed by this closure. + /// This is useful for callables that capture their environment mutably + /// because otherwise any captured variables would still be borrowed by it. /// /// # Example /// @@ -155,30 +165,33 @@ impl<'env> DynamicCallableMut<'env> { (self.func)(args) } - /// Returns the closure info. + /// Returns the callable info. pub fn info(&self) -> &FunctionInfo { &self.info } - /// The [name] of the closure. + /// The [name] of the callable. /// - /// If this [`DynamicCallableMut`] was created using [`IntoCallableMut`], - /// then the default name will always be `None`. + /// For [`DynamicCallableMuts`] created using [`IntoCallableMut`], + /// the default name will always be the full path to the callable as returned by [`std::any::type_name`], + /// unless the callable is a closure, anonymous function, or function pointer, + /// in which case the name will be `None`. /// /// This can be overridden using [`with_name`]. /// /// [name]: FunctionInfo::name + /// [`DynamicCallableMuts`]: DynamicCallableMut /// [`with_name`]: Self::with_name pub fn name(&self) -> Option<&Cow<'static, str>> { self.info.name() } } -/// Outputs the closure's signature. +/// Outputs the callable's signature. /// /// This takes the format: `DynamicCallableMut(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type})`. /// -/// Names for arguments and the closure itself are optional and will default to `_` if not provided. +/// Names for arguments and the callable itself are optional and will default to `_` if not provided. impl<'env> Debug for DynamicCallableMut<'env> { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { let name = self.info.name().unwrap_or(&Cow::Borrowed("_")); @@ -221,16 +234,16 @@ mod tests { use super::*; #[test] - fn should_overwrite_closure_name() { + fn should_overwrite_callable_name() { let mut total = 0; let func = (|a: i32, b: i32| total = a + b) .into_callable_mut() - .with_name("my_closure"); - assert_eq!(func.info().name().unwrap(), "my_closure"); + .with_name("my_callable"); + assert_eq!(func.info().name().unwrap(), "my_callable"); } #[test] - fn should_convert_dynamic_closure_mut_with_into_callable() { + fn should_convert_dynamic_callable_mut_with_into_callable() { fn make_closure<'env, F: IntoCallableMut<'env, M>, M>(f: F) -> DynamicCallableMut<'env> { f.into_callable_mut() } diff --git a/crates/bevy_reflect/src/func/error.rs b/crates/bevy_reflect/src/func/error.rs index c6bb850627322..90bab4ef98483 100644 --- a/crates/bevy_reflect/src/func/error.rs +++ b/crates/bevy_reflect/src/func/error.rs @@ -19,24 +19,24 @@ pub enum FunctionError { /// The result of calling a dynamic [`DynamicCallable`] or [`DynamicCallableMut`]. /// -/// Returns `Ok(value)` if the function was called successfully, +/// Returns `Ok(value)` if the callable was called successfully, /// where `value` is the [`Return`] value of the function. /// /// [`DynamicCallable`]: crate::func::DynamicCallable /// [`DynamicCallableMut`]: crate::func::DynamicCallableMut pub type FunctionResult<'a> = Result, FunctionError>; -/// An error that occurs when registering a function into a [`FunctionRegistry`]. +/// An error that occurs when registering a callable into a [`FunctionRegistry`]. /// /// [`FunctionRegistry`]: crate::func::FunctionRegistry #[derive(Debug, Error, PartialEq)] pub enum FunctionRegistrationError { - /// A function with the given name has already been registered. + /// A callable with the given name has already been registered. /// - /// Contains the duplicate function name. - #[error("a function has already been registered with name {0:?}")] + /// Contains the duplicate callable name. + #[error("a callable has already been registered with name {0:?}")] DuplicateName(Cow<'static, str>), - /// The function is missing a name by which it can be registered. - #[error("function name is missing")] + /// The callable is missing a name by which it can be registered. + #[error("callable name is missing")] MissingName, } diff --git a/crates/bevy_reflect/src/func/info.rs b/crates/bevy_reflect/src/func/info.rs index f47a306396f4b..bfc7c6e18387e 100644 --- a/crates/bevy_reflect/src/func/info.rs +++ b/crates/bevy_reflect/src/func/info.rs @@ -7,8 +7,8 @@ use crate::TypePath; /// Type information for a [`DynamicCallable`] or [`DynamicCallableMut`]. /// -/// This information can be retrieved from certain functions and closures -/// using the [`TypedFunction`] trait. +/// This information can be retrieved directly from certain functions and closures +/// using the [`TypedFunction`] trait, and manually constructed otherwise. /// /// [`DynamicCallable`]: crate::func::DynamicCallable /// [`DynamicCallableMut`]: crate::func::DynamicCallableMut @@ -20,7 +20,7 @@ pub struct FunctionInfo { } impl FunctionInfo { - /// Create a new [`FunctionInfo`] for a function with the given name. + /// Create a new [`FunctionInfo`] for a callable with the given name. pub fn named(name: impl Into>) -> Self { Self { name: Some(name.into()), @@ -43,7 +43,7 @@ impl FunctionInfo { } } - /// Create a new [`FunctionInfo`] from the given function or closure. + /// Create a new [`FunctionInfo`] from the given callable. pub fn from(function: &F) -> Self where F: TypedFunction, @@ -51,13 +51,13 @@ impl FunctionInfo { function.get_function_info() } - /// Set the name of the function. + /// Set the name of the callable. pub fn with_name(mut self, name: impl Into>) -> Self { self.name = Some(name.into()); self } - /// Push an argument onto the function's argument list. + /// Push an argument onto the callable's argument list. /// /// The order in which this method is called matters as it will determine the index of the argument /// based on the current number of arguments. @@ -70,20 +70,20 @@ impl FunctionInfo { self } - /// Set the arguments of the function. + /// Set the arguments of the callable. /// /// This will completely replace any existing arguments. /// - /// It's preferable to use [`Self::with_arg`] to add arguments to the function + /// It's preferable to use [`Self::with_arg`] to add arguments to the callable /// as it will automatically set the index of the argument. pub fn with_args(mut self, args: Vec) -> Self { self.args = args; self } - /// Set the [return information] of the function. + /// Set the [return information] of the callable. /// - /// To manually set the [`ReturnInfo`] of the function, see [`Self::with_return_info`]. + /// To manually set the [`ReturnInfo`] of the callable, see [`Self::with_return_info`]. /// /// [return information]: ReturnInfo pub fn with_return(mut self) -> Self { @@ -91,7 +91,7 @@ impl FunctionInfo { self } - /// Set the [return information] of the function. + /// Set the [return information] of the callable. /// /// This will completely replace any existing return information. /// @@ -103,10 +103,12 @@ impl FunctionInfo { self } - /// The name of the function. + /// The name of the callable. /// /// For [`DynamicCallables`] created using [`IntoCallable`] or [`DynamicCallableMuts`] created using [`IntoCallableMut`], - /// the name will always be the full path to the function as returned by [`std::any::type_name`]. + /// the default name will always be the full path to the callable as returned by [`std::any::type_name`], + /// unless the callable is a closure, anonymous function, or function pointer, + /// in which case the name will be `None`. /// /// [`DynamicCallables`]: crate::func::DynamicCallable /// [`IntoCallable`]: crate::func::IntoCallable @@ -116,17 +118,17 @@ impl FunctionInfo { self.name.as_ref() } - /// The arguments of the function. + /// The arguments of the callable. pub fn args(&self) -> &[ArgInfo] { &self.args } - /// The number of arguments the function takes. + /// The number of arguments the callable takes. pub fn arg_count(&self) -> usize { self.args.len() } - /// The return information of the function. + /// The return information of the callable. pub fn return_info(&self) -> &ReturnInfo { &self.return_info } @@ -162,20 +164,21 @@ impl ReturnInfo { } } -/// A static accessor to compile-time type information for functions. +/// A static accessor to compile-time type information for callables. /// -/// This is the equivalent of [`Typed`] for functions. +/// This is the equivalent of [`Typed`], but for callables. /// /// # Blanket Implementation /// /// This trait has a blanket implementation that covers: /// - Functions and methods defined with the `fn` keyword -/// - Closures that do not capture their environment +/// - Anonymous functions +/// - Function pointers /// - Closures that capture immutable references to their environment /// - Closures that capture mutable references to their environment /// - Closures that take ownership of captured variables /// -/// For each of the above cases, the function signature may only have up to 15 arguments, +/// For each of the above cases, the callable signature may only have up to 15 arguments, /// not including an optional receiver argument (often `&self` or `&mut self`). /// This optional receiver argument may be either a mutable or immutable reference to a type. /// If the return type is also a reference, its lifetime will be bound to the lifetime of this receiver. @@ -209,6 +212,7 @@ impl ReturnInfo { /// /// [module-level documentation]: crate::func /// [`Typed`]: crate::Typed +/// [unconstrained type parameters]: https://doc.rust-lang.org/error_codes/E0207.html pub trait TypedFunction { /// Get the [`FunctionInfo`] for this type. fn function_info() -> FunctionInfo; @@ -219,7 +223,7 @@ pub trait TypedFunction { } } -/// Helper macro for implementing [`TypedFunction`] on Rust closures. +/// Helper macro for implementing [`TypedFunction`] on Rust callables. /// /// This currently implements it for the following signatures (where `argX` may be any of `T`, `&T`, or `&mut T`): /// - `FnMut(arg0, arg1, ..., argN) -> R` diff --git a/crates/bevy_reflect/src/func/into_closure.rs b/crates/bevy_reflect/src/func/into_closure.rs index bf1bffadc3ec1..ab7ae6755d547 100644 --- a/crates/bevy_reflect/src/func/into_closure.rs +++ b/crates/bevy_reflect/src/func/into_closure.rs @@ -7,7 +7,18 @@ use crate::func::{DynamicCallable, ReflectFn, TypedFunction}; /// /// See the [module-level documentation] for more information. /// +/// # Trait Parameters +/// +/// This trait has a `Marker` type parameter that is used to get around issues with +/// [unconstrained type parameters] when defining impls with generic arguments or return types. +/// This `Marker` can be any type, provided it doesn't conflict with other implementations. +/// +/// Additionally, it has a lifetime parameter, `'env`, that is used to bound the lifetime of the callable. +/// For functions and some closures, this will end up just being `'static`, +/// however, closures that borrow from their environment will have a lifetime bound to that environment. +/// /// [module-level documentation]: crate::func +/// [unconstrained type parameters]: https://doc.rust-lang.org/error_codes/E0207.html pub trait IntoCallable<'env, Marker> { /// Converts [`Self`] into a [`DynamicCallable`]. fn into_callable(self) -> DynamicCallable<'env>; @@ -28,7 +39,7 @@ mod tests { use crate::func::ArgList; #[test] - fn should_create_dynamic_closure_from_closure() { + fn should_create_dynamic_callable_from_closure() { let c = 23; let func = (|a: i32, b: i32| a + b + c).into_callable(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); @@ -37,7 +48,7 @@ mod tests { } #[test] - fn should_create_dynamic_closure_from_function() { + fn should_create_dynamic_callable_from_function() { fn add(a: i32, b: i32) -> i32 { a + b } diff --git a/crates/bevy_reflect/src/func/into_closure_mut.rs b/crates/bevy_reflect/src/func/into_closure_mut.rs index 8e210d38446ff..8326a6c3e4129 100644 --- a/crates/bevy_reflect/src/func/into_closure_mut.rs +++ b/crates/bevy_reflect/src/func/into_closure_mut.rs @@ -5,13 +5,23 @@ use crate::func::{DynamicCallableMut, ReflectFnMut, TypedFunction}; /// This trait is automatically implemented for any type that implements /// [`ReflectFnMut`] and [`TypedFunction`]. /// -/// This trait can be seen as a supertrait of [`IntoCallable`]. +/// This trait can be seen as a superset of [`IntoCallable`]. /// /// See the [module-level documentation] for more information. /// -/// [`ReflectFn`]: crate::func::ReflectFn +/// # Trait Parameters +/// +/// This trait has a `Marker` type parameter that is used to get around issues with +/// [unconstrained type parameters] when defining impls with generic arguments or return types. +/// This `Marker` can be any type, provided it doesn't conflict with other implementations. +/// +/// Additionally, it has a lifetime parameter, `'env`, that is used to bound the lifetime of the callable. +/// For functions and some closures, this will end up just being `'static`, +/// however, closures that borrow from their environment will have a lifetime bound to that environment. +/// /// [`IntoCallable`]: crate::func::IntoCallable /// [module-level documentation]: crate::func +/// [unconstrained type parameters]: https://doc.rust-lang.org/error_codes/E0207.html pub trait IntoCallableMut<'env, Marker> { /// Converts [`Self`] into a [`DynamicCallableMut`]. fn into_callable_mut(self) -> DynamicCallableMut<'env>; @@ -35,7 +45,7 @@ mod tests { use crate::func::{ArgList, IntoCallable}; #[test] - fn should_create_dynamic_closure_mut_from_closure() { + fn should_create_dynamic_callable_mut_from_closure() { let c = 23; let func = (|a: i32, b: i32| a + b + c).into_callable(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); @@ -44,7 +54,7 @@ mod tests { } #[test] - fn should_create_dynamic_closure_mut_from_closure_with_mutable_capture() { + fn should_create_dynamic_callable_mut_from_closure_with_mutable_capture() { let mut total = 0; let func = (|a: i32, b: i32| total = a + b).into_callable_mut(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); @@ -53,7 +63,7 @@ mod tests { } #[test] - fn should_create_dynamic_closure_mut_from_function() { + fn should_create_dynamic_callable_mut_from_function() { fn add(a: i32, b: i32) -> i32 { a + b } diff --git a/crates/bevy_reflect/src/func/mod.rs b/crates/bevy_reflect/src/func/mod.rs index 3c9ca80ec38cd..7228c2fa89937 100644 --- a/crates/bevy_reflect/src/func/mod.rs +++ b/crates/bevy_reflect/src/func/mod.rs @@ -1,6 +1,6 @@ -//! Reflection-based dynamic functions. +//! Reflection-based dynamic callables. //! -//! This module provides a way to pass around and call functions dynamically +//! This module provides a way to pass around and invoke callables dynamically //! using the [`DynamicCallable`] and [`DynamicCallableMut`] types. //! //! Many simple functions and closures can be automatically converted to these types @@ -33,9 +33,14 @@ //! assert_eq!(value.unwrap_owned().try_downcast_ref::(), Some(&100)); //! ``` //! -//! # Functions vs Closures +//! # Types of Callables //! -//! In Rust, a "function" is any callable that does not capture its environment. +//! A "callable", put simply, is code that can be invoked with a set of arguments +//! to perform some action. +//! +//! In Rust, there are two main categories of callables: functions and closures. +//! +//! A "function" is a callable that does not capture its environment. //! These are typically defined with the `fn` keyword, but may also use anonymous function syntax. //! //! ```rust @@ -48,7 +53,7 @@ //! let add = |a: i32, b: i32| a + b; //! ``` //! -//! Rust also has the concept of "closures", which are special functions that capture their environment. +//! Closures, on the other hand, are special functions that do capture their environment. //! These are always defined with anonymous function syntax. //! //! ```rust @@ -65,15 +70,9 @@ //! let add = move |a: i32, b: i32| a + b + c; //! ``` //! -//! Each callable may be considered a subset of the other: -//! functions are a subset of immutable closures which are a subset of mutable closures. -//! -//! This means that, in terms of traits, you could imagine that any type that implements -//! [`IntoCallable`] also implements [`IntoCallableMut`]. -//! //! # Valid Signatures //! -//! Many of the traits in this module have default blanket implementations over a specific set of function signatures. +//! Many of the traits in this module have default blanket implementations over a specific set of callable signatures. //! //! These signatures are: //! - `(...) -> R` diff --git a/crates/bevy_reflect/src/func/reflect_fn.rs b/crates/bevy_reflect/src/func/reflect_fn.rs index 51a028941cd8b..972eb6aad4f05 100644 --- a/crates/bevy_reflect/src/func/reflect_fn.rs +++ b/crates/bevy_reflect/src/func/reflect_fn.rs @@ -7,24 +7,25 @@ use crate::{Reflect, TypePath}; /// A reflection-based version of the [`Fn`] trait. /// -/// This allows functions to be called dynamically through [reflection]. +/// This allows callables to be called dynamically through [reflection]. /// /// # Blanket Implementation /// /// This trait has a blanket implementation that covers: /// - Functions and methods defined with the `fn` keyword -/// - Closures that do not capture their environment +/// - Anonymous functions +/// - Function pointers /// - Closures that capture immutable references to their environment /// - Closures that take ownership of captured variables /// -/// For each of the above cases, the function signature may only have up to 15 arguments, +/// For each of the above cases, the callable signature may only have up to 15 arguments, /// not including an optional receiver argument (often `&self` or `&mut self`). /// This optional receiver argument may be either a mutable or immutable reference to a type. /// If the return type is also a reference, its lifetime will be bound to the lifetime of this receiver. /// /// See the [module-level documentation] for more information on valid signatures. /// -/// To handle closures that capture mutable references to their environment, +/// To handle callable that capture mutable references to their environment, /// see the [`ReflectFnMut`] trait instead. /// /// Arguments are expected to implement [`FromArg`], and the return type is expected to implement [`IntoReturn`]. @@ -60,11 +61,11 @@ use crate::{Reflect, TypePath}; /// [derive macro]: derive@crate::Reflect /// [unconstrained type parameters]: https://doc.rust-lang.org/error_codes/E0207.html pub trait ReflectFn<'env, Marker>: ReflectFnMut<'env, Marker> { - /// Call the function with the given arguments and return the result. + /// Invoke the callable with the given arguments and return the result. fn reflect_call<'a>(&self, args: ArgList<'a>) -> FunctionResult<'a>; } -/// Helper macro for implementing [`ReflectFn`] on Rust closures. +/// Helper macro for implementing [`ReflectFn`] on Rust callables. /// /// This currently implements it for the following signatures (where `argX` may be any of `T`, `&T`, or `&mut T`): /// - `Fn(arg0, arg1, ..., argN) -> R` diff --git a/crates/bevy_reflect/src/func/reflect_fn_mut.rs b/crates/bevy_reflect/src/func/reflect_fn_mut.rs index ae109832e47f6..cdfdc86a8be2e 100644 --- a/crates/bevy_reflect/src/func/reflect_fn_mut.rs +++ b/crates/bevy_reflect/src/func/reflect_fn_mut.rs @@ -7,22 +7,23 @@ use crate::{Reflect, TypePath}; /// A reflection-based version of the [`FnMut`] trait. /// -/// This allows functions to be called dynamically through [reflection]. +/// This allows callables to be called dynamically through [reflection]. /// -/// This is a supertrait of [`ReflectFn`], and is used for closures that may mutate their environment. +/// This is a supertrait of [`ReflectFn`], and is used for callables that may mutate their environment. /// /// # Blanket Implementation /// /// This trait has a blanket implementation that covers everything that [`ReflectFn`] does: /// - Functions and methods defined with the `fn` keyword -/// - Closures that do not capture their environment +/// - Anonymous functions +/// - Function pointers /// - Closures that capture immutable references to their environment /// - Closures that take ownership of captured variables /// /// But also allows for: /// - Closures that capture mutable references to their environment /// -/// For each of the above cases, the function signature may only have up to 15 arguments, +/// For each of the above cases, the callable signature may only have up to 15 arguments, /// not including an optional receiver argument (often `&self` or `&mut self`). /// This optional receiver argument may be either a mutable or immutable reference to a type. /// If the return type is also a reference, its lifetime will be bound to the lifetime of this receiver. @@ -66,7 +67,7 @@ use crate::{Reflect, TypePath}; /// [derive macro]: derive@crate::Reflect /// [unconstrained type parameters]: https://doc.rust-lang.org/error_codes/E0207.html pub trait ReflectFnMut<'env, Marker> { - /// Call the function with the given arguments and return the result. + /// Invoke the callable with the given arguments and return the result. fn reflect_call_mut<'a>(&mut self, args: ArgList<'a>) -> FunctionResult<'a>; } diff --git a/crates/bevy_reflect/src/func/registry.rs b/crates/bevy_reflect/src/func/registry.rs index 258ab53e32752..09ac35e92b14f 100644 --- a/crates/bevy_reflect/src/func/registry.rs +++ b/crates/bevy_reflect/src/func/registry.rs @@ -6,40 +6,40 @@ use bevy_utils::HashMap; use crate::func::{DynamicCallable, FunctionRegistrationError, IntoCallable}; -/// A registry of [reflected functions]. +/// A registry of [reflected callables]. /// -/// This is the function-equivalent to the [`TypeRegistry`]. +/// This is the callable-equivalent to the [`TypeRegistry`]. /// -/// All functions and closures are stored as `'static` closures via [`DynamicCallable<'static>`]. +/// All callables must be `'static` as they are stored as [`DynamicCallable<'static>`]. /// -/// [reflected functions]: crate::func +/// [reflected callables]: crate::func /// [`TypeRegistry`]: crate::TypeRegistry #[derive(Default)] pub struct FunctionRegistry { - /// Maps function [names] to their respective [`DynamicCallables`]. + /// Maps callable [names] to their respective [`DynamicCallables`]. /// /// [names]: DynamicCallable::name /// [`DynamicCallables`]: DynamicCallable - functions: HashMap, DynamicCallable<'static>>, + callables: HashMap, DynamicCallable<'static>>, } impl FunctionRegistry { - /// Attempts to register the given function. + /// Attempts to register the given callable. /// - /// This function accepts both functions/closures that satisfy [`IntoCallable`] + /// This function accepts both callables that satisfy [`IntoCallable`] /// and direct [`DynamicCallable`] instances. - /// The given function will internally be stored as a [`DynamicCallable<'static>`] + /// The given callable will internally be stored as a [`DynamicCallable<'static>`] /// and mapped according to its [name]. /// - /// Because the function must have a name, + /// Because the callable must have a name, /// anonymous functions (e.g. `|a: i32, b: i32| { a + b }`) and closures must instead - /// be registered using [`register_with_name`] or converted to a [`DynamicCallable`] + /// be registered using [`register_with_name`] or manually converted to a [`DynamicCallable`] /// and named using [`DynamicCallable::with_name`]. /// Failure to do so will result in an error being returned. /// - /// If a registered function with the same name already exists, + /// If a registered callable with the same name already exists, /// it will not be registered again and an error will be returned. - /// To register the function anyway, overwriting any existing registration, + /// To register the callable anyway, overwriting any existing registration, /// use [`overwrite_registration`] instead. /// /// # Examples @@ -57,7 +57,7 @@ impl FunctionRegistry { /// # } /// ``` /// - /// Functions cannot be registered more than once. + /// Callables cannot be registered more than once. /// /// ``` /// # use bevy_reflect::func::{FunctionRegistrationError, FunctionRegistry, IntoCallable}; @@ -101,50 +101,51 @@ impl FunctionRegistry { /// [`overwrite_registration`]: Self::overwrite_registration pub fn register( &mut self, - function: F, + callable: F, ) -> Result<&mut Self, FunctionRegistrationError> where F: IntoCallable<'static, Marker> + 'static, { - let function = function.into_callable(); - let name = function + let callable = callable.into_callable(); + let name = callable .name() .ok_or(FunctionRegistrationError::MissingName)? .clone(); - self.functions - .try_insert(name, function.into_callable()) + self.callables + .try_insert(name, callable.into_callable()) .map_err(|err| FunctionRegistrationError::DuplicateName(err.entry.key().clone()))?; Ok(self) } - /// Attempts to register the given function with the given name. + /// Attempts to register the given callable with the given name. /// - /// This function accepts both functions/closures that satisfy [`IntoCallable`] + /// This function accepts both callables that satisfy [`IntoCallable`] /// and direct [`DynamicCallable`] instances. - /// The given function will internally be stored as a [`DynamicCallable<'static>`] + /// The given callable will internally be stored as a [`DynamicCallable<'static>`] /// with its [name] set to the given name. /// /// For named functions (e.g. `fn add(a: i32, b: i32) -> i32 { a + b }`) where a custom name is not needed, /// it's recommended to use [`register`] instead as the generated name is guaranteed to be unique. /// - /// If a registered function with the same name already exists, + /// If a registered callable with the same name already exists, /// it will not be registered again and an error will be returned. - /// To register the function anyway, overwriting any existing registration, + /// To register the callable anyway, overwriting any existing registration, /// use [`overwrite_registration_with_name`] instead. /// - /// To avoid conflicts, it's recommended to use a unique name for the function. - /// This can be achieved by "namespacing" the function with a unique identifier, + /// To avoid conflicts, it's recommended to use a unique name for the callable. + /// This can be achieved by "namespacing" the callable with a unique identifier, /// such as the name of your crate. /// - /// For example, to register a function, `add`, from a crate, `my_crate`, + /// For example, to register a callable, `add`, from a crate, `my_crate`, /// you could use the name, `"my_crate::add"`. /// - /// Another approach could be to use the [type name] of the function, - /// however, it should be noted that anonymous functions do _not_ have unique type names. + /// Another approach could be to use the [type name] of the callable, + /// however, it should be noted that anonymous functions and closures + ///are not guaranteed to have unique type names. /// /// This method is a convenience around calling [`IntoCallable::into_callable`] and [`DynamicCallable::with_name`] - /// on the function and inserting it into the registry using the [`register`] method. + /// on the callable and inserting it into the registry using the [`register`] method. /// /// # Examples /// @@ -196,32 +197,32 @@ impl FunctionRegistry { pub fn register_with_name( &mut self, name: impl Into>, - function: F, + callable: F, ) -> Result<&mut Self, FunctionRegistrationError> where F: IntoCallable<'static, Marker> + 'static, { - let function = function.into_callable().with_name(name); - self.register(function) + let callable = callable.into_callable().with_name(name); + self.register(callable) } - /// Registers the given function, overwriting any existing registration. + /// Registers the given callable, overwriting any existing registration. /// - /// This function accepts both functions/closures that satisfy [`IntoCallable`] + /// This function accepts both callables that satisfy [`IntoCallable`] /// and direct [`DynamicCallable`] instances. - /// The given function will internally be stored as a [`DynamicCallable<'static>`] + /// The given callable will internally be stored as a [`DynamicCallable<'static>`] /// and mapped according to its [name]. /// - /// Because the function must have a name, + /// Because the callable must have a name, /// anonymous functions (e.g. `|a: i32, b: i32| { a + b }`) and closures must instead - /// be registered using [`overwrite_registration_with_name`] or converted to a [`DynamicCallable`] + /// be registered using [`overwrite_registration_with_name`] or manually converted to a [`DynamicCallable`] /// and named using [`DynamicCallable::with_name`]. /// Failure to do so will result in an error being returned. /// /// To avoid overwriting existing registrations, /// it's recommended to use the [`register`] method instead. /// - /// Returns the previous function with the same name, if any. + /// Returns the previous callable with the same name, if any. /// /// [name]: DynamicCallable::name /// [`overwrite_registration_with_name`]: Self::overwrite_registration_with_name @@ -239,17 +240,17 @@ impl FunctionRegistry { .ok_or(FunctionRegistrationError::MissingName)? .clone(); - Ok(self.functions.insert(name, function)) + Ok(self.callables.insert(name, function)) } - /// Registers the given function, overwriting any existing registration. + /// Registers the given callable, overwriting any existing registration. /// - /// This function accepts both functions/closures that satisfy [`IntoCallable`] + /// This function accepts both callables that satisfy [`IntoCallable`] /// and direct [`DynamicCallable`] instances. - /// The given function will internally be stored as a [`DynamicCallable<'static>`] + /// The given callable will internally be stored as a [`DynamicCallable<'static>`] /// with its [name] set to the given name. /// - /// Functions are mapped according to their name. + /// Callables are mapped according to their name. /// To avoid overwriting existing registrations, /// it's recommended to use the [`register_with_name`] method instead. /// @@ -264,13 +265,13 @@ impl FunctionRegistry { pub fn overwrite_registration_with_name( &mut self, name: impl Into>, - function: F, + callable: F, ) -> Option> where F: IntoCallable<'static, Marker> + 'static, { - let function = function.into_callable().with_name(name); - match self.overwrite_registration(function) { + let callable = callable.into_callable().with_name(name); + match self.overwrite_registration(callable) { Ok(existing) => existing, Err(FunctionRegistrationError::MissingName) => { unreachable!("the function should have a name") @@ -281,39 +282,39 @@ impl FunctionRegistry { } } - /// Get a reference to a registered function or closure by [name]. + /// Get a reference to a registered callable by [name]. /// /// [name]: DynamicCallable::name pub fn get(&self, name: &str) -> Option<&DynamicCallable<'static>> { - self.functions.get(name) + self.callables.get(name) } - /// Returns `true` if a function or closure with the given [name] is registered. + /// Returns `true` if a callable with the given [name] is registered. /// /// [name]: DynamicCallable::name pub fn contains(&self, name: &str) -> bool { - self.functions.contains_key(name) + self.callables.contains_key(name) } - /// Returns an iterator over all registered functions/closures. + /// Returns an iterator over all registered callables. pub fn iter(&self) -> impl ExactSizeIterator> { - self.functions.values() + self.callables.values() } - /// Returns the number of registered functions/closures. + /// Returns the number of registered callables. pub fn len(&self) -> usize { - self.functions.len() + self.callables.len() } - /// Returns `true` if no functions or closures are registered. + /// Returns `true` if no callables are registered. pub fn is_empty(&self) -> bool { - self.functions.is_empty() + self.callables.is_empty() } } impl Debug for FunctionRegistry { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_set().entries(self.functions.values()).finish() + f.debug_set().entries(self.callables.values()).finish() } } @@ -411,7 +412,7 @@ mod tests { } #[test] - fn should_only_register_function_once() { + fn should_only_register_callable_once() { fn foo() -> i32 { 123 } diff --git a/crates/bevy_reflect/src/func/return_type.rs b/crates/bevy_reflect/src/func/return_type.rs index bedc295c63e4f..ffda35c2b86ef 100644 --- a/crates/bevy_reflect/src/func/return_type.rs +++ b/crates/bevy_reflect/src/func/return_type.rs @@ -6,13 +6,13 @@ use crate::PartialReflect; /// [`DynamicCallableMut`]: crate::func::DynamicCallableMut #[derive(Debug)] pub enum Return<'a> { - /// The function returns nothing (i.e. it returns `()`). + /// The callable returns nothing (i.e. it returns `()`). Unit, - /// The function returns an owned value. + /// The callable returns an owned value. Owned(Box), - /// The function returns a reference to a value. + /// The callable returns a reference to a value. Ref(&'a dyn PartialReflect), - /// The function returns a mutable reference to a value. + /// The callable returns a mutable reference to a value. Mut(&'a mut dyn PartialReflect), } From 44af4d8495474508054bef136f596e2a89fe2959 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 18 Aug 2024 21:12:23 -0700 Subject: [PATCH 5/8] Rename modules --- .../{dynamic_closure.rs => dynamic_callable.rs} | 0 ...ic_closure_mut.rs => dynamic_callable_mut.rs} | 0 .../func/{into_closure.rs => into_callable.rs} | 0 ...{into_closure_mut.rs => into_callable_mut.rs} | 0 crates/bevy_reflect/src/func/mod.rs | 16 ++++++++-------- 5 files changed, 8 insertions(+), 8 deletions(-) rename crates/bevy_reflect/src/func/{dynamic_closure.rs => dynamic_callable.rs} (100%) rename crates/bevy_reflect/src/func/{dynamic_closure_mut.rs => dynamic_callable_mut.rs} (100%) rename crates/bevy_reflect/src/func/{into_closure.rs => into_callable.rs} (100%) rename crates/bevy_reflect/src/func/{into_closure_mut.rs => into_callable_mut.rs} (100%) diff --git a/crates/bevy_reflect/src/func/dynamic_closure.rs b/crates/bevy_reflect/src/func/dynamic_callable.rs similarity index 100% rename from crates/bevy_reflect/src/func/dynamic_closure.rs rename to crates/bevy_reflect/src/func/dynamic_callable.rs diff --git a/crates/bevy_reflect/src/func/dynamic_closure_mut.rs b/crates/bevy_reflect/src/func/dynamic_callable_mut.rs similarity index 100% rename from crates/bevy_reflect/src/func/dynamic_closure_mut.rs rename to crates/bevy_reflect/src/func/dynamic_callable_mut.rs diff --git a/crates/bevy_reflect/src/func/into_closure.rs b/crates/bevy_reflect/src/func/into_callable.rs similarity index 100% rename from crates/bevy_reflect/src/func/into_closure.rs rename to crates/bevy_reflect/src/func/into_callable.rs diff --git a/crates/bevy_reflect/src/func/into_closure_mut.rs b/crates/bevy_reflect/src/func/into_callable_mut.rs similarity index 100% rename from crates/bevy_reflect/src/func/into_closure_mut.rs rename to crates/bevy_reflect/src/func/into_callable_mut.rs diff --git a/crates/bevy_reflect/src/func/mod.rs b/crates/bevy_reflect/src/func/mod.rs index 7228c2fa89937..ba91f65e9b6d5 100644 --- a/crates/bevy_reflect/src/func/mod.rs +++ b/crates/bevy_reflect/src/func/mod.rs @@ -99,24 +99,24 @@ //! [coherence issues]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#coherence-leak-check pub use args::{ArgError, ArgList, ArgValue}; -pub use dynamic_closure::*; -pub use dynamic_closure_mut::*; +pub use dynamic_callable::*; +pub use dynamic_callable_mut::*; pub use error::*; pub use info::*; -pub use into_closure::*; -pub use into_closure_mut::*; +pub use into_callable::*; +pub use into_callable_mut::*; pub use reflect_fn::*; pub use reflect_fn_mut::*; pub use registry::*; pub use return_type::*; pub mod args; -mod dynamic_closure; -mod dynamic_closure_mut; +mod dynamic_callable; +mod dynamic_callable_mut; mod error; mod info; -mod into_closure; -mod into_closure_mut; +mod into_callable; +mod into_callable_mut; pub(crate) mod macros; mod reflect_fn; mod reflect_fn_mut; From f45d2894978afebaa968fcffef422782df52938a Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 18 Aug 2024 22:09:42 -0700 Subject: [PATCH 6/8] Switch to "function" terminology --- benches/benches/bevy_reflect/function.rs | 12 +- crates/bevy_app/src/app.rs | 24 +-- crates/bevy_app/src/sub_app.rs | 4 +- .../bevy_reflect/compile_fail/tests/func.rs | 2 +- .../tests/into_callable/arguments_fail.rs | 8 +- .../tests/into_callable/closure_fail.rs | 6 +- .../tests/into_callable/return_fail.rs | 10 +- crates/bevy_reflect/src/func/args/arg.rs | 12 +- crates/bevy_reflect/src/func/args/from_arg.rs | 6 +- crates/bevy_reflect/src/func/args/info.rs | 26 +-- crates/bevy_reflect/src/func/args/list.rs | 6 +- crates/bevy_reflect/src/func/args/mod.rs | 6 +- .../bevy_reflect/src/func/dynamic_callable.rs | 108 +++++----- .../src/func/dynamic_callable_mut.rs | 128 ++++++------ crates/bevy_reflect/src/func/error.rs | 26 +-- crates/bevy_reflect/src/func/info.rs | 60 +++--- crates/bevy_reflect/src/func/into_callable.rs | 30 +-- .../src/func/into_callable_mut.rs | 40 ++-- crates/bevy_reflect/src/func/mod.rs | 37 ++-- crates/bevy_reflect/src/func/reflect_fn.rs | 12 +- .../bevy_reflect/src/func/reflect_fn_mut.rs | 13 +- crates/bevy_reflect/src/func/registry.rs | 192 +++++++++--------- crates/bevy_reflect/src/func/return_type.rs | 14 +- crates/bevy_reflect/src/lib.rs | 2 +- examples/reflection/function_reflection.rs | 43 ++-- 25 files changed, 415 insertions(+), 412 deletions(-) diff --git a/benches/benches/bevy_reflect/function.rs b/benches/benches/bevy_reflect/function.rs index bc06be65939d4..4eb97eee827b2 100644 --- a/benches/benches/bevy_reflect/function.rs +++ b/benches/benches/bevy_reflect/function.rs @@ -1,4 +1,4 @@ -use bevy_reflect::func::{ArgList, IntoCallable, TypedFunction}; +use bevy_reflect::func::{ArgList, IntoFunction, TypedFunction}; use bevy_reflect::prelude::*; use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; @@ -24,19 +24,19 @@ fn typed(c: &mut Criterion) { fn into(c: &mut Criterion) { c.benchmark_group("into") .bench_function("function", |b| { - b.iter(|| add.into_callable()); + b.iter(|| add.into_function()); }) .bench_function("closure", |b| { let capture = 25; let closure = |a: i32| a + capture; - b.iter(|| closure.into_callable()); + b.iter(|| closure.into_function()); }); } fn call(c: &mut Criterion) { c.benchmark_group("call") .bench_function("function", |b| { - let add = add.into_callable(); + let add = add.into_function(); b.iter_batched( || ArgList::new().push_owned(75_i32).push_owned(25_i32), |args| add.call(args), @@ -45,7 +45,7 @@ fn call(c: &mut Criterion) { }) .bench_function("closure", |b| { let capture = 25; - let add = (|a: i32| a + capture).into_callable(); + let add = (|a: i32| a + capture).into_function(); b.iter_batched( || ArgList::new().push_owned(75_i32), |args| add.call(args), @@ -56,7 +56,7 @@ fn call(c: &mut Criterion) { fn clone(c: &mut Criterion) { c.benchmark_group("clone").bench_function("function", |b| { - let add = add.into_callable(); + let add = add.into_function(); b.iter(|| add.clone()); }); } diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index 12dbb5ebefc11..e4fa508a69f26 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -605,16 +605,16 @@ impl App { /// Registers the given function into the [`AppFunctionRegistry`] resource. /// - /// The given function will internally be stored as a [`DynamicCallable`] + /// The given function will internally be stored as a [`DynamicFunction`] /// and mapped according to its [name]. /// /// Because the function must have a name, /// anonymous functions (e.g. `|a: i32, b: i32| { a + b }`) and closures must instead - /// be registered using [`register_function_with_name`] or converted to a [`DynamicCallable`] - /// and named using [`DynamicCallable::with_name`]. + /// be registered using [`register_function_with_name`] or converted to a [`DynamicFunction`] + /// and named using [`DynamicFunction::with_name`]. /// Failure to do so will result in a panic. /// - /// Only types that implement [`IntoCallable`] may be registered via this method. + /// Only types that implement [`IntoFunction`] may be registered via this method. /// /// See [`FunctionRegistry::register`] for more information. /// @@ -650,7 +650,7 @@ impl App { /// .register_function(add); /// ``` /// - /// Anonymous functions and closures should be registered using [`register_function_with_name`] or given a name using [`DynamicCallable::with_name`]. + /// Anonymous functions and closures should be registered using [`register_function_with_name`] or given a name using [`DynamicFunction::with_name`]. /// /// ```should_panic /// use bevy_app::App; @@ -660,15 +660,15 @@ impl App { /// ``` /// /// [`register_function_with_name`]: Self::register_function_with_name - /// [`DynamicCallable`]: bevy_reflect::func::DynamicCallable + /// [`DynamicFunction`]: bevy_reflect::func::DynamicFunction /// [name]: bevy_reflect::func::FunctionInfo::name - /// [`DynamicCallable::with_name`]: bevy_reflect::func::DynamicCallable::with_name - /// [`IntoCallable`]: bevy_reflect::func::IntoCallable + /// [`DynamicFunction::with_name`]: bevy_reflect::func::DynamicFunction::with_name + /// [`IntoFunction`]: bevy_reflect::func::IntoFunction /// [`FunctionRegistry::register`]: bevy_reflect::func::FunctionRegistry::register #[cfg(feature = "reflect_functions")] pub fn register_function(&mut self, function: F) -> &mut Self where - F: bevy_reflect::func::IntoCallable<'static, Marker> + 'static, + F: bevy_reflect::func::IntoFunction<'static, Marker> + 'static, { self.main_mut().register_function(function); self @@ -689,7 +689,7 @@ impl App { /// For named functions (e.g. `fn add(a: i32, b: i32) -> i32 { a + b }`) where a custom name is not needed, /// it's recommended to use [`register_function`] instead as the generated name is guaranteed to be unique. /// - /// Only types that implement [`IntoCallable`] may be registered via this method. + /// Only types that implement [`IntoFunction`] may be registered via this method. /// /// See [`FunctionRegistry::register_with_name`] for more information. /// @@ -738,7 +738,7 @@ impl App { /// /// [type name]: std::any::type_name /// [`register_function`]: Self::register_function - /// [`IntoCallable`]: bevy_reflect::func::IntoCallable + /// [`IntoFunction`]: bevy_reflect::func::IntoFunction /// [`FunctionRegistry::register_with_name`]: bevy_reflect::func::FunctionRegistry::register_with_name #[cfg(feature = "reflect_functions")] pub fn register_function_with_name( @@ -747,7 +747,7 @@ impl App { function: F, ) -> &mut Self where - F: bevy_reflect::func::IntoCallable<'static, Marker> + 'static, + F: bevy_reflect::func::IntoFunction<'static, Marker> + 'static, { self.main_mut().register_function_with_name(name, function); self diff --git a/crates/bevy_app/src/sub_app.rs b/crates/bevy_app/src/sub_app.rs index c12ea9f0c88bf..48ffe9738830e 100644 --- a/crates/bevy_app/src/sub_app.rs +++ b/crates/bevy_app/src/sub_app.rs @@ -413,7 +413,7 @@ impl SubApp { #[cfg(feature = "reflect_functions")] pub fn register_function(&mut self, function: F) -> &mut Self where - F: bevy_reflect::func::IntoCallable<'static, Marker> + 'static, + F: bevy_reflect::func::IntoFunction<'static, Marker> + 'static, { let registry = self.world.resource_mut::(); registry.write().register(function).unwrap(); @@ -428,7 +428,7 @@ impl SubApp { function: F, ) -> &mut Self where - F: bevy_reflect::func::IntoCallable<'static, Marker> + 'static, + F: bevy_reflect::func::IntoFunction<'static, Marker> + 'static, { let registry = self.world.resource_mut::(); registry.write().register_with_name(name, function).unwrap(); diff --git a/crates/bevy_reflect/compile_fail/tests/func.rs b/crates/bevy_reflect/compile_fail/tests/func.rs index 64b587fc6a848..51ec8397a7972 100644 --- a/crates/bevy_reflect/compile_fail/tests/func.rs +++ b/crates/bevy_reflect/compile_fail/tests/func.rs @@ -1,3 +1,3 @@ fn main() -> compile_fail_utils::ui_test::Result<()> { - compile_fail_utils::test("reflect_into_callable", "tests/into_callable") + compile_fail_utils::test("reflect_into_function", "tests/into_function") } diff --git a/crates/bevy_reflect/compile_fail/tests/into_callable/arguments_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_callable/arguments_fail.rs index c01c39c9cfda1..9187e874ec823 100644 --- a/crates/bevy_reflect/compile_fail/tests/into_callable/arguments_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/into_callable/arguments_fail.rs @@ -1,6 +1,6 @@ #![allow(unused)] -use bevy_reflect::func::IntoCallable; +use bevy_reflect::func::IntoFunction; use bevy_reflect::Reflect; fn pass(_: i32) {} @@ -30,11 +30,11 @@ struct Foo; fn argument_not_reflect(foo: Foo) {} fn main() { - let _ = pass.into_callable(); + let _ = pass.into_function(); - let _ = too_many_arguments.into_callable(); + let _ = too_many_arguments.into_function(); //~^ E0599 - let _ = argument_not_reflect.into_callable(); + let _ = argument_not_reflect.into_function(); //~^ E0599 } diff --git a/crates/bevy_reflect/compile_fail/tests/into_callable/closure_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_callable/closure_fail.rs index 07aa86a65be7e..0083198534a1e 100644 --- a/crates/bevy_reflect/compile_fail/tests/into_callable/closure_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/into_callable/closure_fail.rs @@ -1,6 +1,6 @@ #![allow(unused)] -use bevy_reflect::func::{DynamicCallable, IntoCallable}; +use bevy_reflect::func::{DynamicFunction, IntoFunction}; use bevy_reflect::Reflect; fn main() { @@ -8,11 +8,11 @@ fn main() { let closure_capture_owned = move || println!("{}", value); // Pass: - let _: DynamicCallable<'static> = closure_capture_owned.into_callable(); + let _: DynamicFunction<'static> = closure_capture_owned.into_function(); let value = String::from("Hello, World!"); let closure_capture_reference = || println!("{}", value); //~^ ERROR: `value` does not live long enough - let _: DynamicCallable<'static> = closure_capture_reference.into_callable(); + let _: DynamicFunction<'static> = closure_capture_reference.into_function(); } diff --git a/crates/bevy_reflect/compile_fail/tests/into_callable/return_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_callable/return_fail.rs index 5e2b8c81e219b..d73a3406b306b 100644 --- a/crates/bevy_reflect/compile_fail/tests/into_callable/return_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/into_callable/return_fail.rs @@ -1,6 +1,6 @@ #![allow(unused)] -use bevy_reflect::func::IntoCallable; +use bevy_reflect::func::IntoFunction; use bevy_reflect::Reflect; fn pass() -> i32 { @@ -22,13 +22,13 @@ fn return_with_invalid_lifetime<'a, 'b>(a: &'a String, b: &'b String) -> &'b Str } fn main() { - let _ = pass.into_callable(); + let _ = pass.into_function(); - let _ = return_not_reflect.into_callable(); + let _ = return_not_reflect.into_function(); //~^ E0599 - let _ = return_with_lifetime_pass.into_callable(); + let _ = return_with_lifetime_pass.into_function(); - let _ = return_with_invalid_lifetime.into_callable(); + let _ = return_with_invalid_lifetime.into_function(); //~^ E0599 } diff --git a/crates/bevy_reflect/src/func/args/arg.rs b/crates/bevy_reflect/src/func/args/arg.rs index 7910243e3d5b2..14c02eecf1175 100644 --- a/crates/bevy_reflect/src/func/args/arg.rs +++ b/crates/bevy_reflect/src/func/args/arg.rs @@ -2,10 +2,10 @@ use crate::func::args::{ArgError, FromArg, Ownership}; use crate::{PartialReflect, Reflect, TypePath}; use std::ops::Deref; -/// Represents an argument that can be passed to a [`DynamicCallable`] or [`DynamicCallableMut`]. +/// Represents an argument that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// -/// [`DynamicCallable`]: crate::func::DynamicCallable -/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut +/// [`DynamicFunction`]: crate::func::DynamicFunction +/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut #[derive(Debug)] pub struct Arg<'a> { index: usize, @@ -179,10 +179,10 @@ impl<'a> Arg<'a> { } } -/// Represents an argument that can be passed to a [`DynamicCallable`] or [`DynamicCallableMut`]. +/// Represents an argument that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// -/// [`DynamicCallable`]: crate::func::DynamicCallable -/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut +/// [`DynamicFunction`]: crate::func::DynamicFunction +/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut #[derive(Debug)] pub enum ArgValue<'a> { Owned(Box), diff --git a/crates/bevy_reflect/src/func/args/from_arg.rs b/crates/bevy_reflect/src/func/args/from_arg.rs index 90f82dedea12b..88d04aefe7525 100644 --- a/crates/bevy_reflect/src/func/args/from_arg.rs +++ b/crates/bevy_reflect/src/func/args/from_arg.rs @@ -3,7 +3,7 @@ use crate::func::args::{Arg, ArgError}; /// A trait for types that can be created from an [`Arg`]. /// /// This trait exists so that types can be automatically converted into an [`Arg`] -/// so they can be put into an [`ArgList`] and passed to a [`DynamicCallable`] or [`DynamicCallableMut`]. +/// so they can be put into an [`ArgList`] and passed to a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// /// This trait is used instead of a blanket [`From`] implementation due to coherence issues: /// we can't implement `From` for both `T` and `&T`/`&mut T`. @@ -11,8 +11,8 @@ use crate::func::args::{Arg, ArgError}; /// This trait is automatically implemented when using the `Reflect` [derive macro]. /// /// [`ArgList`]: crate::func::args::ArgList -/// [`DynamicCallable`]: crate::func::DynamicCallable -/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut +/// [`DynamicFunction`]: crate::func::DynamicFunction +/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut /// [derive macro]: derive@crate::Reflect pub trait FromArg { /// The type to convert into. diff --git a/crates/bevy_reflect/src/func/args/info.rs b/crates/bevy_reflect/src/func/args/info.rs index 734c12f5d8ae7..e932e77be3f33 100644 --- a/crates/bevy_reflect/src/func/args/info.rs +++ b/crates/bevy_reflect/src/func/args/info.rs @@ -3,14 +3,14 @@ use alloc::borrow::Cow; use crate::func::args::{GetOwnership, Ownership}; use crate::TypePath; -/// Type information for an [`Arg`] used in a [`DynamicCallable`] or [`DynamicCallableMut`]. +/// Type information for an [`Arg`] used in a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// /// [`Arg`]: crate::func::args::Arg -/// [`DynamicCallable`]: crate::func::DynamicCallable -/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut +/// [`DynamicFunction`]: crate::func::DynamicFunction +/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut #[derive(Debug, Clone)] pub struct ArgInfo { - /// The index of the argument within its callable. + /// The index of the argument within its function. index: usize, /// The name of the argument (if provided). name: Option>, @@ -44,7 +44,7 @@ impl ArgInfo { self } - /// The index of the argument within its callable. + /// The index of the argument within its function. pub fn index(&self) -> usize { self.index } @@ -53,16 +53,16 @@ impl ArgInfo { /// /// Note that this may return `None` even if the argument has a name. /// This is because the name needs to be manually set using [`Self::with_name`] - /// since the name can't be inferred from the callable type alone. + /// since the name can't be inferred from the function type alone. /// - /// For [`DynamicCallables`] created using [`IntoCallable`] - /// and [`DynamicCallableMuts`] created using [`IntoCallableMut`], + /// For [`DynamicFunctions`] created using [`IntoFunction`] + /// and [`DynamicFunctionMuts`] created using [`IntoFunctionMut`], /// the name will always be `None`. /// - /// [`DynamicCallables`]: crate::func::DynamicCallable - /// [`IntoCallable`]: crate::func::IntoCallable - /// [`DynamicCallableMuts`]: crate::func::DynamicCallableMut - /// [`IntoCallableMut`]: crate::func::IntoCallableMut + /// [`DynamicFunctions`]: crate::func::DynamicFunction + /// [`IntoFunction`]: crate::func::IntoFunction + /// [`DynamicFunctionMuts`]: crate::func::DynamicFunctionMut + /// [`IntoFunctionMut`]: crate::func::IntoFunctionMut pub fn name(&self) -> Option<&str> { self.name.as_deref() } @@ -96,7 +96,7 @@ impl ArgInfo { /// This is primarily used for error reporting and debugging. #[derive(Debug, Clone, PartialEq, Eq)] pub enum ArgId { - /// The index of the argument within its callable. + /// The index of the argument within its function. Index(usize), /// The name of the argument. Name(Cow<'static, str>), diff --git a/crates/bevy_reflect/src/func/args/list.rs b/crates/bevy_reflect/src/func/args/list.rs index a965ef636a2b9..15458250f4d8e 100644 --- a/crates/bevy_reflect/src/func/args/list.rs +++ b/crates/bevy_reflect/src/func/args/list.rs @@ -3,7 +3,7 @@ use crate::func::ArgError; use crate::{PartialReflect, Reflect, TypePath}; use std::collections::VecDeque; -/// A list of arguments that can be passed to a [`DynamicCallable`] or [`DynamicCallableMut`]. +/// A list of arguments that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// /// # Example /// @@ -26,8 +26,8 @@ use std::collections::VecDeque; /// ``` /// /// [arguments]: Arg -/// [`DynamicCallable`]: crate::func::DynamicCallable -/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut +/// [`DynamicFunction`]: crate::func::DynamicFunction +/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut #[derive(Default, Debug)] pub struct ArgList<'a> { list: VecDeque>, diff --git a/crates/bevy_reflect/src/func/args/mod.rs b/crates/bevy_reflect/src/func/args/mod.rs index 361e23d419ef6..da0ea00bb1abd 100644 --- a/crates/bevy_reflect/src/func/args/mod.rs +++ b/crates/bevy_reflect/src/func/args/mod.rs @@ -1,7 +1,7 @@ -//! Argument types and utilities for working with [`DynamicCallable`] and [`DynamicCallableMut`]. +//! Argument types and utilities for working with [`DynamicFunction`] and [`DynamicFunctionMut`]. //! -//! [`DynamicCallable`]: crate::func::DynamicCallable -//! [`DynamicCallableMut`]: crate::func::DynamicCallableMut +//! [`DynamicFunction`]: crate::func::DynamicFunction +//! [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut pub use arg::*; pub use error::*; diff --git a/crates/bevy_reflect/src/func/dynamic_callable.rs b/crates/bevy_reflect/src/func/dynamic_callable.rs index d307164d2e1e7..2794f1cb9ae89 100644 --- a/crates/bevy_reflect/src/func/dynamic_callable.rs +++ b/crates/bevy_reflect/src/func/dynamic_callable.rs @@ -1,37 +1,37 @@ use crate::func::args::{ArgInfo, ArgList}; use crate::func::info::FunctionInfo; -use crate::func::{DynamicCallableMut, FunctionResult, IntoCallable, IntoCallableMut, ReturnInfo}; +use crate::func::{DynamicFunctionMut, FunctionResult, IntoFunction, IntoFunctionMut, ReturnInfo}; use alloc::borrow::Cow; use core::fmt::{Debug, Formatter}; use std::sync::Arc; -/// A dynamic representation of a callable. +/// A dynamic representation of a function. /// /// This type can be used to represent any callable that satisfies [`Fn`] /// (or the reflection-based equivalent, [`ReflectFn`]). /// That is, any function or closure that does not mutably borrow data from its environment. /// -/// For callables that do need to capture their environment mutably, -/// see [`DynamicCallableMut`]. +/// For functions that do need to capture their environment mutably (i.e. mutable closures), +/// see [`DynamicFunctionMut`]. /// /// See the [module-level documentation] for more information. /// /// You will generally not need to construct this manually. -/// Instead, many functions and closures can be automatically converted using the [`IntoCallable`] trait. +/// Instead, many functions and closures can be automatically converted using the [`IntoFunction`] trait. /// /// # Example /// -/// Most of the time, a [`DynamicCallable`] can be created using the [`IntoCallable`] trait: +/// Most of the time, a [`DynamicFunction`] can be created using the [`IntoFunction`] trait: /// /// ``` -/// # use bevy_reflect::func::{ArgList, DynamicCallable, FunctionInfo, IntoCallable}; +/// # use bevy_reflect::func::{ArgList, DynamicFunction, FunctionInfo, IntoFunction}; /// # /// fn add(a: i32, b: i32) -> i32 { /// a + b /// } /// -/// // Convert the function into a dynamic callable using `IntoCallable::into_callable`: -/// let mut func: DynamicCallable = add.into_callable(); +/// // Convert the function into a dynamic function using `IntoFunction::into_function`: +/// let mut func: DynamicFunction = add.into_function(); /// /// // Dynamically call it: /// let args = ArgList::default().push_owned(25_i32).push_owned(75_i32); @@ -43,19 +43,19 @@ use std::sync::Arc; /// /// [`ReflectFn`]: crate::func::ReflectFn /// [module-level documentation]: crate::func -pub struct DynamicCallable<'env> { +pub struct DynamicFunction<'env> { pub(super) info: FunctionInfo, pub(super) func: Arc Fn(ArgList<'a>) -> FunctionResult<'a> + Send + Sync + 'env>, } -impl<'env> DynamicCallable<'env> { - /// Create a new [`DynamicCallable`]. +impl<'env> DynamicFunction<'env> { + /// Create a new [`DynamicFunction`]. /// /// The given function can be used to call out to any other callable, /// including functions, closures, or methods. /// - /// It's important that the callable signature matches the provided [`FunctionInfo`]. - /// This info may be used by consumers of this callable for validation and debugging. + /// It's important that the function signature matches the provided [`FunctionInfo`]. + /// This info may be used by consumers of this function for validation and debugging. pub fn new Fn(ArgList<'a>) -> FunctionResult<'a> + Send + Sync + 'env>( func: F, info: FunctionInfo, @@ -66,46 +66,46 @@ impl<'env> DynamicCallable<'env> { } } - /// Set the name of the callable. + /// Set the name of the function. /// - /// For [`DynamicCallables`] created using [`IntoCallable`], - /// the default name will always be the full path to the callable as returned by [`std::any::type_name`], - /// unless the callable is a closure, anonymous function, or function pointer, + /// For [`DynamicFunctions`] created using [`IntoFunction`], + /// the default name will always be the full path to the function as returned by [`std::any::type_name`], + /// unless the function is a closure, anonymous function, or function pointer, /// in which case the name will be `None`. /// - /// [`DynamicCallables`]: DynamicCallable + /// [`DynamicFunctions`]: DynamicFunction pub fn with_name(mut self, name: impl Into>) -> Self { self.info = self.info.with_name(name); self } - /// Set the argument information of the callable. + /// Set the argument information of the function. /// - /// It's important that the arguments match the intended callable signature, - /// as this can be used by consumers of this callable for validation and debugging. + /// It's important that the arguments match the intended function signature, + /// as this can be used by consumers of this function for validation and debugging. pub fn with_args(mut self, args: Vec) -> Self { self.info = self.info.with_args(args); self } - /// Set the return information of the callable. + /// Set the return information of the function. pub fn with_return_info(mut self, return_info: ReturnInfo) -> Self { self.info = self.info.with_return_info(return_info); self } - /// Invoke the callable with the given arguments. + /// Call the function with the given arguments. /// /// # Example /// /// ``` - /// # use bevy_reflect::func::{IntoCallable, ArgList}; + /// # use bevy_reflect::func::{IntoFunction, ArgList}; /// let c = 23; /// let add = |a: i32, b: i32| -> i32 { /// a + b + c /// }; /// - /// let mut func = add.into_callable().with_name("add"); + /// let mut func = add.into_function().with_name("add"); /// let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); /// let result = func.call(args).unwrap().unwrap_owned(); /// assert_eq!(result.try_take::().unwrap(), 123); @@ -114,37 +114,37 @@ impl<'env> DynamicCallable<'env> { (self.func)(args) } - /// Returns the callable info. + /// Returns the function info. pub fn info(&self) -> &FunctionInfo { &self.info } - /// The [name] of the callable. + /// The [name] of the function. /// - /// For [`DynamicCallables`] created using [`IntoCallable`], - /// the default name will always be the full path to the callable as returned by [`std::any::type_name`], - /// unless the callable is a closure, anonymous function, or function pointer, + /// For [`DynamicFunctions`] created using [`IntoFunction`], + /// the default name will always be the full path to the function as returned by [`std::any::type_name`], + /// unless the function is a closure, anonymous function, or function pointer, /// in which case the name will be `None`. /// /// This can be overridden using [`with_name`]. /// /// [name]: FunctionInfo::name - /// [`DynamicCallables`]: DynamicCallable + /// [`DynamicFunctions`]: DynamicFunction /// [`with_name`]: Self::with_name pub fn name(&self) -> Option<&Cow<'static, str>> { self.info.name() } } -/// Outputs the closure's signature. +/// Outputs the function's signature. /// -/// This takes the format: `DynamicCallable(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type})`. +/// This takes the format: `DynamicFunction(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type})`. /// -/// Names for arguments and the callable itself are optional and will default to `_` if not provided. -impl<'env> Debug for DynamicCallable<'env> { +/// Names for arguments and the function itself are optional and will default to `_` if not provided. +impl<'env> Debug for DynamicFunction<'env> { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { let name = self.info.name().unwrap_or(&Cow::Borrowed("_")); - write!(f, "DynamicCallable(fn {name}(")?; + write!(f, "DynamicFunction(fn {name}(")?; for (index, arg) in self.info.args().iter().enumerate() { let name = arg.name().unwrap_or("_"); @@ -161,7 +161,7 @@ impl<'env> Debug for DynamicCallable<'env> { } } -impl<'env> Clone for DynamicCallable<'env> { +impl<'env> Clone for DynamicFunction<'env> { fn clone(&self) -> Self { Self { info: self.info.clone(), @@ -170,17 +170,17 @@ impl<'env> Clone for DynamicCallable<'env> { } } -impl<'env> IntoCallable<'env, ()> for DynamicCallable<'env> { +impl<'env> IntoFunction<'env, ()> for DynamicFunction<'env> { #[inline] - fn into_callable(self) -> DynamicCallable<'env> { + fn into_function(self) -> DynamicFunction<'env> { self } } -impl<'env> IntoCallableMut<'env, ()> for DynamicCallable<'env> { +impl<'env> IntoFunctionMut<'env, ()> for DynamicFunction<'env> { #[inline] - fn into_callable_mut(self) -> DynamicCallableMut<'env> { - DynamicCallableMut::from(self) + fn into_function_mut(self) -> DynamicFunctionMut<'env> { + DynamicFunctionMut::from(self) } } @@ -189,32 +189,32 @@ mod tests { use super::*; #[test] - fn should_overwrite_callable_name() { + fn should_overwrite_function_name() { let c = 23; let func = (|a: i32, b: i32| a + b + c) - .into_callable() - .with_name("my_callable"); - assert_eq!(func.info().name().unwrap(), "my_callable"); + .into_function() + .with_name("my_function"); + assert_eq!(func.info().name().unwrap(), "my_function"); } #[test] - fn should_convert_dynamic_callable_with_into_callable() { - fn make_closure<'env, F: IntoCallable<'env, M>, M>(f: F) -> DynamicCallable<'env> { - f.into_callable() + fn should_convert_dynamic_function_with_into_function() { + fn make_closure<'env, F: IntoFunction<'env, M>, M>(f: F) -> DynamicFunction<'env> { + f.into_function() } let c = 23; - let callable: DynamicCallable = make_closure(|a: i32, b: i32| a + b + c); - let _: DynamicCallable = make_closure(callable); + let function: DynamicFunction = make_closure(|a: i32, b: i32| a + b + c); + let _: DynamicFunction = make_closure(function); } #[test] - fn should_clone_dynamic_callable() { + fn should_clone_dynamic_function() { let hello = String::from("Hello"); let greet = |name: &String| -> String { format!("{}, {}!", hello, name) }; - let greet = greet.into_callable().with_name("greet"); + let greet = greet.into_function().with_name("greet"); let clone = greet.clone(); assert_eq!(greet.name().unwrap(), "greet"); diff --git a/crates/bevy_reflect/src/func/dynamic_callable_mut.rs b/crates/bevy_reflect/src/func/dynamic_callable_mut.rs index d46ab3ff60ec6..06d1e0f71c463 100644 --- a/crates/bevy_reflect/src/func/dynamic_callable_mut.rs +++ b/crates/bevy_reflect/src/func/dynamic_callable_mut.rs @@ -3,30 +3,30 @@ use core::fmt::{Debug, Formatter}; use crate::func::args::{ArgInfo, ArgList}; use crate::func::info::FunctionInfo; -use crate::func::{DynamicCallable, FunctionResult, IntoCallable, IntoCallableMut, ReturnInfo}; +use crate::func::{DynamicFunction, FunctionResult, IntoFunctionMut, ReturnInfo}; -/// A dynamic representation of a callable. +/// A dynamic representation of a function. /// /// This type can be used to represent any callable that satisfies [`FnMut`] /// (or the reflection-based equivalent, [`ReflectFnMut`]). /// That is, any function or closure. /// -/// For callables that do not need to capture their environment mutably, -/// it's recommended to use [`DynamicCallable`] instead. +/// For functions that do not need to capture their environment mutably, +/// it's recommended to use [`DynamicFunction`] instead. /// -/// This type can be seen as a superset of [`DynamicCallable`]. +/// This type can be seen as a superset of [`DynamicFunction`]. /// /// See the [module-level documentation] for more information. /// /// You will generally not need to construct this manually. -/// Instead, many functions and closures can be automatically converted using the [`IntoCallableMut`] trait. +/// Instead, many functions and closures can be automatically converted using the [`IntoFunctionMut`] trait. /// /// # Example /// -/// Most of the time, a [`DynamicCallableMut`] can be created using the [`IntoCallableMut`] trait: +/// Most of the time, a [`DynamicFunctionMut`] can be created using the [`IntoFunctionMut`] trait: /// /// ``` -/// # use bevy_reflect::func::{ArgList, DynamicCallableMut, FunctionInfo, IntoCallableMut}; +/// # use bevy_reflect::func::{ArgList, DynamicFunctionMut, FunctionInfo, IntoFunctionMut}; /// # /// let mut list: Vec = vec![1, 2, 3]; /// @@ -37,12 +37,12 @@ use crate::func::{DynamicCallable, FunctionResult, IntoCallable, IntoCallableMut /// old_value /// }; /// -/// // Since this closure mutably borrows data, we can't convert it into a regular `DynamicCallable`, +/// // Since this closure mutably borrows data, we can't convert it into a regular `DynamicFunction`, /// // as doing so would result in a compile-time error: -/// // let mut func: DynamicCallable = replace.into_callable(); +/// // let mut func: DynamicFunction = replace.into_function(); /// -/// // Instead, we convert it into a dynamic callable using `IntoCallableMut::into_callable_mut`: -/// let mut func: DynamicCallableMut = replace.into_callable_mut(); +/// // Instead, we convert it into a `DynamicFunctionMut` using `IntoFunctionMut::into_function_mut`: +/// let mut func: DynamicFunctionMut = replace.into_function_mut(); /// /// // Dynamically call it: /// let args = ArgList::default().push_owned(1_usize).push_owned(-2_i32); @@ -54,26 +54,26 @@ use crate::func::{DynamicCallable, FunctionResult, IntoCallable, IntoCallableMut /// // Note that `func` still has a reference to `list`, /// // so we need to drop it before we can access `list` again. /// // Alternatively, we could have invoked `func` with -/// // `DynamicCallableMut::call_once` to immediately consume it. +/// // `DynamicFunctionMut::call_once` to immediately consume it. /// drop(func); /// assert_eq!(list, vec![1, -2, 3]); /// ``` /// /// [`ReflectFnMut`]: crate::func::ReflectFnMut /// [module-level documentation]: crate::func -pub struct DynamicCallableMut<'env> { +pub struct DynamicFunctionMut<'env> { info: FunctionInfo, func: Box FnMut(ArgList<'a>) -> FunctionResult<'a> + 'env>, } -impl<'env> DynamicCallableMut<'env> { - /// Create a new [`DynamicCallableMut`]. +impl<'env> DynamicFunctionMut<'env> { + /// Create a new [`DynamicFunctionMut`]. /// /// The given function can be used to call out to any other callable, /// including functions, closures, or methods. /// - /// It's important that the callable signature matches the provided [`FunctionInfo`]. - /// This info may be used by consumers of this callable for validation and debugging. + /// It's important that the function signature matches the provided [`FunctionInfo`]. + /// This info may be used by consumers of this function for validation and debugging. pub fn new FnMut(ArgList<'a>) -> FunctionResult<'a> + 'env>( func: F, info: FunctionInfo, @@ -84,75 +84,75 @@ impl<'env> DynamicCallableMut<'env> { } } - /// Set the name of the callable. + /// Set the name of the function. /// - /// For [`DynamicCallableMuts`] created using [`IntoCallableMut`], - /// the default name will always be the full path to the callable as returned by [`std::any::type_name`], - /// unless the callable is a closure, anonymous function, or function pointer, + /// For [`DynamicFunctionMuts`] created using [`IntoFunctionMut`], + /// the default name will always be the full path to the function as returned by [`std::any::type_name`], + /// unless the function is a closure, anonymous function, or function pointer, /// in which case the name will be `None`. /// - /// [`DynamicCallableMuts`]: DynamicCallableMut + /// [`DynamicFunctionMuts`]: DynamicFunctionMut pub fn with_name(mut self, name: impl Into>) -> Self { self.info = self.info.with_name(name); self } - /// Set the argument information of the callable. + /// Set the argument information of the function. /// - /// It's important that the arguments match the intended callable signature, - /// as this can be used by consumers of this callable for validation and debugging. + /// It's important that the arguments match the intended function signature, + /// as this can be used by consumers of this function for validation and debugging. pub fn with_args(mut self, args: Vec) -> Self { self.info = self.info.with_args(args); self } - /// Set the return information of the callable. + /// Set the return information of the function. pub fn with_return_info(mut self, return_info: ReturnInfo) -> Self { self.info = self.info.with_return_info(return_info); self } - /// Invoke the callable with the given arguments. + /// Call the function with the given arguments. /// - /// Variables that are captured mutably by this callable - /// won't be usable until this callable is dropped. - /// Consider using [`call_once`] if you want to consume the callable + /// Variables that are captured mutably by this function + /// won't be usable until this function is dropped. + /// Consider using [`call_once`] if you want to consume the function /// immediately after calling it. /// /// # Example /// /// ``` - /// # use bevy_reflect::func::{IntoCallableMut, ArgList}; + /// # use bevy_reflect::func::{IntoFunctionMut, ArgList}; /// let mut total = 0; /// let add = |a: i32, b: i32| -> i32 { /// total = a + b; /// total /// }; /// - /// let mut func = add.into_callable_mut().with_name("add"); + /// let mut func = add.into_function_mut().with_name("add"); /// let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); /// let result = func.call(args).unwrap().unwrap_owned(); /// assert_eq!(result.try_take::().unwrap(), 100); /// ``` /// - /// [`call_once`]: DynamicCallableMut::call_once + /// [`call_once`]: DynamicFunctionMut::call_once pub fn call<'a>(&mut self, args: ArgList<'a>) -> FunctionResult<'a> { (self.func)(args) } - /// Invoke the callable with the given arguments and consume it. + /// Call the function with the given arguments and consume it. /// - /// This is useful for callables that capture their environment mutably + /// This is useful for functions that capture their environment mutably /// because otherwise any captured variables would still be borrowed by it. /// /// # Example /// /// ``` - /// # use bevy_reflect::func::{IntoCallableMut, ArgList}; + /// # use bevy_reflect::func::{IntoFunctionMut, ArgList}; /// let mut count = 0; /// let increment = |amount: i32| count += amount; /// - /// let increment_function = increment.into_callable_mut(); + /// let increment_function = increment.into_function_mut(); /// let args = ArgList::new().push_owned(5_i32); /// /// // We need to drop `increment_function` here so that we @@ -165,37 +165,37 @@ impl<'env> DynamicCallableMut<'env> { (self.func)(args) } - /// Returns the callable info. + /// Returns the function info. pub fn info(&self) -> &FunctionInfo { &self.info } - /// The [name] of the callable. + /// The [name] of the function. /// - /// For [`DynamicCallableMuts`] created using [`IntoCallableMut`], - /// the default name will always be the full path to the callable as returned by [`std::any::type_name`], - /// unless the callable is a closure, anonymous function, or function pointer, + /// For [`DynamicFunctionMuts`] created using [`IntoFunctionMut`], + /// the default name will always be the full path to the function as returned by [`std::any::type_name`], + /// unless the function is a closure, anonymous function, or function pointer, /// in which case the name will be `None`. /// /// This can be overridden using [`with_name`]. /// /// [name]: FunctionInfo::name - /// [`DynamicCallableMuts`]: DynamicCallableMut + /// [`DynamicFunctionMuts`]: DynamicFunctionMut /// [`with_name`]: Self::with_name pub fn name(&self) -> Option<&Cow<'static, str>> { self.info.name() } } -/// Outputs the callable's signature. +/// Outputs the function's signature. /// -/// This takes the format: `DynamicCallableMut(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type})`. +/// This takes the format: `DynamicFunctionMut(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type})`. /// -/// Names for arguments and the callable itself are optional and will default to `_` if not provided. -impl<'env> Debug for DynamicCallableMut<'env> { +/// Names for arguments and the function itself are optional and will default to `_` if not provided. +impl<'env> Debug for DynamicFunctionMut<'env> { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { let name = self.info.name().unwrap_or(&Cow::Borrowed("_")); - write!(f, "DynamicCallableMut(fn {name}(")?; + write!(f, "DynamicFunctionMut(fn {name}(")?; for (index, arg) in self.info.args().iter().enumerate() { let name = arg.name().unwrap_or("_"); @@ -212,19 +212,19 @@ impl<'env> Debug for DynamicCallableMut<'env> { } } -impl<'env> From> for DynamicCallableMut<'env> { +impl<'env> From> for DynamicFunctionMut<'env> { #[inline] - fn from(closure: DynamicCallable<'env>) -> Self { + fn from(function: DynamicFunction<'env>) -> Self { Self { - info: closure.info, - func: Box::new(move |args| (closure.func)(args)), + info: function.info, + func: Box::new(move |args| (function.func)(args)), } } } -impl<'env> IntoCallableMut<'env, ()> for DynamicCallableMut<'env> { +impl<'env> IntoFunctionMut<'env, ()> for DynamicFunctionMut<'env> { #[inline] - fn into_callable_mut(self) -> DynamicCallableMut<'env> { + fn into_function_mut(self) -> DynamicFunctionMut<'env> { self } } @@ -234,22 +234,22 @@ mod tests { use super::*; #[test] - fn should_overwrite_callable_name() { + fn should_overwrite_function_name() { let mut total = 0; let func = (|a: i32, b: i32| total = a + b) - .into_callable_mut() - .with_name("my_callable"); - assert_eq!(func.info().name().unwrap(), "my_callable"); + .into_function_mut() + .with_name("my_function"); + assert_eq!(func.info().name().unwrap(), "my_function"); } #[test] - fn should_convert_dynamic_callable_mut_with_into_callable() { - fn make_closure<'env, F: IntoCallableMut<'env, M>, M>(f: F) -> DynamicCallableMut<'env> { - f.into_callable_mut() + fn should_convert_dynamic_function_mut_with_into_function() { + fn make_closure<'env, F: IntoFunctionMut<'env, M>, M>(f: F) -> DynamicFunctionMut<'env> { + f.into_function_mut() } let mut total = 0; - let closure: DynamicCallableMut = make_closure(|a: i32, b: i32| total = a + b); - let _: DynamicCallableMut = make_closure(closure); + let closure: DynamicFunctionMut = make_closure(|a: i32, b: i32| total = a + b); + let _: DynamicFunctionMut = make_closure(closure); } } diff --git a/crates/bevy_reflect/src/func/error.rs b/crates/bevy_reflect/src/func/error.rs index 90bab4ef98483..a37123f1b6cba 100644 --- a/crates/bevy_reflect/src/func/error.rs +++ b/crates/bevy_reflect/src/func/error.rs @@ -3,10 +3,10 @@ use crate::func::Return; use alloc::borrow::Cow; use thiserror::Error; -/// An error that occurs when calling a [`DynamicCallable`] or [`DynamicCallableMut`]. +/// An error that occurs when calling a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// -/// [`DynamicCallable`]: crate::func::DynamicCallable -/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut +/// [`DynamicFunction`]: crate::func::DynamicFunction +/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut #[derive(Debug, Error, PartialEq)] pub enum FunctionError { /// An error occurred while converting an argument. @@ -17,26 +17,26 @@ pub enum FunctionError { ArgCountMismatch { expected: usize, received: usize }, } -/// The result of calling a dynamic [`DynamicCallable`] or [`DynamicCallableMut`]. +/// The result of calling a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// -/// Returns `Ok(value)` if the callable was called successfully, +/// Returns `Ok(value)` if the function was called successfully, /// where `value` is the [`Return`] value of the function. /// -/// [`DynamicCallable`]: crate::func::DynamicCallable -/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut +/// [`DynamicFunction`]: crate::func::DynamicFunction +/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut pub type FunctionResult<'a> = Result, FunctionError>; -/// An error that occurs when registering a callable into a [`FunctionRegistry`]. +/// An error that occurs when registering a function into a [`FunctionRegistry`]. /// /// [`FunctionRegistry`]: crate::func::FunctionRegistry #[derive(Debug, Error, PartialEq)] pub enum FunctionRegistrationError { - /// A callable with the given name has already been registered. + /// A function with the given name has already been registered. /// - /// Contains the duplicate callable name. - #[error("a callable has already been registered with name {0:?}")] + /// Contains the duplicate function name. + #[error("a function has already been registered with name {0:?}")] DuplicateName(Cow<'static, str>), - /// The callable is missing a name by which it can be registered. - #[error("callable name is missing")] + /// The function is missing a name by which it can be registered. + #[error("function name is missing")] MissingName, } diff --git a/crates/bevy_reflect/src/func/info.rs b/crates/bevy_reflect/src/func/info.rs index bfc7c6e18387e..413af8a3ed511 100644 --- a/crates/bevy_reflect/src/func/info.rs +++ b/crates/bevy_reflect/src/func/info.rs @@ -5,13 +5,13 @@ use bevy_utils::all_tuples; use crate::func::args::{ArgInfo, GetOwnership, Ownership}; use crate::TypePath; -/// Type information for a [`DynamicCallable`] or [`DynamicCallableMut`]. +/// Type information for a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// /// This information can be retrieved directly from certain functions and closures /// using the [`TypedFunction`] trait, and manually constructed otherwise. /// -/// [`DynamicCallable`]: crate::func::DynamicCallable -/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut +/// [`DynamicFunction`]: crate::func::DynamicFunction +/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut #[derive(Debug, Clone)] pub struct FunctionInfo { name: Option>, @@ -20,7 +20,7 @@ pub struct FunctionInfo { } impl FunctionInfo { - /// Create a new [`FunctionInfo`] for a callable with the given name. + /// Create a new [`FunctionInfo`] for a function with the given name. pub fn named(name: impl Into>) -> Self { Self { name: Some(name.into()), @@ -43,7 +43,7 @@ impl FunctionInfo { } } - /// Create a new [`FunctionInfo`] from the given callable. + /// Create a new [`FunctionInfo`] from the given function. pub fn from(function: &F) -> Self where F: TypedFunction, @@ -51,13 +51,13 @@ impl FunctionInfo { function.get_function_info() } - /// Set the name of the callable. + /// Set the name of the function. pub fn with_name(mut self, name: impl Into>) -> Self { self.name = Some(name.into()); self } - /// Push an argument onto the callable's argument list. + /// Push an argument onto the function's argument list. /// /// The order in which this method is called matters as it will determine the index of the argument /// based on the current number of arguments. @@ -70,20 +70,20 @@ impl FunctionInfo { self } - /// Set the arguments of the callable. + /// Set the arguments of the function. /// /// This will completely replace any existing arguments. /// - /// It's preferable to use [`Self::with_arg`] to add arguments to the callable + /// It's preferable to use [`Self::with_arg`] to add arguments to the function /// as it will automatically set the index of the argument. pub fn with_args(mut self, args: Vec) -> Self { self.args = args; self } - /// Set the [return information] of the callable. + /// Set the [return information] of the function. /// - /// To manually set the [`ReturnInfo`] of the callable, see [`Self::with_return_info`]. + /// To manually set the [`ReturnInfo`] of the function, see [`Self::with_return_info`]. /// /// [return information]: ReturnInfo pub fn with_return(mut self) -> Self { @@ -91,7 +91,7 @@ impl FunctionInfo { self } - /// Set the [return information] of the callable. + /// Set the [return information] of the function. /// /// This will completely replace any existing return information. /// @@ -103,41 +103,41 @@ impl FunctionInfo { self } - /// The name of the callable. + /// The name of the function. /// - /// For [`DynamicCallables`] created using [`IntoCallable`] or [`DynamicCallableMuts`] created using [`IntoCallableMut`], - /// the default name will always be the full path to the callable as returned by [`std::any::type_name`], - /// unless the callable is a closure, anonymous function, or function pointer, + /// For [`DynamicFunctions`] created using [`IntoFunction`] or [`DynamicFunctionMuts`] created using [`IntoFunctionMut`], + /// the default name will always be the full path to the function as returned by [`std::any::type_name`], + /// unless the function is a closure, anonymous function, or function pointer, /// in which case the name will be `None`. /// - /// [`DynamicCallables`]: crate::func::DynamicCallable - /// [`IntoCallable`]: crate::func::IntoCallable - /// [`DynamicCallableMuts`]: crate::func::DynamicCallableMut - /// [`IntoCallableMut`]: crate::func::IntoCallableMut + /// [`DynamicFunctions`]: crate::func::DynamicFunction + /// [`IntoFunction`]: crate::func::IntoFunction + /// [`DynamicFunctionMuts`]: crate::func::DynamicFunctionMut + /// [`IntoFunctionMut`]: crate::func::IntoFunctionMut pub fn name(&self) -> Option<&Cow<'static, str>> { self.name.as_ref() } - /// The arguments of the callable. + /// The arguments of the function. pub fn args(&self) -> &[ArgInfo] { &self.args } - /// The number of arguments the callable takes. + /// The number of arguments the function takes. pub fn arg_count(&self) -> usize { self.args.len() } - /// The return information of the callable. + /// The return information of the function. pub fn return_info(&self) -> &ReturnInfo { &self.return_info } } -/// Information about the return type of a [`DynamicCallable`] or [`DynamicCallableMut`]. +/// Information about the return type of a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// -/// [`DynamicCallable`]: crate::func::DynamicCallable -/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut +/// [`DynamicFunction`]: crate::func::DynamicFunction +/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut #[derive(Debug, Clone)] pub struct ReturnInfo { type_path: &'static str, @@ -164,9 +164,9 @@ impl ReturnInfo { } } -/// A static accessor to compile-time type information for callables. +/// A static accessor to compile-time type information for functions. /// -/// This is the equivalent of [`Typed`], but for callables. +/// This is the equivalent of [`Typed`], but for function. /// /// # Blanket Implementation /// @@ -178,7 +178,7 @@ impl ReturnInfo { /// - Closures that capture mutable references to their environment /// - Closures that take ownership of captured variables /// -/// For each of the above cases, the callable signature may only have up to 15 arguments, +/// For each of the above cases, the function signature may only have up to 15 arguments, /// not including an optional receiver argument (often `&self` or `&mut self`). /// This optional receiver argument may be either a mutable or immutable reference to a type. /// If the return type is also a reference, its lifetime will be bound to the lifetime of this receiver. @@ -223,7 +223,7 @@ pub trait TypedFunction { } } -/// Helper macro for implementing [`TypedFunction`] on Rust callables. +/// Helper macro for implementing [`TypedFunction`] on Rust functions. /// /// This currently implements it for the following signatures (where `argX` may be any of `T`, `&T`, or `&mut T`): /// - `FnMut(arg0, arg1, ..., argN) -> R` diff --git a/crates/bevy_reflect/src/func/into_callable.rs b/crates/bevy_reflect/src/func/into_callable.rs index ab7ae6755d547..3b52605aa31f4 100644 --- a/crates/bevy_reflect/src/func/into_callable.rs +++ b/crates/bevy_reflect/src/func/into_callable.rs @@ -1,6 +1,6 @@ -use crate::func::{DynamicCallable, ReflectFn, TypedFunction}; +use crate::func::{DynamicFunction, ReflectFn, TypedFunction}; -/// A trait for types that can be converted into a [`DynamicCallable`]. +/// A trait for types that can be converted into a [`DynamicFunction`]. /// /// This trait is automatically implemented for any type that implements /// [`ReflectFn`] and [`TypedFunction`]. @@ -13,23 +13,23 @@ use crate::func::{DynamicCallable, ReflectFn, TypedFunction}; /// [unconstrained type parameters] when defining impls with generic arguments or return types. /// This `Marker` can be any type, provided it doesn't conflict with other implementations. /// -/// Additionally, it has a lifetime parameter, `'env`, that is used to bound the lifetime of the callable. -/// For functions and some closures, this will end up just being `'static`, +/// Additionally, it has a lifetime parameter, `'env`, that is used to bound the lifetime of the function. +/// For named functions and some closures, this will end up just being `'static`, /// however, closures that borrow from their environment will have a lifetime bound to that environment. /// /// [module-level documentation]: crate::func /// [unconstrained type parameters]: https://doc.rust-lang.org/error_codes/E0207.html -pub trait IntoCallable<'env, Marker> { - /// Converts [`Self`] into a [`DynamicCallable`]. - fn into_callable(self) -> DynamicCallable<'env>; +pub trait IntoFunction<'env, Marker> { + /// Converts [`Self`] into a [`DynamicFunction`]. + fn into_function(self) -> DynamicFunction<'env>; } -impl<'env, F, Marker1, Marker2> IntoCallable<'env, (Marker1, Marker2)> for F +impl<'env, F, Marker1, Marker2> IntoFunction<'env, (Marker1, Marker2)> for F where F: ReflectFn<'env, Marker1> + TypedFunction + Send + Sync + 'env, { - fn into_callable(self) -> DynamicCallable<'env> { - DynamicCallable::new(move |args| self.reflect_call(args), Self::function_info()) + fn into_function(self) -> DynamicFunction<'env> { + DynamicFunction::new(move |args| self.reflect_call(args), Self::function_info()) } } @@ -39,21 +39,21 @@ mod tests { use crate::func::ArgList; #[test] - fn should_create_dynamic_callable_from_closure() { + fn should_create_dynamic_function_from_closure() { let c = 23; - let func = (|a: i32, b: i32| a + b + c).into_callable(); + let func = (|a: i32, b: i32| a + b + c).into_function(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); let result = func.call(args).unwrap().unwrap_owned(); assert_eq!(result.try_downcast_ref::(), Some(&123)); } #[test] - fn should_create_dynamic_callable_from_function() { + fn should_create_dynamic_function_from_function() { fn add(a: i32, b: i32) -> i32 { a + b } - let func = add.into_callable(); + let func = add.into_function(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); let result = func.call(args).unwrap().unwrap_owned(); assert_eq!(result.try_downcast_ref::(), Some(&100)); @@ -62,7 +62,7 @@ mod tests { #[test] fn should_default_closure_name_to_none() { let c = 23; - let func = (|a: i32, b: i32| a + b + c).into_callable(); + let func = (|a: i32, b: i32| a + b + c).into_function(); assert_eq!(func.info().name(), None); } } diff --git a/crates/bevy_reflect/src/func/into_callable_mut.rs b/crates/bevy_reflect/src/func/into_callable_mut.rs index 8326a6c3e4129..b4671047a658f 100644 --- a/crates/bevy_reflect/src/func/into_callable_mut.rs +++ b/crates/bevy_reflect/src/func/into_callable_mut.rs @@ -1,11 +1,11 @@ -use crate::func::{DynamicCallableMut, ReflectFnMut, TypedFunction}; +use crate::func::{DynamicFunctionMut, ReflectFnMut, TypedFunction}; -/// A trait for types that can be converted into a [`DynamicCallableMut`]. +/// A trait for types that can be converted into a [`DynamicFunctionMut`]. /// /// This trait is automatically implemented for any type that implements /// [`ReflectFnMut`] and [`TypedFunction`]. /// -/// This trait can be seen as a superset of [`IntoCallable`]. +/// This trait can be seen as a superset of [`IntoFunction`]. /// /// See the [module-level documentation] for more information. /// @@ -15,24 +15,24 @@ use crate::func::{DynamicCallableMut, ReflectFnMut, TypedFunction}; /// [unconstrained type parameters] when defining impls with generic arguments or return types. /// This `Marker` can be any type, provided it doesn't conflict with other implementations. /// -/// Additionally, it has a lifetime parameter, `'env`, that is used to bound the lifetime of the callable. -/// For functions and some closures, this will end up just being `'static`, +/// Additionally, it has a lifetime parameter, `'env`, that is used to bound the lifetime of the function. +/// For named functions and some closures, this will end up just being `'static`, /// however, closures that borrow from their environment will have a lifetime bound to that environment. /// -/// [`IntoCallable`]: crate::func::IntoCallable +/// [`IntoFunction`]: crate::func::IntoFunction /// [module-level documentation]: crate::func /// [unconstrained type parameters]: https://doc.rust-lang.org/error_codes/E0207.html -pub trait IntoCallableMut<'env, Marker> { - /// Converts [`Self`] into a [`DynamicCallableMut`]. - fn into_callable_mut(self) -> DynamicCallableMut<'env>; +pub trait IntoFunctionMut<'env, Marker> { + /// Converts [`Self`] into a [`DynamicFunctionMut`]. + fn into_function_mut(self) -> DynamicFunctionMut<'env>; } -impl<'env, F, Marker1, Marker2> IntoCallableMut<'env, (Marker1, Marker2)> for F +impl<'env, F, Marker1, Marker2> IntoFunctionMut<'env, (Marker1, Marker2)> for F where F: ReflectFnMut<'env, Marker1> + TypedFunction + 'env, { - fn into_callable_mut(mut self) -> DynamicCallableMut<'env> { - DynamicCallableMut::new( + fn into_function_mut(mut self) -> DynamicFunctionMut<'env> { + DynamicFunctionMut::new( move |args| self.reflect_call_mut(args), Self::function_info(), ) @@ -42,33 +42,33 @@ where #[cfg(test)] mod tests { use super::*; - use crate::func::{ArgList, IntoCallable}; + use crate::func::{ArgList, IntoFunction}; #[test] - fn should_create_dynamic_callable_mut_from_closure() { + fn should_create_dynamic_function_mut_from_closure() { let c = 23; - let func = (|a: i32, b: i32| a + b + c).into_callable(); + let func = (|a: i32, b: i32| a + b + c).into_function(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); let result = func.call(args).unwrap().unwrap_owned(); assert_eq!(result.try_downcast_ref::(), Some(&123)); } #[test] - fn should_create_dynamic_callable_mut_from_closure_with_mutable_capture() { + fn should_create_dynamic_function_mut_from_closure_with_mutable_capture() { let mut total = 0; - let func = (|a: i32, b: i32| total = a + b).into_callable_mut(); + let func = (|a: i32, b: i32| total = a + b).into_function_mut(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); func.call_once(args).unwrap(); assert_eq!(total, 100); } #[test] - fn should_create_dynamic_callable_mut_from_function() { + fn should_create_dynamic_function_mut_from_function() { fn add(a: i32, b: i32) -> i32 { a + b } - let mut func = add.into_callable_mut(); + let mut func = add.into_function_mut(); let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); let result = func.call(args).unwrap().unwrap_owned(); assert_eq!(result.try_downcast_ref::(), Some(&100)); @@ -77,7 +77,7 @@ mod tests { #[test] fn should_default_closure_name_to_none() { let mut total = 0; - let func = (|a: i32, b: i32| total = a + b).into_callable_mut(); + let func = (|a: i32, b: i32| total = a + b).into_function_mut(); assert_eq!(func.info().name(), None); } } diff --git a/crates/bevy_reflect/src/func/mod.rs b/crates/bevy_reflect/src/func/mod.rs index ba91f65e9b6d5..45a9a1a316c26 100644 --- a/crates/bevy_reflect/src/func/mod.rs +++ b/crates/bevy_reflect/src/func/mod.rs @@ -1,10 +1,10 @@ -//! Reflection-based dynamic callables. +//! Reflection-based dynamic functions. //! -//! This module provides a way to pass around and invoke callables dynamically -//! using the [`DynamicCallable`] and [`DynamicCallableMut`] types. +//! This module provides a way to pass around and call functions dynamically +//! using the [`DynamicFunction`] and [`DynamicFunctionMut`] types. //! //! Many simple functions and closures can be automatically converted to these types -//! using the [`IntoCallable`] and [`IntoCallableMut`] traits, respectively. +//! using the [`IntoFunction`] and [`IntoFunctionMut`] traits, respectively. //! //! Once this dynamic representation is created, it can be called with a set of arguments provided //! via an [`ArgList`]. @@ -17,12 +17,12 @@ //! ``` //! # use bevy_reflect::PartialReflect; //! # use bevy_reflect::func::args::ArgList; -//! # use bevy_reflect::func::{DynamicCallable, FunctionResult, IntoCallable, Return}; +//! # use bevy_reflect::func::{DynamicFunction, FunctionResult, IntoFunction, Return}; //! fn add(a: i32, b: i32) -> i32 { //! a + b //! } //! -//! let mut func: DynamicCallable = add.into_callable(); +//! let mut func: DynamicFunction = add.into_function(); //! let args: ArgList = ArgList::default() //! // Pushing a known type with owned ownership //! .push_owned(25_i32) @@ -33,23 +33,24 @@ //! assert_eq!(value.unwrap_owned().try_downcast_ref::(), Some(&100)); //! ``` //! -//! # Types of Callables +//! # Types of Functions //! -//! A "callable", put simply, is code that can be invoked with a set of arguments -//! to perform some action. +//! For simplicity, this module uses the umbrella term "function" to refer to any Rust callable: +//! code that can be invoked with a set of arguments to perform some action. //! //! In Rust, there are two main categories of callables: functions and closures. //! //! A "function" is a callable that does not capture its environment. -//! These are typically defined with the `fn` keyword, but may also use anonymous function syntax. +//! These are typically defined with the `fn` keyword, which are referred to as _named_ functions. +//! But they are also _anonymous_ functions, which are unnamed and defined with anonymous function syntax. //! //! ```rust -//! // This is a standard Rust function: +//! // This is a named function: //! fn add(a: i32, b: i32) -> i32 { //! a + b //! } //! -//! // This is an anonymous Rust function: +//! // This is an anonymous function: //! let add = |a: i32, b: i32| a + b; //! ``` //! @@ -72,7 +73,7 @@ //! //! # Valid Signatures //! -//! Many of the traits in this module have default blanket implementations over a specific set of callable signatures. +//! Many of the traits in this module have default blanket implementations over a specific set of function signatures. //! //! These signatures are: //! - `(...) -> R` @@ -91,7 +92,7 @@ //! namely the [lack of variadic generics] and certain [coherence issues]. //! //! For other functions that don't conform to one of the above signatures, -//! [`DynamicCallable`] and [`DynamicCallableMut`] can instead be created manually. +//! [`DynamicFunction`] and [`DynamicFunctionMut`] can instead be created manually. //! //! [`PartialReflect`]: crate::PartialReflect //! [`Reflect`]: crate::Reflect @@ -136,7 +137,7 @@ mod tests { fn should_error_on_missing_args() { fn foo(_: i32) {} - let func = foo.into_callable(); + let func = foo.into_function(); let args = ArgList::new(); let result = func.call(args); assert_eq!( @@ -152,7 +153,7 @@ mod tests { fn should_error_on_too_many_args() { fn foo() {} - let func = foo.into_callable(); + let func = foo.into_function(); let args = ArgList::new().push_owned(123_i32); let result = func.call(args); assert_eq!( @@ -168,7 +169,7 @@ mod tests { fn should_error_on_invalid_arg_type() { fn foo(_: i32) {} - let func = foo.into_callable(); + let func = foo.into_function(); let args = ArgList::new().push_owned(123_u32); let result = func.call(args); assert_eq!( @@ -185,7 +186,7 @@ mod tests { fn should_error_on_invalid_arg_ownership() { fn foo(_: &i32) {} - let func = foo.into_callable(); + let func = foo.into_function(); let args = ArgList::new().push_owned(123_i32); let result = func.call(args); assert_eq!( diff --git a/crates/bevy_reflect/src/func/reflect_fn.rs b/crates/bevy_reflect/src/func/reflect_fn.rs index 972eb6aad4f05..1dc1d31302309 100644 --- a/crates/bevy_reflect/src/func/reflect_fn.rs +++ b/crates/bevy_reflect/src/func/reflect_fn.rs @@ -7,7 +7,7 @@ use crate::{Reflect, TypePath}; /// A reflection-based version of the [`Fn`] trait. /// -/// This allows callables to be called dynamically through [reflection]. +/// This allows functions to be called dynamically through [reflection]. /// /// # Blanket Implementation /// @@ -18,14 +18,14 @@ use crate::{Reflect, TypePath}; /// - Closures that capture immutable references to their environment /// - Closures that take ownership of captured variables /// -/// For each of the above cases, the callable signature may only have up to 15 arguments, +/// For each of the above cases, the function signature may only have up to 15 arguments, /// not including an optional receiver argument (often `&self` or `&mut self`). /// This optional receiver argument may be either a mutable or immutable reference to a type. /// If the return type is also a reference, its lifetime will be bound to the lifetime of this receiver. /// /// See the [module-level documentation] for more information on valid signatures. /// -/// To handle callable that capture mutable references to their environment, +/// To handle functions that capture mutable references to their environment, /// see the [`ReflectFnMut`] trait instead. /// /// Arguments are expected to implement [`FromArg`], and the return type is expected to implement [`IntoReturn`]. @@ -53,7 +53,7 @@ use crate::{Reflect, TypePath}; /// This `Marker` can be any type, provided it doesn't conflict with other implementations. /// /// Additionally, it has a lifetime parameter, `'env`, that is used to bound the lifetime of the function. -/// For most functions, this will end up just being `'static`, +/// For named functions and some closures, this will end up just being `'static`, /// however, closures that borrow from their environment will have a lifetime bound to that environment. /// /// [reflection]: crate @@ -61,11 +61,11 @@ use crate::{Reflect, TypePath}; /// [derive macro]: derive@crate::Reflect /// [unconstrained type parameters]: https://doc.rust-lang.org/error_codes/E0207.html pub trait ReflectFn<'env, Marker>: ReflectFnMut<'env, Marker> { - /// Invoke the callable with the given arguments and return the result. + /// Call the function with the given arguments and return the result. fn reflect_call<'a>(&self, args: ArgList<'a>) -> FunctionResult<'a>; } -/// Helper macro for implementing [`ReflectFn`] on Rust callables. +/// Helper macro for implementing [`ReflectFn`] on Rust functions. /// /// This currently implements it for the following signatures (where `argX` may be any of `T`, `&T`, or `&mut T`): /// - `Fn(arg0, arg1, ..., argN) -> R` diff --git a/crates/bevy_reflect/src/func/reflect_fn_mut.rs b/crates/bevy_reflect/src/func/reflect_fn_mut.rs index cdfdc86a8be2e..a6a6bd6e9fa58 100644 --- a/crates/bevy_reflect/src/func/reflect_fn_mut.rs +++ b/crates/bevy_reflect/src/func/reflect_fn_mut.rs @@ -7,9 +7,10 @@ use crate::{Reflect, TypePath}; /// A reflection-based version of the [`FnMut`] trait. /// -/// This allows callables to be called dynamically through [reflection]. +/// This allows functions to be called dynamically through [reflection]. /// -/// This is a supertrait of [`ReflectFn`], and is used for callables that may mutate their environment. +/// This is a supertrait of [`ReflectFn`], and is used for functions that may mutate their environment, +/// such as closures that capture mutable references. /// /// # Blanket Implementation /// @@ -23,7 +24,7 @@ use crate::{Reflect, TypePath}; /// But also allows for: /// - Closures that capture mutable references to their environment /// -/// For each of the above cases, the callable signature may only have up to 15 arguments, +/// For each of the above cases, the function signature may only have up to 15 arguments, /// not including an optional receiver argument (often `&self` or `&mut self`). /// This optional receiver argument may be either a mutable or immutable reference to a type. /// If the return type is also a reference, its lifetime will be bound to the lifetime of this receiver. @@ -58,7 +59,7 @@ use crate::{Reflect, TypePath}; /// This `Marker` can be any type, provided it doesn't conflict with other implementations. /// /// Additionally, it has a lifetime parameter, `'env`, that is used to bound the lifetime of the function. -/// For most functions, this will end up just being `'static`, +/// For named functions and some closures, this will end up just being `'static`, /// however, closures that borrow from their environment will have a lifetime bound to that environment. /// /// [reflection]: crate @@ -67,11 +68,11 @@ use crate::{Reflect, TypePath}; /// [derive macro]: derive@crate::Reflect /// [unconstrained type parameters]: https://doc.rust-lang.org/error_codes/E0207.html pub trait ReflectFnMut<'env, Marker> { - /// Invoke the callable with the given arguments and return the result. + /// Call the function with the given arguments and return the result. fn reflect_call_mut<'a>(&mut self, args: ArgList<'a>) -> FunctionResult<'a>; } -/// Helper macro for implementing [`ReflectFnMut`] on Rust closures. +/// Helper macro for implementing [`ReflectFnMut`] on Rust functions. /// /// This currently implements it for the following signatures (where `argX` may be any of `T`, `&T`, or `&mut T`): /// - `FnMut(arg0, arg1, ..., argN) -> R` diff --git a/crates/bevy_reflect/src/func/registry.rs b/crates/bevy_reflect/src/func/registry.rs index 09ac35e92b14f..87f66a070da04 100644 --- a/crates/bevy_reflect/src/func/registry.rs +++ b/crates/bevy_reflect/src/func/registry.rs @@ -4,42 +4,42 @@ use std::sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}; use bevy_utils::HashMap; -use crate::func::{DynamicCallable, FunctionRegistrationError, IntoCallable}; +use crate::func::{DynamicFunction, FunctionRegistrationError, IntoFunction}; -/// A registry of [reflected callables]. +/// A registry of [reflected functions]. /// -/// This is the callable-equivalent to the [`TypeRegistry`]. +/// This is the function-equivalent to the [`TypeRegistry`]. /// -/// All callables must be `'static` as they are stored as [`DynamicCallable<'static>`]. +/// All functions must be `'static` as they are stored as [`DynamicFunction<'static>`]. /// -/// [reflected callables]: crate::func +/// [reflected functions]: crate::func /// [`TypeRegistry`]: crate::TypeRegistry #[derive(Default)] pub struct FunctionRegistry { - /// Maps callable [names] to their respective [`DynamicCallables`]. + /// Maps function [names] to their respective [`DynamicFunctions`]. /// - /// [names]: DynamicCallable::name - /// [`DynamicCallables`]: DynamicCallable - callables: HashMap, DynamicCallable<'static>>, + /// [names]: DynamicFunction::name + /// [`DynamicFunctions`]: DynamicFunction + functions: HashMap, DynamicFunction<'static>>, } impl FunctionRegistry { - /// Attempts to register the given callable. + /// Attempts to register the given function. /// - /// This function accepts both callables that satisfy [`IntoCallable`] - /// and direct [`DynamicCallable`] instances. - /// The given callable will internally be stored as a [`DynamicCallable<'static>`] + /// This function accepts both functions that satisfy [`IntoFunction`] + /// and direct [`DynamicFunction`] instances. + /// The given function will internally be stored as a [`DynamicFunction<'static>`] /// and mapped according to its [name]. /// - /// Because the callable must have a name, + /// Because the function must have a name, /// anonymous functions (e.g. `|a: i32, b: i32| { a + b }`) and closures must instead - /// be registered using [`register_with_name`] or manually converted to a [`DynamicCallable`] - /// and named using [`DynamicCallable::with_name`]. + /// be registered using [`register_with_name`] or manually converted to a [`DynamicFunction`] + /// and named using [`DynamicFunction::with_name`]. /// Failure to do so will result in an error being returned. /// - /// If a registered callable with the same name already exists, + /// If a registered function with the same name already exists, /// it will not be registered again and an error will be returned. - /// To register the callable anyway, overwriting any existing registration, + /// To register the function anyway, overwriting any existing registration, /// use [`overwrite_registration`] instead. /// /// # Examples @@ -57,10 +57,10 @@ impl FunctionRegistry { /// # } /// ``` /// - /// Callables cannot be registered more than once. + /// Functions cannot be registered more than once. /// /// ``` - /// # use bevy_reflect::func::{FunctionRegistrationError, FunctionRegistry, IntoCallable}; + /// # use bevy_reflect::func::{FunctionRegistrationError, FunctionRegistry, IntoFunction}; /// fn add(a: i32, b: i32) -> i32 { /// a + b /// } @@ -73,14 +73,14 @@ impl FunctionRegistry { /// /// // Note that this simply relies on the name of the function to determine uniqueness. /// // You can rename the function to register a separate instance of it. - /// let result = registry.register(add.into_callable().with_name("add2")); + /// let result = registry.register(add.into_function().with_name("add2")); /// assert!(result.is_ok()); /// ``` /// - /// Anonymous functions and closures should be registered using [`register_with_name`] or given a name using [`DynamicCallable::with_name`]. + /// Anonymous functions and closures should be registered using [`register_with_name`] or given a name using [`DynamicFunction::with_name`]. /// /// ``` - /// # use bevy_reflect::func::{FunctionRegistrationError, FunctionRegistry, IntoCallable}; + /// # use bevy_reflect::func::{FunctionRegistrationError, FunctionRegistry, IntoFunction}; /// /// let anonymous = || -> i32 { 123 }; /// @@ -92,60 +92,60 @@ impl FunctionRegistry { /// let result = registry.register_with_name("my_crate::add", |a: i32, b: i32| a + b); /// assert!(result.is_ok()); /// - /// let result = registry.register((|a: i32, b: i32| a * b).into_callable().with_name("my_crate::mul")); + /// let result = registry.register((|a: i32, b: i32| a * b).into_function().with_name("my_crate::mul")); /// assert!(result.is_ok()); /// ``` /// - /// [name]: DynamicCallable::name + /// [name]: DynamicFunction::name /// [`register_with_name`]: Self::register_with_name /// [`overwrite_registration`]: Self::overwrite_registration pub fn register( &mut self, - callable: F, + function: F, ) -> Result<&mut Self, FunctionRegistrationError> where - F: IntoCallable<'static, Marker> + 'static, + F: IntoFunction<'static, Marker> + 'static, { - let callable = callable.into_callable(); - let name = callable + let function = function.into_function(); + let name = function .name() .ok_or(FunctionRegistrationError::MissingName)? .clone(); - self.callables - .try_insert(name, callable.into_callable()) + self.functions + .try_insert(name, function.into_function()) .map_err(|err| FunctionRegistrationError::DuplicateName(err.entry.key().clone()))?; Ok(self) } - /// Attempts to register the given callable with the given name. + /// Attempts to register the given function with the given name. /// - /// This function accepts both callables that satisfy [`IntoCallable`] - /// and direct [`DynamicCallable`] instances. - /// The given callable will internally be stored as a [`DynamicCallable<'static>`] + /// This function accepts both functions that satisfy [`IntoFunction`] + /// and direct [`DynamicFunction`] instances. + /// The given function will internally be stored as a [`DynamicFunction<'static>`] /// with its [name] set to the given name. /// /// For named functions (e.g. `fn add(a: i32, b: i32) -> i32 { a + b }`) where a custom name is not needed, /// it's recommended to use [`register`] instead as the generated name is guaranteed to be unique. /// - /// If a registered callable with the same name already exists, + /// If a registered function with the same name already exists, /// it will not be registered again and an error will be returned. - /// To register the callable anyway, overwriting any existing registration, + /// To register the function anyway, overwriting any existing registration, /// use [`overwrite_registration_with_name`] instead. /// - /// To avoid conflicts, it's recommended to use a unique name for the callable. - /// This can be achieved by "namespacing" the callable with a unique identifier, + /// To avoid conflicts, it's recommended to use a unique name for the function. + /// This can be achieved by "namespacing" the function with a unique identifier, /// such as the name of your crate. /// - /// For example, to register a callable, `add`, from a crate, `my_crate`, + /// For example, to register a function, `add`, from a crate, `my_crate`, /// you could use the name, `"my_crate::add"`. /// - /// Another approach could be to use the [type name] of the callable, + /// Another approach could be to use the [type name] of the function, /// however, it should be noted that anonymous functions and closures ///are not guaranteed to have unique type names. /// - /// This method is a convenience around calling [`IntoCallable::into_callable`] and [`DynamicCallable::with_name`] - /// on the callable and inserting it into the registry using the [`register`] method. + /// This method is a convenience around calling [`IntoFunction::into_function`] and [`DynamicFunction::with_name`] + /// on the function and inserting it into the registry using the [`register`] method. /// /// # Examples /// @@ -190,88 +190,88 @@ impl FunctionRegistry { /// registry.register_with_name("my_function", two).unwrap(); /// ``` /// - /// [name]: DynamicCallable::name + /// [name]: DynamicFunction::name /// [`register`]: Self::register /// [`overwrite_registration_with_name`]: Self::overwrite_registration_with_name /// [type name]: std::any::type_name pub fn register_with_name( &mut self, name: impl Into>, - callable: F, + function: F, ) -> Result<&mut Self, FunctionRegistrationError> where - F: IntoCallable<'static, Marker> + 'static, + F: IntoFunction<'static, Marker> + 'static, { - let callable = callable.into_callable().with_name(name); - self.register(callable) + let function = function.into_function().with_name(name); + self.register(function) } - /// Registers the given callable, overwriting any existing registration. + /// Registers the given function, overwriting any existing registration. /// - /// This function accepts both callables that satisfy [`IntoCallable`] - /// and direct [`DynamicCallable`] instances. - /// The given callable will internally be stored as a [`DynamicCallable<'static>`] + /// This function accepts both functions that satisfy [`IntoFunction`] + /// and direct [`DynamicFunction`] instances. + /// The given function will internally be stored as a [`DynamicFunction<'static>`] /// and mapped according to its [name]. /// - /// Because the callable must have a name, + /// Because the function must have a name, /// anonymous functions (e.g. `|a: i32, b: i32| { a + b }`) and closures must instead - /// be registered using [`overwrite_registration_with_name`] or manually converted to a [`DynamicCallable`] - /// and named using [`DynamicCallable::with_name`]. + /// be registered using [`overwrite_registration_with_name`] or manually converted to a [`DynamicFunction`] + /// and named using [`DynamicFunction::with_name`]. /// Failure to do so will result in an error being returned. /// /// To avoid overwriting existing registrations, /// it's recommended to use the [`register`] method instead. /// - /// Returns the previous callable with the same name, if any. + /// Returns the previous function with the same name, if any. /// - /// [name]: DynamicCallable::name + /// [name]: DynamicFunction::name /// [`overwrite_registration_with_name`]: Self::overwrite_registration_with_name /// [`register`]: Self::register pub fn overwrite_registration( &mut self, function: F, - ) -> Result>, FunctionRegistrationError> + ) -> Result>, FunctionRegistrationError> where - F: IntoCallable<'static, Marker> + 'static, + F: IntoFunction<'static, Marker> + 'static, { - let function = function.into_callable(); + let function = function.into_function(); let name = function .name() .ok_or(FunctionRegistrationError::MissingName)? .clone(); - Ok(self.callables.insert(name, function)) + Ok(self.functions.insert(name, function)) } - /// Registers the given callable, overwriting any existing registration. + /// Registers the given function, overwriting any existing registration. /// - /// This function accepts both callables that satisfy [`IntoCallable`] - /// and direct [`DynamicCallable`] instances. - /// The given callable will internally be stored as a [`DynamicCallable<'static>`] + /// This function accepts both functions that satisfy [`IntoFunction`] + /// and direct [`DynamicFunction`] instances. + /// The given function will internally be stored as a [`DynamicFunction<'static>`] /// with its [name] set to the given name. /// - /// Callables are mapped according to their name. + /// Functions are mapped according to their name. /// To avoid overwriting existing registrations, /// it's recommended to use the [`register_with_name`] method instead. /// - /// This method is a convenience around calling [`IntoCallable::into_callable`] and [`DynamicCallable::with_name`] + /// This method is a convenience around calling [`IntoFunction::into_function`] and [`DynamicFunction::with_name`] /// on the function and inserting it into the registry using the [`overwrite_registration`] method. /// /// Returns the previous function with the same name, if any. /// - /// [name]: DynamicCallable::name + /// [name]: DynamicFunction::name /// [`register_with_name`]: Self::register_with_name /// [`overwrite_registration`]: Self::overwrite_registration pub fn overwrite_registration_with_name( &mut self, name: impl Into>, - callable: F, - ) -> Option> + function: F, + ) -> Option> where - F: IntoCallable<'static, Marker> + 'static, + F: IntoFunction<'static, Marker> + 'static, { - let callable = callable.into_callable().with_name(name); - match self.overwrite_registration(callable) { + let function = function.into_function().with_name(name); + match self.overwrite_registration(function) { Ok(existing) => existing, Err(FunctionRegistrationError::MissingName) => { unreachable!("the function should have a name") @@ -282,39 +282,39 @@ impl FunctionRegistry { } } - /// Get a reference to a registered callable by [name]. + /// Get a reference to a registered function by [name]. /// - /// [name]: DynamicCallable::name - pub fn get(&self, name: &str) -> Option<&DynamicCallable<'static>> { - self.callables.get(name) + /// [name]: DynamicFunction::name + pub fn get(&self, name: &str) -> Option<&DynamicFunction<'static>> { + self.functions.get(name) } - /// Returns `true` if a callable with the given [name] is registered. + /// Returns `true` if a function with the given [name] is registered. /// - /// [name]: DynamicCallable::name + /// [name]: DynamicFunction::name pub fn contains(&self, name: &str) -> bool { - self.callables.contains_key(name) + self.functions.contains_key(name) } - /// Returns an iterator over all registered callables. - pub fn iter(&self) -> impl ExactSizeIterator> { - self.callables.values() + /// Returns an iterator over all registered functions. + pub fn iter(&self) -> impl ExactSizeIterator> { + self.functions.values() } - /// Returns the number of registered callables. + /// Returns the number of registered functions. pub fn len(&self) -> usize { - self.callables.len() + self.functions.len() } - /// Returns `true` if no callables are registered. + /// Returns `true` if no functions are registered. pub fn is_empty(&self) -> bool { - self.callables.is_empty() + self.functions.is_empty() } } impl Debug for FunctionRegistry { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_set().entries(self.callables.values()).finish() + f.debug_set().entries(self.functions.values()).finish() } } @@ -341,7 +341,7 @@ impl FunctionRegistryArc { #[cfg(test)] mod tests { use super::*; - use crate::func::{ArgList, IntoCallable}; + use crate::func::{ArgList, IntoFunction}; #[test] fn should_register_function() { @@ -386,7 +386,7 @@ mod tests { 123 } - let function = foo.into_callable().with_name("custom_name"); + let function = foo.into_function().with_name("custom_name"); let mut registry = FunctionRegistry::default(); registry.register(function).unwrap(); @@ -401,7 +401,7 @@ mod tests { let value = 123; let foo = move || -> i32 { value }; - let function = foo.into_callable().with_name("custom_name"); + let function = foo.into_function().with_name("custom_name"); let mut registry = FunctionRegistry::default(); registry.register(function).unwrap(); @@ -412,7 +412,7 @@ mod tests { } #[test] - fn should_only_register_callable_once() { + fn should_only_register_function_once() { fn foo() -> i32 { 123 } @@ -425,7 +425,7 @@ mod tests { let mut registry = FunctionRegistry::default(); registry.register(foo).unwrap(); - let result = registry.register(bar.into_callable().with_name(name)); + let result = registry.register(bar.into_function().with_name(name)); assert!(matches!( result, @@ -453,7 +453,7 @@ mod tests { let mut registry = FunctionRegistry::default(); registry.register(foo).unwrap(); registry - .overwrite_registration(bar.into_callable().with_name(name)) + .overwrite_registration(bar.into_function().with_name(name)) .unwrap(); assert_eq!(registry.len(), 1); @@ -467,7 +467,7 @@ mod tests { fn should_error_on_missing_name() { let foo = || -> i32 { 123 }; - let function = foo.into_callable(); + let function = foo.into_function(); let mut registry = FunctionRegistry::default(); let result = registry.register(function); @@ -488,6 +488,6 @@ mod tests { registry.register_with_name("foo", foo).unwrap(); let debug = format!("{:?}", registry); - assert_eq!(debug, "{DynamicCallable(fn foo() -> i32)}"); + assert_eq!(debug, "{DynamicFunction(fn foo() -> i32)}"); } } diff --git a/crates/bevy_reflect/src/func/return_type.rs b/crates/bevy_reflect/src/func/return_type.rs index ffda35c2b86ef..9ad44018d93b2 100644 --- a/crates/bevy_reflect/src/func/return_type.rs +++ b/crates/bevy_reflect/src/func/return_type.rs @@ -1,18 +1,18 @@ use crate::PartialReflect; -/// The return type of a [`DynamicCallable`] or [`DynamicCallableMut`]. +/// The return type of a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// -/// [`DynamicCallable`]: crate::func::DynamicCallable -/// [`DynamicCallableMut`]: crate::func::DynamicCallableMut +/// [`DynamicFunction`]: crate::func::DynamicFunction +/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut #[derive(Debug)] pub enum Return<'a> { - /// The callable returns nothing (i.e. it returns `()`). + /// The function returns nothing (i.e. it returns `()`). Unit, - /// The callable returns an owned value. + /// The function returns an owned value. Owned(Box), - /// The callable returns a reference to a value. + /// The function returns a reference to a value. Ref(&'a dyn PartialReflect), - /// The callable returns a mutable reference to a value. + /// The function returns a mutable reference to a value. Mut(&'a mut dyn PartialReflect), } diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 9a17c9fd43aa0..fca875b70b851 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -574,7 +574,7 @@ pub mod prelude { }; #[cfg(feature = "functions")] - pub use crate::func::{IntoCallable, IntoCallableMut}; + pub use crate::func::{IntoFunction, IntoFunctionMut}; } pub use array::*; diff --git a/examples/reflection/function_reflection.rs b/examples/reflection/function_reflection.rs index 5827b5b2fb816..b004d2020ff78 100644 --- a/examples/reflection/function_reflection.rs +++ b/examples/reflection/function_reflection.rs @@ -7,8 +7,8 @@ //! processing deserialized reflection data, or even just storing type-erased versions of your functions. use bevy::reflect::func::{ - ArgList, DynamicCallable, DynamicCallableMut, FunctionError, FunctionInfo, IntoCallable, - IntoCallableMut, Return, + ArgList, DynamicFunction, DynamicFunctionMut, FunctionError, FunctionInfo, IntoFunction, + IntoFunctionMut, Return, }; use bevy::reflect::{PartialReflect, Reflect}; @@ -35,12 +35,12 @@ fn main() { // However, you'll notice that we have to know the types of the arguments and return value at compile time. // This means there's not really a way to store or call these functions dynamically at runtime. // Luckily, Bevy's reflection crate comes with a set of tools for doing just that! - // We do this by first converting our function into the reflection-based `DynamicCallable` type - // using the `IntoCallable` trait. - let function: DynamicCallable<'static> = dbg!(add.into_callable()); + // We do this by first converting our function into the reflection-based `DynamicFunction` type + // using the `IntoFunction` trait. + let function: DynamicFunction<'static> = dbg!(add.into_function()); - // This time, you'll notice that `DynamicCallable` doesn't take any information about the function's arguments or return value. - // This is because `DynamicCallable` checks the types of the arguments and return value at runtime. + // This time, you'll notice that `DynamicFunction` doesn't take any information about the function's arguments or return value. + // This is because `DynamicFunction` checks the types of the arguments and return value at runtime. // Now we can generate a list of arguments: let args: ArgList = dbg!(ArgList::new().push_owned(2_i32).push_owned(2_i32)); @@ -56,33 +56,34 @@ fn main() { assert_eq!(value.try_take::().unwrap(), 4); // The same can also be done for closures that capture references to their environment. - // Closures that capture their environment immutably can be converted into a `DynamicCallable` - // using the `IntoCallable` trait. + // Closures that capture their environment immutably can be converted into a `DynamicFunction` + // using the `IntoFunction` trait. let minimum = 5; let clamp = |value: i32| value.max(minimum); - let function: DynamicCallable = dbg!(clamp.into_callable()); + let function: DynamicFunction = dbg!(clamp.into_function()); let args = dbg!(ArgList::new().push_owned(2_i32)); let return_value = dbg!(function.call(args).unwrap()); let value: Box = return_value.unwrap_owned(); assert_eq!(value.try_take::().unwrap(), 5); // We can also handle closures that capture their environment mutably - // using the `IntoCallableMut` trait. + // using the `IntoFunctionMut` trait. let mut count = 0; let increment = |amount: i32| count += amount; - let closure: DynamicCallableMut = dbg!(increment.into_callable_mut()); + let closure: DynamicFunctionMut = dbg!(increment.into_function_mut()); let args = dbg!(ArgList::new().push_owned(5_i32)); - // Because `DynamicCallableMut` mutably borrows `total`, + + // Because `DynamicFunctionMut` mutably borrows `total`, // it will need to be dropped before `total` can be accessed again. - // This can be done manually with `drop(closure)` or by using the `DynamicCallableMut::call_once` method. + // This can be done manually with `drop(closure)` or by using the `DynamicFunctionMut::call_once` method. dbg!(closure.call_once(args).unwrap()); assert_eq!(count, 5); // As stated before, this works for many kinds of simple functions. // Functions with non-reflectable arguments or return values may not be able to be converted. - // Generic functions are also not supported (unless manually monomorphized like `foo::.into_callable()`). + // Generic functions are also not supported (unless manually monomorphized like `foo::.into_function()`). // Additionally, the lifetime of the return value is tied to the lifetime of the first argument. // However, this means that many methods (i.e. functions with a `self` parameter) are also supported: #[derive(Reflect, Default)] @@ -104,20 +105,20 @@ fn main() { let mut data = Data::default(); - let set_value = dbg!(Data::set_value.into_callable()); + let set_value = dbg!(Data::set_value.into_function()); let args = dbg!(ArgList::new().push_mut(&mut data)).push_owned(String::from("Hello, world!")); dbg!(set_value.call(args).unwrap()); assert_eq!(data.value, "Hello, world!"); - let get_value = dbg!(Data::get_value.into_callable()); + let get_value = dbg!(Data::get_value.into_function()); let args = dbg!(ArgList::new().push_ref(&data)); let return_value = dbg!(get_value.call(args).unwrap()); let value: &dyn PartialReflect = return_value.unwrap_ref(); assert_eq!(value.try_downcast_ref::().unwrap(), "Hello, world!"); - // Lastly, for more complex use cases, you can always create a custom `DynamicCallable` manually. - // This is useful for functions that can't be converted via the `IntoCallable` trait. - // For example, this function doesn't implement `IntoCallable` due to the fact that + // Lastly, for more complex use cases, you can always create a custom `DynamicFunction` manually. + // This is useful for functions that can't be converted via the `IntoFunction` trait. + // For example, this function doesn't implement `IntoFunction` due to the fact that // the lifetime of the return value is not tied to the lifetime of the first argument. fn get_or_insert(value: i32, container: &mut Option) -> &i32 { if container.is_none() { @@ -127,7 +128,7 @@ fn main() { container.as_ref().unwrap() } - let get_or_insert_function = dbg!(DynamicCallable::new( + let get_or_insert_function = dbg!(DynamicFunction::new( |mut args| { // We can optionally add a check to ensure we were given the correct number of arguments. if args.len() != 2 { From 333e66cd3a17643c5d91ab8b835948046fc01c1a Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 18 Aug 2024 22:11:11 -0700 Subject: [PATCH 7/8] Rename modules --- .../{dynamic_callable.rs => dynamic_function.rs} | 0 ...c_callable_mut.rs => dynamic_function_mut.rs} | 0 .../func/{into_callable.rs => into_function.rs} | 0 ...into_callable_mut.rs => into_function_mut.rs} | 0 crates/bevy_reflect/src/func/mod.rs | 16 ++++++++-------- 5 files changed, 8 insertions(+), 8 deletions(-) rename crates/bevy_reflect/src/func/{dynamic_callable.rs => dynamic_function.rs} (100%) rename crates/bevy_reflect/src/func/{dynamic_callable_mut.rs => dynamic_function_mut.rs} (100%) rename crates/bevy_reflect/src/func/{into_callable.rs => into_function.rs} (100%) rename crates/bevy_reflect/src/func/{into_callable_mut.rs => into_function_mut.rs} (100%) diff --git a/crates/bevy_reflect/src/func/dynamic_callable.rs b/crates/bevy_reflect/src/func/dynamic_function.rs similarity index 100% rename from crates/bevy_reflect/src/func/dynamic_callable.rs rename to crates/bevy_reflect/src/func/dynamic_function.rs diff --git a/crates/bevy_reflect/src/func/dynamic_callable_mut.rs b/crates/bevy_reflect/src/func/dynamic_function_mut.rs similarity index 100% rename from crates/bevy_reflect/src/func/dynamic_callable_mut.rs rename to crates/bevy_reflect/src/func/dynamic_function_mut.rs diff --git a/crates/bevy_reflect/src/func/into_callable.rs b/crates/bevy_reflect/src/func/into_function.rs similarity index 100% rename from crates/bevy_reflect/src/func/into_callable.rs rename to crates/bevy_reflect/src/func/into_function.rs diff --git a/crates/bevy_reflect/src/func/into_callable_mut.rs b/crates/bevy_reflect/src/func/into_function_mut.rs similarity index 100% rename from crates/bevy_reflect/src/func/into_callable_mut.rs rename to crates/bevy_reflect/src/func/into_function_mut.rs diff --git a/crates/bevy_reflect/src/func/mod.rs b/crates/bevy_reflect/src/func/mod.rs index 45a9a1a316c26..a924231ff4cab 100644 --- a/crates/bevy_reflect/src/func/mod.rs +++ b/crates/bevy_reflect/src/func/mod.rs @@ -100,24 +100,24 @@ //! [coherence issues]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#coherence-leak-check pub use args::{ArgError, ArgList, ArgValue}; -pub use dynamic_callable::*; -pub use dynamic_callable_mut::*; +pub use dynamic_function::*; +pub use dynamic_function_mut::*; pub use error::*; pub use info::*; -pub use into_callable::*; -pub use into_callable_mut::*; +pub use into_function::*; +pub use into_function_mut::*; pub use reflect_fn::*; pub use reflect_fn_mut::*; pub use registry::*; pub use return_type::*; pub mod args; -mod dynamic_callable; -mod dynamic_callable_mut; +mod dynamic_function; +mod dynamic_function_mut; mod error; mod info; -mod into_callable; -mod into_callable_mut; +mod into_function; +mod into_function_mut; pub(crate) mod macros; mod reflect_fn; mod reflect_fn_mut; From 8def158e82073b4332c8241d87d697915f3fdf07 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Mon, 19 Aug 2024 08:49:05 -0700 Subject: [PATCH 8/8] Rename compile test directory --- .../tests/{into_callable => into_function}/arguments_fail.rs | 0 .../tests/{into_callable => into_function}/closure_fail.rs | 0 .../tests/{into_callable => into_function}/return_fail.rs | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename crates/bevy_reflect/compile_fail/tests/{into_callable => into_function}/arguments_fail.rs (100%) rename crates/bevy_reflect/compile_fail/tests/{into_callable => into_function}/closure_fail.rs (100%) rename crates/bevy_reflect/compile_fail/tests/{into_callable => into_function}/return_fail.rs (100%) diff --git a/crates/bevy_reflect/compile_fail/tests/into_callable/arguments_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_function/arguments_fail.rs similarity index 100% rename from crates/bevy_reflect/compile_fail/tests/into_callable/arguments_fail.rs rename to crates/bevy_reflect/compile_fail/tests/into_function/arguments_fail.rs diff --git a/crates/bevy_reflect/compile_fail/tests/into_callable/closure_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_function/closure_fail.rs similarity index 100% rename from crates/bevy_reflect/compile_fail/tests/into_callable/closure_fail.rs rename to crates/bevy_reflect/compile_fail/tests/into_function/closure_fail.rs diff --git a/crates/bevy_reflect/compile_fail/tests/into_callable/return_fail.rs b/crates/bevy_reflect/compile_fail/tests/into_function/return_fail.rs similarity index 100% rename from crates/bevy_reflect/compile_fail/tests/into_callable/return_fail.rs rename to crates/bevy_reflect/compile_fail/tests/into_function/return_fail.rs