Skip to content

Commit 2fac024

Browse files
committed
Wire up with GodotNullableFfi
1 parent acef27c commit 2fac024

File tree

10 files changed

+84
-68
lines changed

10 files changed

+84
-68
lines changed

godot-codegen/src/generator/native_structures.rs

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -83,59 +83,59 @@ fn make_native_structure(
8383

8484
// mod re_export needed, because class should not appear inside the file module, and we can't re-export private struct as pub
8585
let tokens = quote! {
86-
#imports
87-
use std::ffi::c_void; // for opaque object pointer fields
88-
use crate::meta::{GodotConvert, FromGodot, ToGodot};
89-
90-
/// Native structure; can be passed via pointer in APIs that are not exposed to GDScript.
91-
///
92-
#[doc = #doc]
93-
#[derive(Clone, PartialEq, Debug)]
94-
#[repr(C)]
95-
pub struct #class_name {
96-
#fields
97-
}
98-
99-
impl #class_name {
100-
#methods
101-
}
102-
103-
impl GodotConvert for *mut #class_name {
104-
type Via = i64;
105-
}
106-
107-
impl ToGodot for *mut #class_name {
108-
type ToVia<'v> = i64;
109-
110-
fn to_godot(&self) -> Self::ToVia<'_> {
111-
*self as i64
112-
}
113-
}
114-
115-
impl FromGodot for *mut #class_name {
116-
fn try_from_godot(via: Self::Via) -> Result<Self, crate::meta::error::ConvertError> {
117-
Ok(via as Self)
118-
}
119-
}
120-
121-
impl GodotConvert for *const #class_name {
122-
type Via = i64;
123-
}
124-
125-
impl ToGodot for *const #class_name {
126-
type ToVia<'v> = i64;
127-
128-
fn to_godot(&self) -> Self::ToVia<'_> {
129-
*self as i64
130-
}
131-
}
132-
133-
impl FromGodot for *const #class_name {
134-
fn try_from_godot(via: Self::Via) -> Result<Self, crate::meta::error::ConvertError> {
135-
Ok(via as Self)
136-
}
137-
}
138-
};
86+
#imports
87+
use std::ffi::c_void; // for opaque object pointer fields
88+
use crate::meta::{GodotConvert, FromGodot, ToGodot};
89+
90+
/// Native structure; can be passed via pointer in APIs that are not exposed to GDScript.
91+
///
92+
#[doc = #doc]
93+
#[derive(Clone, PartialEq, Debug)]
94+
#[repr(C)]
95+
pub struct #class_name {
96+
#fields
97+
}
98+
99+
impl #class_name {
100+
#methods
101+
}
102+
103+
impl GodotConvert for *mut #class_name {
104+
type Via = i64;
105+
}
106+
107+
impl ToGodot for *mut #class_name {
108+
type ToVia<'v> = i64;
109+
110+
fn to_godot(&self) -> Self::ToVia<'_> {
111+
*self as i64
112+
}
113+
}
114+
115+
impl FromGodot for *mut #class_name {
116+
fn try_from_godot(via: Self::Via) -> Result<Self, crate::meta::error::ConvertError> {
117+
Ok(via as Self)
118+
}
119+
}
120+
121+
impl GodotConvert for *const #class_name {
122+
type Via = i64;
123+
}
124+
125+
impl ToGodot for *const #class_name {
126+
type ToVia<'v> = i64;
127+
128+
fn to_godot(&self) -> Self::ToVia<'_> {
129+
*self as i64
130+
}
131+
}
132+
133+
impl FromGodot for *const #class_name {
134+
fn try_from_godot(via: Self::Via) -> Result<Self, crate::meta::error::ConvertError> {
135+
Ok(via as Self)
136+
}
137+
}
138+
};
139139
// note: TypePtr -> ObjectPtr conversion OK?
140140

141141
builtins::GeneratedBuiltin { code: tokens }

godot-core/src/builtin/collections/array.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* License, v. 2.0. If a copy of the MPL was not distributed with this
55
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
66
*/
7-
7+
use std::borrow::Borrow;
88
use std::fmt;
99
use std::marker::PhantomData;
1010

