-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bevy_reflect: Improve DynamicFunction
ergonomics
#14201
bevy_reflect: Improve DynamicFunction
ergonomics
#14201
Conversation
c1d31be
to
aa00b83
Compare
Clippy's not happy with my choice of naming in Should we rename? If so, to what? So far on Discord, we've come up with the following alternatives:
Keep in mind that we also need We might also want to consider whether we want to keep |
I just went with |
f991f3d
to
f2bb3ef
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much improved API; fantastic PR writeup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor docs stuff. Looks like this makes the whole IntoFunction
process more straightforward and understandable, which I'm happy about :)
6b7ef4e
to
90a17de
Compare
Includes removing a need for ArgInfo when reifying args
We no longer rely on FunctionInfo to validate functions and instead just parse things directly It's still a good idea to give functions proper FunctionInfo, but it's no longer strictly required for things to work
This was done purely for aesthetics
90a17de
to
e707cff
Compare
Objective
Many functions can be converted to
DynamicFunction
usingIntoFunction
. Unfortunately, we are limited by Rust itself and the implementations are far from exhaustive. For example, we can't convert functions with more than 16 arguments. Additionally, we can't handle returns with lifetimes not tied to the lifetime of the first argument.In such cases, users will have to create their
DynamicFunction
manually.Let's take the following function:
This function cannot be converted to a
DynamicFunction
viaIntoFunction
due to the lifetime of the return value being tied to the second argument. Therefore, we need to construct theDynamicFunction
manually:While still a small and straightforward snippet, there's a decent amount going on here. There's a lot of room for improvements when it comes to ergonomics and readability.
The goal of this PR is to address those issues.
Solution
Improve the ergonomics and readability of manually created
DynamicFunction
s.Some of the major changes:
&ArgInfo
when reifying arguments (i.e. the&info.args()[1]
calls)pop
methods onArgList
to handle both popping and castingtake
methods onArgList
for taking the arguments out in order&FunctionInfo
in the internal closure (Change 1 made it no longer necessary)ArgInfo
andReturnInfo
With all these changes in place, we get something a lot nicer to both write and look at:
Alternatively, to rely on type inference for taking arguments, you could do:
Testing
You can test locally by running:
Changelog
&ArgInfo
argument fromFromArg::from_arg
trait method&ArgInfo
argument fromArg::take_***
methodsArgValue
Arg
is now a struct containing anArgValue
and an argumentindex
Arg::take_***
methods now requireT
is alsoTypePath
Arg::new
,Arg::index
,Arg::value
,Arg::take_value
, andArg::take
methodsArgId
inArgError
with just the argumentindex
ArgError::EmptyArgList
ArgList::push
toArgList::push_arg
ArgList::pop_arg
,ArgList::pop_owned
,ArgList::pop_ref
, andArgList::pop_mut
ArgList::take_arg
,ArgList::take_owned
,ArgList::take_ref
,ArgList::take_mut
, andArgList::take
ArgList::pop
is now genericFunctionError::InvalidArgCount
toFunctionError::ArgCountMismatch
DynamicFunction::new
no longer has a&FunctionInfo
argumentFunctionInfo::with_arg
FunctionInfo::with_return
Internal Migration Guide
Important
Function reflection was introduced as part of the 0.15 dev cycle. This migration guide was written for developers relying on
main
during this cycle, and is not a breaking change coming from 0.14.FromArg::from_arg
trait method and theArg::take_***
methods no longer take a&ArgInfo
argument.Arg
is nowArgValue
.Arg
is now a struct which contains anArgValue
.Arg::take_***
methods now requireT
is alsoTypePath
id: ArgId
inArgError
have been replaced withindex: usize
ArgList::push
is nowArgList::push_arg
. It also takes the newArgValue
type.ArgList::pop
has becomeArgList::pop_arg
and now returnsArgValue
.Arg::pop
now takes a generic type and downcasts to that type. It's recommended to useArgList::take
and friends instead since they allow removing the arguments from the list in the order they were pushed (rather than reverse order).FunctionError::InvalidArgCount
is nowFunctionError::ArgCountMismatch
DynamicFunction::new
no longer has a&FunctionInfo
argument. This argument can be removed.