1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
//! Reflection-based dynamic functions.
//!
//! 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 [`IntoFunction`] and [`IntoFunctionMut`] traits, respectively.
//!
//! Once this dynamic representation is created, it can be called with a set of arguments provided
//! via an [`ArgList`].
//!
//! This returns a [`FunctionResult`] containing the [`Return`] value,
//! which can be used to extract a [`PartialReflect`] trait object.
//!
//! # Example
//!
//! ```
//! # use bevy_reflect::PartialReflect;
//! # use bevy_reflect::func::args::ArgList;
//! # use bevy_reflect::func::{DynamicFunction, FunctionResult, IntoFunction, Return};
//! fn add(a: i32, b: i32) -> i32 {
//! a + b
//! }
//!
//! let mut func: DynamicFunction = add.into_function();
//! let args: ArgList = ArgList::default()
//! // Pushing a known type with owned ownership
//! .with_owned(25_i32)
//! // Pushing a reflected type with owned ownership
//! .with_boxed(Box::new(75_i32) as Box<dyn PartialReflect>);
//! let result: FunctionResult = func.call(args);
//! let value: Return = result.unwrap();
//! assert_eq!(value.unwrap_owned().try_downcast_ref::<i32>(), Some(&100));
//! ```
//!
//! # Types of Functions
//!
//! 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, which are referred to as _named_ functions.
//! But there are also _anonymous_ functions, which are unnamed and defined with anonymous function syntax.
//!
//! ```rust
//! // This is a named function:
//! fn add(a: i32, b: i32) -> i32 {
//! a + b
//! }
//!
//! // This is an anonymous function:
//! let add = |a: i32, b: i32| a + b;
//! ```
//!
//! Closures, on the other hand, are special functions that do capture their environment.
//! These are always defined with anonymous function syntax.
//!
//! ```
//! // A closure that captures an immutable reference to a variable
//! let c = 123;
//! let add = |a: i32, b: i32| a + b + c;
//!
//! // A closure that captures a mutable reference to a variable
//! let mut total = 0;
//! let add = |a: i32, b: i32| total += a + b;
//!
//! // A closure that takes ownership of its captured variables by moving them
//! let c = 123;
//! let add = move |a: i32, b: i32| a + b + c;
//! ```
//!
//! # Valid Signatures
//!
//! Many of the traits in this module have default blanket implementations over a specific set of function signatures.
//!
//! These signatures are:
//! - `(...) -> R`
//! - `for<'a> (&'a arg, ...) -> &'a R`
//! - `for<'a> (&'a mut arg, ...) -> &'a R`
//! - `for<'a> (&'a mut arg, ...) -> &'a mut R`
//!
//! Where `...` represents 0 to 15 arguments (inclusive) of the form `T`, `&T`, or `&mut T`.
//! The lifetime of any reference to the return type `R`, must be tied to a "receiver" argument
//! (i.e. the first argument in the signature, normally `self`).
//!
//! Each trait will also have its own requirements for what traits are required for both arguments and return types,
//! but a good rule-of-thumb is that all types should derive [`Reflect`].
//!
//! The reason for such a small subset of valid signatures is due to limitations in Rust—
//! 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 [`DynamicFunctionMut`] can instead be created manually.
//!
//! # Generic Functions
//!
//! In Rust, generic functions are [monomorphized] by the compiler,
//! which means that a separate copy of the function is generated for each concrete set of type parameters.
//!
//! When converting a generic function to a [`DynamicFunction`] or [`DynamicFunctionMut`],
//! the function must be manually monomorphized with concrete types.
//! In other words, you cannot write `add<T>.into_function()`.
//! Instead, you will need to write `add::<i32>.into_function()`.
//!
//! This means that reflected functions cannot be generic themselves.
//! To get around this limitation, you can consider [overloading] your function with multiple concrete types.
//!
//! # Overloading Functions
//!
//! Both [`DynamicFunction`] and [`DynamicFunctionMut`] support [function overloading].
//!
//! Function overloading allows one function to handle multiple types of arguments.
//! This is useful for simulating generic functions by having an overload for each known concrete type.
//! Additionally, it can also simulate [variadic functions]: functions that can be called with a variable number of arguments.
//!
//! Internally, this works by storing multiple functions in a map,
//! where each function is associated with a specific argument signature.
//!
//! To learn more, see the docs on [`DynamicFunction::with_overload`].
//!
//! # Function Registration
//!
//! This module also provides a [`FunctionRegistry`] that can be used to register functions and closures
//! by name so that they may be retrieved and called dynamically.
//!
//! ```
//! # use bevy_reflect::func::{ArgList, FunctionRegistry};
//! fn add(a: i32, b: i32) -> i32 {
//! a + b
//! }
//!
//! let mut registry = FunctionRegistry::default();
//!
//! // You can register functions and methods by their `core::any::type_name`:
//! registry.register(add).unwrap();
//!
//! // Or you can register them by a custom name:
//! registry.register_with_name("mul", |a: i32, b: i32| a * b).unwrap();
//!
//! // You can then retrieve and call these functions by name:
//! let reflect_add = registry.get(core::any::type_name_of_val(&add)).unwrap();
//! let value = reflect_add.call(ArgList::default().with_owned(10_i32).with_owned(5_i32)).unwrap();
//! assert_eq!(value.unwrap_owned().try_downcast_ref::<i32>(), Some(&15));
//!
//! let reflect_mul = registry.get("mul").unwrap();
//! let value = reflect_mul.call(ArgList::default().with_owned(10_i32).with_owned(5_i32)).unwrap();
//! assert_eq!(value.unwrap_owned().try_downcast_ref::<i32>(), Some(&50));
//! ```
//!
//! [`PartialReflect`]: crate::PartialReflect
//! [`Reflect`]: crate::Reflect
//! [lack of variadic generics]: https://poignardazur.github.io/2024/05/25/report-on-rustnl-variadics/
//! [coherence issues]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#coherence-leak-check
//! [monomorphized]: https://en.wikipedia.org/wiki/Monomorphization
//! [overloading]: #overloading-functions
//! [function overloading]: https://en.wikipedia.org/wiki/Function_overloading
//! [variadic functions]: https://en.wikipedia.org/wiki/Variadic_function
pub use ;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub