Skip to content
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

Implement ToGodot/FromGodot for Vec<T> #263

Closed
astrale-sharp opened this issue May 8, 2023 · 14 comments · Fixed by #795
Closed

Implement ToGodot/FromGodot for Vec<T> #263

astrale-sharp opened this issue May 8, 2023 · 14 comments · Fixed by #795
Labels
c: register Register classes, functions and other symbols to GDScript feature Adds functionality to the library

Comments

@astrale-sharp
Copy link
Contributor

astrale-sharp commented May 8, 2023

For option Maybe returning T::to_variant() if option is some else Variant::nil()
for Result dict!("Ok" : T::to_variant() )
for Vec, returning a variant array

@Mercerenies
Copy link
Contributor

Option is being worked on (at least for Option<Gd<T>>) at #240, by the way. I'm not aware of any work being done for vectors or results.

@astrale-sharp
Copy link
Contributor Author

I'd be interested to contribute if no one is on the case yet !

@lilizoey
Copy link
Member

lilizoey commented May 8, 2023

Vec<T> definitely has a pretty obvious implementation, alongside other obvious collections. In fact we already have a From impl to convert Array<T> into Vec<T>, though not the reverse which is weird, but i guess you can just do .iter().collect().

Result i'm a bit more unsure about. i think we should base Result on #246 when that's merged, rather than make a separate implementation.

Option will be handled by #247 as mentioned, and it makes more sense to give it a separate implementation since it's used to represent nullable values.

@lilizoey lilizoey added quality-of-life No new functionality, but improves ergonomics/internals c: register Register classes, functions and other symbols to GDScript labels May 8, 2023
@Bromeon Bromeon added feature Adds functionality to the library and removed quality-of-life No new functionality, but improves ergonomics/internals labels May 8, 2023
@Bromeon
Copy link
Member

Bromeon commented May 8, 2023

What would the semantics for Result<T, E> be?
Would any Err(...) enumerator always map to Variant::nil()?

Also, what's the motivation behind it? Might be more explicit to use Result::ok() if that's desired 🤔

@Bromeon
Copy link
Member

Bromeon commented Jun 13, 2023

@astrale-sharp any comments? 🙂

@astrale-sharp
Copy link
Contributor Author

Would any Err(...) enumerator always map to Variant::nil()?

I don't understand what you mean there.

If V and E in Result<V,E> are both ToGodot I don't see what's lost in making the Result ToGodot as well, it can make handling Errors on the gdscript side a little more convenient.

Actually I don't really care about Result but Option and Vec are definitly something I came across making my game

@lilizoey lilizoey changed the title Feature : implement ToVariant for Vec<T>, Result<T>, Option<T> where T : ToVariant Feature : implement ToGodot for Vec<T>, Result<T>, Option<T> where T : ToGodot Oct 27, 2023
@lilizoey
Copy link
Member

Note: ToVariant has now been renamed/re-purposed into ToGodot

@lilizoey
Copy link
Member

Suggestion:
Assume here that T: GodotConvert/ToGodot/FromGodot as appropriate.

GodotConvert:

  • Option<T>, with Via = Variant (unless other more specific implementation exists, such as for Option<Gd<T>>)
  • Vec<T>, with Via = Array<T::Via>
  • Result<T, ConvertError>, with Via = T::Via (see Make FromGodot conversions fallible #467)

ToGodot:

  • Option<T> maps None => Variant::nil(), Some(x) => x.to_variant()
  • Vec<T> does effectively vec.iter().collect()
  • Result<T,E> is either not implemented, or we just panic for Err. In the future we may support using Result as a return type, where Err prints an error to Godot or something like that.

FromGodot:

  • Option<T> map null => None and value => T::from_godot(value)
  • Vec<T> does effectively arr.iter_shared().collect()
  • Result<T, ConvertError> does Ok(T::try_from_godot(value)) (see Make FromGodot conversions fallible #467)

We then have:

  • Option always maps to a nullable variant, except when the type itself is nullable.
  • Vec is Array as most people would expect
  • Result can be used to detect errors when a function is called

Additionally we should implement Property and maybe Export for at least Option<T>, unless this causes godot to behave weirdly (such as the editor displaying weird values if you attempt to set it to the wrong value). We may consider only implementing it for Option<Variant> if that's the case.

@Bromeon
Copy link
Member

Bromeon commented Oct 28, 2023

Sounds good, thanks for listing it up.

I'm not sure about Option<Variant> though -- you would have two possible null states: None and Some(Variant::nil()).
It might be a necessity if we have an Option<T> blanket impl though...

@lilizoey
Copy link
Member

lilizoey commented Oct 28, 2023

Sounds good, thanks for listing it up.

I'm not sure about Option<Variant> though -- you would have two possible null states: None and Some(Variant::nil()). It might be a necessity if we have an Option<T> blanket impl though...

i think we'd probably implement it for each different option of Via. Since there's only a limited number of possible Via types. so we can choose to leave out Variant if we want. (kinda necessary if we want Option<Gd<T>> to be different)

@StatisMike
Copy link
Contributor

Lately, I've made a wrapper for Vec<Gd<T>> where T: Inherits<Resource> for my crate: https://github.com/StatisMike/gd-props/blob/master/gd-props-defs/src/types.rs#L88.

It implements GodotConvert + ToGodot + FromGodot, with Array<Gd<T>> as its Godot representation.
Also, it implements Property and Export, though with Property its Intermediate needed to be different: VariantArray.

It's because there were problems with extending the vector in the editor - otherwise, there will be a need to either create default Gd<T> and extend the Vec on inputting another element, or make the Rust representation Vec<Option<Gd<T>>>, making it much more verbose than current roundtrip from Array<Gd<T>> to `Vec<Gd>``

I think I could whip up a more universal wrapper for gdext - I think that besides GodotConvert + ToGodot + FromGodot the Property and Export should be also implemented for it to be able to expose it on the Godot side and make it exportable.

@Bromeon
Copy link
Member

Bromeon commented Dec 26, 2023

To be clear, Property/Export should be considered separately from ToGodot/FromGodot.

The former should not be implemented for things like Vec<T> because they come with costly conversions every time a property is read or written on Godot side. This is not clear from simply declaring a field in a struct. We thus only implement these traits for native Godot types.

Returning/accepting values in #[func] on the other hand already implies by-value semantics, so it's less surprising. ToGodot/FromGodot can be supported for different Rust types as indicated in the title. I don't see why there should be a special case for Resource though.

@StatisMike
Copy link
Contributor

StatisMike commented Jan 5, 2024

@Bromeon The special case for Gd<Resource> was only valid in the linked crate: it is for handling resources, so it was intended as serialization wrapper for subresource collections.

Though you are right, if any wrapper should be constructed at all, it should be done other way around.

@Bromeon
Copy link
Member

Bromeon commented Aug 11, 2024

I'm changing the scope of this issue to Vec<T>.

Regarding the other types mentioned in the original title:

  • Option<T> is not generally applicable since GDScript doesn't have nullability, so something like Option<i32> makes no sense. The types that can represent null states are Variant and Option<Gd<T>>, which are already supported.
    • Auto-downgrading Option<T> to use Variant on the FFI comes at a loss of type safety and performance; as such I'd prefer if this were explicit for now.
  • Result<T, E> is discussed separately in #425.

@Bromeon Bromeon changed the title Feature : implement ToGodot for Vec<T>, Result<T>, Option<T> where T : ToGodot Implement ToGodot/FromGodot for Vec<T> Aug 11, 2024
@Bromeon Bromeon linked a pull request Aug 11, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: register Register classes, functions and other symbols to GDScript feature Adds functionality to the library
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants