Skip to content

Commit 07f8d2e

Browse files
committed
Remove ToVariant, FromVariant, and VariantMetadata impls for pointers
This commit splits SignatureTuple into two separate traits: PtrcallSignatureTuple and VarcallSignatureTuple. The latter is a child of the former. PtrcallSignatureTuple is used for ptrcall and only demands GodotFuncMarshall of its arguments. VarcallSignatureTuple is used for varcall and additionally demands ToVariant, FromVariant, and VariantMetadata of its arguments, so pointers cannot benefit from the optimizations provided by varcall over ptrcall.
1 parent 4107ee6 commit 07f8d2e

File tree

5 files changed

+55
-92
lines changed

5 files changed

+55
-92
lines changed

godot-codegen/src/util.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,11 @@ fn to_rust_type_uncached(ty: &str, ctx: &mut Context) -> RustTy {
306306
if is_const {
307307
ty = ty.replace("const ", "");
308308
}
309+
// .trim() is necessary here, as the Godot extension API
310+
// places a space between a type and its stars if it's a
311+
// double pointer. That is, Godot writes "int*" but, if it's a
312+
// double pointer, then it writes "int **" instead (with a
313+
// space in the middle).
309314
let inner_type = to_rust_type(ty.trim(), ctx);
310315
return RustTy::RawPointer {
311316
inner: Box::new(inner_type),

godot-core/src/builtin/meta/signature.rs

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ use godot_ffi::VariantType;
99
use std::fmt::Debug;
1010

1111
#[doc(hidden)]
12-
pub trait SignatureTuple {
13-
type Params;
14-
type Ret;
15-
12+
pub trait VarcallSignatureTuple: PtrcallSignatureTuple {
1613
fn variant_type(index: i32) -> VariantType;
1714
fn property_info(index: i32, param_name: &str) -> PropertyInfo;
1815
fn param_metadata(index: i32) -> sys::GDExtensionClassMethodArgumentMetadata;
@@ -25,6 +22,12 @@ pub trait SignatureTuple {
2522
func: fn(sys::GDExtensionClassInstancePtr, Self::Params) -> Self::Ret,
2623
method_name: &str,
2724
);
25+
}
26+
27+
#[doc(hidden)]
28+
pub trait PtrcallSignatureTuple {
29+
type Params;
30+
type Ret;
2831

2932
// Note: this method imposes extra bounds on GodotFfi, which may not be implemented for user types.
3033
// We could fall back to varcalls in such cases, and not require GodotFfi categorically.
@@ -58,19 +61,16 @@ use crate::builtin::meta::*;
5861
use crate::builtin::{FromVariant, ToVariant, Variant};
5962
use crate::obj::GodotClass;
6063

61-
macro_rules! impl_signature_for_tuple {
64+
macro_rules! impl_varcall_signature_for_tuple {
6265
(
6366
$R:ident
6467
$(, $Pn:ident : $n:literal)*
6568
) => {
6669
#[allow(unused_variables)]
67-
impl<$R, $($Pn,)*> SignatureTuple for ($R, $($Pn,)*)
70+
impl<$R, $($Pn,)*> VarcallSignatureTuple for ($R, $($Pn,)*)
6871
where $R: VariantMetadata + ToVariant + sys::GodotFuncMarshal + Debug,
6972
$( $Pn: VariantMetadata + FromVariant + sys::GodotFuncMarshal + Debug, )*
7073
{
71-
type Params = ($($Pn,)*);
72-
type Ret = $R;
73-
7474
#[inline]
7575
fn variant_type(index: i32) -> sys::VariantType {
7676
match index {
@@ -122,8 +122,23 @@ macro_rules! impl_signature_for_tuple {
122122

123123
varcall_return::<$R>(func(instance_ptr, args), ret, err)
124124
}
125+
}
126+
};
127+
}
128+
129+
macro_rules! impl_ptrcall_signature_for_tuple {
130+
(
131+
$R:ident
132+
$(, $Pn:ident : $n:literal)*
133+
) => {
134+
#[allow(unused_variables)]
135+
impl<$R, $($Pn,)*> PtrcallSignatureTuple for ($R, $($Pn,)*)
136+
where $R: sys::GodotFuncMarshal + Debug,
137+
$( $Pn: sys::GodotFuncMarshal + Debug, )*
138+
{
139+
type Params = ($($Pn,)*);
140+
type Ret = $R;
125141

126-
#[inline]
127142
unsafe fn ptrcall<C : GodotClass>(
128143
instance_ptr: sys::GDExtensionClassInstancePtr,
129144
args_ptr: *const sys::GDExtensionConstTypePtr,
@@ -219,14 +234,25 @@ fn return_error<R>(method_name: &str, arg: &impl Debug) -> ! {
219234
panic!("{method_name}: return type {return_ty} is unable to store value {arg:?}",);
220235
}
221236

222-
impl_signature_for_tuple!(R);
223-
impl_signature_for_tuple!(R, P0: 0);
224-
impl_signature_for_tuple!(R, P0: 0, P1: 1);
225-
impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2);
226-
impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3);
227-
impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4);
228-
impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5);
229-
impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6);
230-
impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7);
231-
impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7, P8: 8);
232-
impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7, P8: 8, P9: 9);
237+
impl_varcall_signature_for_tuple!(R);
238+
impl_ptrcall_signature_for_tuple!(R);
239+
impl_varcall_signature_for_tuple!(R, P0: 0);
240+
impl_ptrcall_signature_for_tuple!(R, P0: 0);
241+
impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1);
242+
impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1);
243+
impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2);
244+
impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2);
245+
impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3);
246+
impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3);
247+
impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4);
248+
impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4);
249+
impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5);
250+
impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5);
251+
impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6);
252+
impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6);
253+
impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7);
254+
impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7);
255+
impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7, P8: 8);
256+
impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7, P8: 8);
257+
impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7, P8: 8, P9: 9);
258+
impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7, P8: 8, P9: 9);

