-
-
Notifications
You must be signed in to change notification settings - Fork 197
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
impl GodotFfi
for Option<T>
when T
is pointer sized and nullable #240
#247
Conversation
if you wanna talk a bit about design for this, feel free to check out the discord thread for this issue. i've been experimenting with a couple of things there. if this just works then that'd be great, but i didn't really think this would work as an implementation. |
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.
i dont think doing
let nil_ptr = ptr::null_mut();
interface_fn!(variant_new_nil)(nil_ptr);
is correct, since you're telling godot to initialize a new object into a null-pointer. im a bit surprised it works.
also is there a reason you can't just pass around null-pointers directly in this code? does that break something?
also could you change the title to reflect what the PR actually does.
Unfortunately, I don't use Discord, so this thread is completely in accessible to me. The initial changes did indeed not really work for |
right, that is what i initially assumed. I'll have a closer look at everything later but to summarize a bit from the discord thread: the basic issue is rust orphan rules. as you might have noticed, it's not possible to blanket implement unsafe impl<T: GodotClass> GodotFfi for Option<Gd<T>> {} so how do we work around this? your idea does work, but it means we now have a bunch of not really useful types. but if it doesn't break anything then it's not the worst honestly. though I'd need more time to be sure that there's no UB. if we want to only implement it for first, use some kind of newtype representing a nullable Gd. im not sure how possible this is, as i never tested it, and it might require users to use that nullable Gd type. which isn't ideal. second, create a new trait something like impl<T: NullableGodotFfi> GodotFfi for Option<T> now we implement both thirdly, we could move |
Why not just a simple marker trait? trait NullableGodotFfi: GodotFfi {} and we constraint the impl of impl<T: NullableGodotFfi> GodotFfi for Option<T> { ... } |
that probably works yeah! if you make it unsafe and add the safety requirement that anything that implements the trait is nullable and pointer-sized then we should be good to use your implementation (maybe with a couple of tweaks still). since we can then rely on the guarantee that anything that implements that trait is pointer sized. maybe a different name would be more appropriate too. since it declares that the type is both nullable and pointer-sized in godot. though from what you're saying it sounds like every type that is nullable is pointer-sized. but i feel like it'd still be good for the name to reflect that. if it turns out there are more nullable types, or godot adds other nullable types, then we can tweak the trait slightly. |
a couple of things. could you change the name of this PR to reflect what the PR actually does, rather than the issue it fixes? (such as "implements |
Option<Gd<T>>
does not implement ToVariant
#240GodotFfi
for Option<T>
when T
is pointer sized and nullable #240
For completeness’s sake and to document my findings: the current Godot 4.0 source indicates that only |
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.
This looks good! Only a couple of minor things.
I'm not sure about the name GodotNullablePtrSized
but i also am not entirely sure what would be a better name than that.
I'm very interested in seeing if the memory checked builds in the CI will be happy with this.
bors try
fn mirror_option_node(&self, value: Option<Gd<Node>>) -> Option<Gd<Node>> { | ||
value | ||
} | ||
} |
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.
it looks like it should be possible to add these tests to the build.rs
so they get auto-generated, can you do that if it is? dont worry about it if it would require rewriting the macro or something tho.
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.
The test generation does currently not play very well with Option
. We need different tests for both Some(...)
and None
but the tests derive their name from the rust type. That makes it impossible to have tests for the same type with different values.
The accept
methods are also implemented slightly different from what the code generation does because they operate on and check Options
. I thought it's easier to just implement the tests manually, than to expand the complexity of the macros.
tryBuild succeeded! The publicly hosted instance of bors-ng is deprecated and will go away soon. If you want to self-host your own instance, instructions are here. If you want to switch to GitHub's built-in merge queue, visit their help page. |
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.
Thanks a lot for this addition! 🙂
@lilizoey already mentioned a lot, I agree with their comments.
Regarding GodotNullablePtrSized
:
- It's not obvious at first sight why
GodotFfi
wasn't implemented directly onOption<Gd<T>>
. Could you document that it exists primarily because of the orphan rule, that is, becauseGodotFfi
andGd
live in separate crates? The existing general doc about the nullable pointer counterpart in Godot is great too, but you could add that there's currently just one concrete implementor:Option<Gd<T>>
. - Maybe name it simply
GodotNullablePtr
? TheSized
makes people think of Rust'sSized
marker.
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.
Thanks for the update! Could you also fix the merge conflicts? 🙂
API docs are being generated and will be shortly available at: https://godot-rust.github.io/docs/gdext/pr-247 |
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.
Seems basically good to me at least!
At the moment we can't merge because there are upstream breaking changes in |
bors try |
bors p=8 |
tryBuild failed: |
…t-rust#240 Additionally FromVariant and ToVariant are also implemented for Option<Gd<T>> to satisfy all the requirements for ffi and godot_api.
Thanks for the quick update and the patience! 🚀 bors r+ |
Build succeeded! The publicly hosted instance of bors-ng is deprecated and will go away soon. If you want to self-host your own instance, instructions are here. If you want to switch to GitHub's built-in merge queue, visit their help page. |
ToVariant
andFromVariant
are implemented forOption<Gd<T>>
as well as they are a requirement of#[godot_api]
.Closes #240.