-
-
Notifications
You must be signed in to change notification settings - Fork 198
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
Require AsObjectArg
pass-by-ref, consistent with AsArg
#947
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Bromeon
added
quality-of-life
No new functionality, but improves ergonomics/internals
c: core
Core components
labels
Nov 9, 2024
API docs are being generated and will be shortly available at: https://godot-rust.github.io/docs/gdext/pr-947 |
The idea is to require pass-by-ref for objects, in order to discourage accidental/unnecessary cloning. This is also consistent with AsArg by-refs, in particular `impl AsArg<Gd<T>>` when used in arrays and packed arrays. The downside is that it needs an extra `&` in some places, and one can no longer use pass-by-value to "consume" objects, ending their lifetime with the call. What is also unclear is whether there are situations where we can benefit from moving "into" the engine (perf-wise). So this may need some more discussion. One option is also to move toward using Copy for manually managed Gd<T> types, which would mean a) those could be passed by-value, and b) we would anyway lose the "consume" semantics. This is a more conservative choice for now, with minor syntactic drawbacks, but in line with AsArg<T> and the potential to expand in the future.
`&mut obj` args can only be passed once, since &mut T: !Copy. This means that passing it to a Godot API works once, and then causes moved-out errors. This comes with a few issues: * It either needs the `&*` pattern or not, depending on the order of calls. Reordering breaks them. * It's inconsistent with `AsArg`, which is only implemented for `&T` in case of by-ref builtins. * Consuming `&mut T` should probably be allowed iff consuming `T` is allowed. That said, we'll need to check the ergonomic impact and see how arguments are being passed in practice.
Bromeon
force-pushed
the
qol/objects-by-ref
branch
2 times, most recently
from
November 9, 2024 19:28
e724f5c
to
e8f72ff
Compare
It's relatively common that Godot APIs return `Option<Gd<T>>` or pass this type in virtual functions. To avoid excessive `as_ref()` calls, we **could** directly support `&Option<Gd>` in addition to `Option<&Gd>`. However, this is currently not done as it hides nullability, especially in situations where a return type is directly propagated: api(create_obj().as_ref()) api(&create_obj()) While the first is slightly longer, it looks different from a function create_obj() that returns Gd<T> and thus can never be null. It's also quite idiomatic to use as_ref() for inner-option transforms in Rust. For now, the code is still added but inactive.
Bromeon
force-pushed
the
qol/objects-by-ref
branch
from
November 9, 2024 19:35
e8f72ff
to
1110e37
Compare
Bromeon
added
feature
Adds functionality to the library
and removed
quality-of-life
No new functionality, but improves ergonomics/internals
labels
Nov 10, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
A more conservative approach for initial v0.2, but more consistent with
AsArg
by-ref semantics and with the potential to expand in the future. Also cuts down on the number of monomorphizations without losing functionality.After this PR, you can pass object arguments as follows:
Gd
&Gd
&arg
&Gd
&Gd
arg
&mut Gd
&Gd
&*arg
Option<Gd>
Option<&Gd>
arg.as_ref()
Option<&Gd>
Option<&Gd>
arg
Option<&mut Gd>
Option<&Gd>
arg.as_deref()
Gd::null_arg()
We'll need to check the ergonomic impact and see how arguments are typically being passed in practice.
Below more detailed rationale on individual
impl
s.Remove
impl AsObjectArg<T>
forGd<T>
valuesPossibly controversial, but the idea is to require pass-by-value for objects, in order to discourage accidental/unnecessary cloning. This is also consistent with AsArg by-refs, in particular
impl AsArg<Gd<T>>
when used in arrays and packed arrays.The downside is that it needs an extra
&
in some places, and one can no longer use pass-by-value to "consume" objects, ending their lifetime with the call. What is also unclear is whether there are situations where we can benefit from moving "into" the engine (perf-wise). So this may need some more discussion.One option is also to move toward using
Copy
for manually managedGd<T>
types, which would mean a) those could be passed by-value, and b) we would anyway lose the "consume" semantics.Remove
impl AsObjectArg<T>
for&mut Gd<T>
references&mut obj
args can only be passed once, since&mut T: !Copy
. This means that passing it to a Godot API works once,and then causes moved-out errors. This comes with a few issues:
&*
pattern or not, depending on the order of calls. Reordering breaks them.AsArg
, which is only implemented for&T
in case of by-ref builtins.&mut T
should probably be allowed iff consumingT
is allowed.Note about
impl AsObjectArg<T>
for&Option<Gd<T>>
(outer reference)It's relatively common that Godot APIs return
Option<Gd<T>>
or pass this type in virtual functions. To avoid excessiveas_ref()
calls, we could directly support&Option<Gd>
in addition toOption<&Gd>
. However, this is currently not done as it hides nullability, especially in situations where a return type is directly propagated:While the first is slightly longer, it looks different from a function
create_obj()
that returnsGd<T>
and thus can never be null. In some scenarios, it's better to immediately ensure non-null (e.g. throughunwrap()
) instead of propagating nulls.