godot-core/src/builtin/variant/impls.rs

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -263,71 +263,3 @@ impl<T: EngineEnum> VariantMetadata for T {
263263
sys::GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT32
264264
}
265265
}
266-
267-
impl<T> ToVariant for *mut T {
268-
fn to_variant(&self) -> Variant {
269-
(*self as i64).to_variant()
270-
}
271-
}
272-
273-
impl<T> ToVariant for *const T {
274-
fn to_variant(&self) -> Variant {
275-
(*self as i64).to_variant()
276-
}
277-
}
278-
279-
impl<T> FromVariant for *mut T {
280-
fn try_from_variant(variant: &Variant) -> Result<Self, VariantConversionError> {
281-
let n = i64::try_from_variant(variant)?;
282-
Ok(n as Self)
283-
}
284-
}
285-
286-
impl<T> FromVariant for *const T {
287-
fn try_from_variant(variant: &Variant) -> Result<Self, VariantConversionError> {
288-
let n = i64::try_from_variant(variant)?;
289-
Ok(n as Self)
290-
}
291-
}
292-
293-
impl<T> VariantMetadata for *mut T {
294-
fn variant_type() -> VariantType {
295-
VariantType::Int
296-
}
297-
298-
fn property_info(property_name: &str) -> PropertyInfo {
299-
PropertyInfo {
300-
variant_type: Self::variant_type(),
301-
class_name: Self::class_name(),
302-
property_name: StringName::from(property_name),
303-
hint: global::PropertyHint::PROPERTY_HINT_INT_IS_POINTER,
304-
hint_string: GodotString::from("pointer"),
305-
usage: global::PropertyUsageFlags::PROPERTY_USAGE_DEFAULT,
306-
}
307-
}
308-
309-
fn param_metadata() -> sys::GDExtensionClassMethodArgumentMetadata {
310-
sys::GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64
311-
}
312-
}
313-
314-
impl<T> VariantMetadata for *const T {
315-
fn variant_type() -> VariantType {
316-
VariantType::Int
317-
}
318-
319-
fn property_info(property_name: &str) -> PropertyInfo {
320-
PropertyInfo {
321-
variant_type: Self::variant_type(),
322-
class_name: Self::class_name(),
323-
property_name: StringName::from(property_name),
324-
hint: global::PropertyHint::PROPERTY_HINT_INT_IS_POINTER,
325-
hint_string: GodotString::from("pointer"),
326-
usage: global::PropertyUsageFlags::PROPERTY_USAGE_DEFAULT,
327-
}
328-
}
329-
330-
fn param_metadata() -> sys::GDExtensionClassMethodArgumentMetadata {
331-
sys::GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64
332-
}
333-
}

godot-core/src/macros.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ macro_rules! gdext_call_signature_method {
6262
$method_name:ident,
6363
$ptrcall_type:path
6464
) => {
65-
<Sig as $crate::builtin::meta::SignatureTuple>::ptrcall::<$Class>(
65+
<Sig as $crate::builtin::meta::PtrcallSignatureTuple>::ptrcall::<$Class>(
6666
$instance_ptr,
6767
$args,
6868
$ret,
@@ -79,7 +79,7 @@ macro_rules! gdext_call_signature_method {
7979
$func:expr,
8080
$method_name:ident
8181
) => {
82-
<Sig as $crate::builtin::meta::SignatureTuple>::varcall::<$Class>(
82+
<Sig as $crate::builtin::meta::VarcallSignatureTuple>::varcall::<$Class>(
8383
$instance_ptr,
8484
$args,
8585
$ret,

itest/rust/src/native_structures_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl TextServerExtensionVirtual for TestTextServer {
7070
}
7171

7272
#[itest]
73-
fn test_native_structures() {
73+
fn test_native_structures_codegen() {
7474
// Test construction of a few simple types.
7575
let _ = AudioFrame {
7676
left: 0.0,

0 commit comments

Comments
 (0)