@@ -258,26 +258,31 @@ impl<T: ArrayElement> Array<T> {
258258

259259
/// Sets the value at the specified index.
260260
///
261+
/// `value` uses `Borrow<T>` to accept either by value or by reference.
262+
///
261263
/// # Panics
262264
///
263265
/// If `index` is out of bounds.
264-
pub fn set(&mut self, index: usize, value: &T) {
266+
pub fn set(&mut self, index: usize, value: impl Borrow<T>) {
265267
let ptr_mut = self.ptr_mut(index);
266268

269+
let variant = value.borrow().to_variant();
270+
267271
// SAFETY: `ptr_mut` just checked that the index is not out of bounds.
268-
unsafe {
269-
value.to_variant().move_into_var_ptr(ptr_mut);
270-
}
272+
unsafe { variant.move_into_var_ptr(ptr_mut) };
271273
}
272274

273275
/// Appends an element to the end of the array.
274276
///
277+
/// `value` uses `Borrow<T>` to accept either by value or by reference.
278+
///
275279
/// _Godot equivalents: `append` and `push_back`_
276280
#[doc(alias = "append")]
277281
#[doc(alias = "push_back")]
278-
pub fn push(&mut self, value: &T) {
282+
pub fn push(&mut self, value: impl Borrow<T>) {
279283
// SAFETY: The array has type `T` and we're writing a value of type `T` to it.
280-
unsafe { self.as_inner_mut() }.push_back(&value.to_variant());
284+
let mut inner = unsafe { self.as_inner_mut() };
285+
inner.push_back(&value.borrow().to_variant());
281286
}
282287

283288
/// Adds an element at the beginning of the array, in O(n).

godot-core/src/meta/godot_convert/impls.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ where
9191
impl<T: ToGodot> ToGodot for Option<T>
9292
where
9393
Option<T::Via>: GodotType,
94+
for<'f> T::ToVia<'f>: GodotType<Ffi: GodotNullableFfi>,
9495
{
9596
type ToVia<'v> = Option<T::ToVia<'v>>
97+
// type ToVia<'v> = Self::Via
9698
where Self: 'v;
9799

98100
fn to_godot(&self) -> Self::ToVia<'_> {

godot-core/src/meta/godot_convert/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub trait GodotConvert {
4040
///
4141
/// Please read the [`godot::meta` module docs][crate::meta] for further information about conversions.
4242
pub trait ToGodot: Sized + GodotConvert {
43-
type ToVia<'v>
43+
type ToVia<'v>: GodotType
4444
where
4545
Self: 'v;
4646

godot-core/src/meta/ref_arg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl<'r, T> ToGodot for RefArg<'r, T>
2929
where
3030
T: ToGodot,
3131
{
32-
type ToVia<'v> = Self::Via
32+
type ToVia<'v> = T::ToVia<'v>
3333
where Self: 'v;
3434

3535
fn to_godot(&self) -> Self::ToVia<'_> {

godot-core/src/meta/traits.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ pub trait GodotFfiVariant: Sized + GodotFfi {
3838
// type. For instance [`i32`] does not implement `GodotFfi` because it cannot represent all values of
3939
// Godot's `int` type, however it does implement `GodotType` because we can set the metadata of values with
4040
// this type to indicate that they are 32 bits large.
41-
pub trait GodotType:
42-
GodotConvert<Via = Self> + ToGodot + FromGodot + sealed::Sealed + 'static
41+
pub trait GodotType: GodotConvert<Via = Self> + sealed::Sealed + Sized + 'static
4342
// 'static is not technically required, but it simplifies a few things (limits e.g. ObjectArg).
4443
{
4544
#[doc(hidden)]
@@ -145,7 +144,7 @@ pub trait GodotType:
145144
message = "`Array<T>` can only store element types supported in Godot arrays (no nesting).",
146145
label = "has invalid element type"
147146
)]
148-
pub trait ArrayElement: GodotType + sealed::Sealed {
147+
pub trait ArrayElement: GodotType + ToGodot + FromGodot + sealed::Sealed {
149148
/// Returns the representation of this type as a type string.
150149
///
151150
/// Used for elements in arrays (the latter despite `ArrayElement` not having a direct relation).

godot-macros/src/derive/derive_to_godot.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ fn make_togodot_for_newtype_struct(name: &Ident, field: &NewtypeStruct) -> Token
4242

4343
quote! {
4444
impl ::godot::meta::ToGodot for #name {
45+
// For now by-value, may change.
46+
type ToVia<'v> = #via_type;
47+
4548
fn to_godot(&self) -> #via_type {
4649
::godot::meta::ToGodot::to_godot(&self.#field_name)
4750
}
@@ -67,6 +70,8 @@ fn make_togodot_for_int_enum(
6770

6871
quote! {
6972
impl ::godot::meta::ToGodot for #name {
73+
type ToVia<'v> = #int;
74+
7075
#[allow(unused_parens)] // Error "unnecessary parentheses around block return value"; comes from ord expressions like (1 + 2).
7176
fn to_godot(&self) -> #int {
7277
match self {
@@ -86,6 +91,8 @@ fn make_togodot_for_string_enum(name: &Ident, enum_: &CStyleEnum) -> TokenStream
8691

8792
quote! {
8893
impl ::godot::meta::ToGodot for #name {
94+
type ToVia<'v> = ::godot::builtin::GString;
95+
8996
fn to_godot(&self) -> ::godot::builtin::GString {
9097
match self {
9198
#(

itest/rust/build.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,10 @@ macro_rules! push_newtype {
8686
}
8787

8888
impl godot::meta::ToGodot for $name {
89+
type ToVia<'v> = $T;
90+
8991
#[allow(clippy::clone_on_copy)]
90-
fn to_godot(&self) -> Self::ToVia<'_>
91-
{
92+
fn to_godot(&self) -> Self::ToVia<'_> {
9293
self.0.clone()
9394
}
9495
}

itest/rust/src/builtin_tests/containers/array_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ fn array_from_packed_array() {
5353
// This tests that the resulting array doesn't secretly have a runtime type assigned to it,
5454
// which is not reflected in our static type. It would make sense if it did, but Godot decided
5555
// otherwise: we get an untyped array.
56-
array.push(GString::from("hi").to_variant());
56+
array.push(&GString::from("hi").to_variant());
5757
assert_eq!(array, varray![42, "hi"]);
5858
}
5959

itest/rust/src/builtin_tests/convert_test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ impl GodotConvert for ConvertedStruct {
106106
}
107107

108108
impl ToGodot for ConvertedStruct {
109+
type ToVia<'v> = Dictionary;
110+
109111
fn to_godot(&self) -> Self::ToVia<'_> {
110112
dict! {
111113
"a": self.a,

0 commit comments

Comments
 (0)