Skip to content

Commit

Permalink
bevy_reflect: Add FunctionRegistry::call (#15148)
Browse files Browse the repository at this point in the history
# Objective

There may be times where a function in the `FunctionRegistry` doesn't
need to be fully retrieved. A user may just need to call it with a set
of arguments.

We should provide a shortcut for doing this.

## Solution

Add the `FunctionRegistry::call` method to directly call a function in
the registry with the given name and arguments.

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect --all-features
```
  • Loading branch information
MrGVSV authored Sep 20, 2024
1 parent 5484d2d commit ebb57c5
Showing 1 changed file with 32 additions and 1 deletion.
33 changes: 32 additions & 1 deletion crates/bevy_reflect/src/func/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use std::sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard};

use bevy_utils::HashMap;

use crate::func::{DynamicFunction, FunctionRegistrationError, IntoFunction};
use crate::func::{
ArgList, DynamicFunction, FunctionRegistrationError, FunctionResult, IntoFunction,
};

/// A registry of [reflected functions].
///
Expand Down Expand Up @@ -282,6 +284,18 @@ impl FunctionRegistry {
}
}

/// Calls the function with the given [name] and [args].
///
/// Returns `None` if no function with the given name is registered.
/// Otherwise, returns the result of the function call.
///
/// [name]: DynamicFunction::name
/// [args]: ArgList
pub fn call<'a>(&self, name: &str, args: ArgList<'a>) -> Option<FunctionResult<'a>> {
let func = self.get(name)?;
Some(func.call(args))
}

/// Get a reference to a registered function by [name].
///
/// [name]: DynamicFunction::name
Expand Down Expand Up @@ -463,6 +477,23 @@ mod tests {
assert_eq!(value.try_downcast_ref::<i32>(), Some(&321));
}

#[test]
fn should_call_function_via_registry() {
fn add(a: i32, b: i32) -> i32 {
a + b
}

let mut registry = FunctionRegistry::default();
registry.register(add).unwrap();

let args = ArgList::new().push_owned(25_i32).push_owned(75_i32);
let result = registry
.call(std::any::type_name_of_val(&add), args)
.unwrap();
let value = result.unwrap().unwrap_owned();
assert_eq!(value.try_downcast_ref::<i32>(), Some(&100));
}

#[test]
fn should_error_on_missing_name() {
let foo = || -> i32 { 123 };
Expand Down

0 comments on commit ebb57c5

Please sign in to comment.