-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
bevy_reflect: Improve DynamicFunction ergonomics
#14201
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
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
alice-i-cecile
left a comment
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.
mweatherley
left a comment
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
DynamicFunctionusingIntoFunction. 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
DynamicFunctionmanually.Let's take the following function:
This function cannot be converted to a
DynamicFunctionviaIntoFunctiondue to the lifetime of the return value being tied to the second argument. Therefore, we need to construct theDynamicFunctionmanually: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
DynamicFunctions.Some of the major changes:
&ArgInfowhen reifying arguments (i.e. the&info.args()[1]calls)popmethods onArgListto handle both popping and castingtakemethods onArgListfor taking the arguments out in order&FunctionInfoin the internal closure (Change 1 made it no longer necessary)ArgInfoandReturnInfoWith 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
&ArgInfoargument fromFromArg::from_argtrait method&ArgInfoargument fromArg::take_***methodsArgValueArgis now a struct containing anArgValueand an argumentindexArg::take_***methods now requireTis alsoTypePathArg::new,Arg::index,Arg::value,Arg::take_value, andArg::takemethodsArgIdinArgErrorwith just the argumentindexArgError::EmptyArgListArgList::pushtoArgList::push_argArgList::pop_arg,ArgList::pop_owned,ArgList::pop_ref, andArgList::pop_mutArgList::take_arg,ArgList::take_owned,ArgList::take_ref,ArgList::take_mut, andArgList::takeArgList::popis now genericFunctionError::InvalidArgCounttoFunctionError::ArgCountMismatchDynamicFunction::newno longer has a&FunctionInfoargumentFunctionInfo::with_argFunctionInfo::with_returnInternal Migration Guide
Important
Function reflection was introduced as part of the 0.15 dev cycle. This migration guide was written for developers relying on
mainduring this cycle, and is not a breaking change coming from 0.14.FromArg::from_argtrait method and theArg::take_***methods no longer take a&ArgInfoargument.Argis nowArgValue.Argis now a struct which contains anArgValue.Arg::take_***methods now requireTis alsoTypePathid: ArgIdinArgErrorhave been replaced withindex: usizeArgList::pushis nowArgList::push_arg. It also takes the newArgValuetype.ArgList::pophas becomeArgList::pop_argand now returnsArgValue.Arg::popnow takes a generic type and downcasts to that type. It's recommended to useArgList::takeand friends instead since they allow removing the arguments from the list in the order they were pushed (rather than reverse order).FunctionError::InvalidArgCountis nowFunctionError::ArgCountMismatchDynamicFunction::newno longer has a&FunctionInfoargument. This argument can be removed.