diff --git a/godot-codegen/src/util.rs b/godot-codegen/src/util.rs index 02b05b535..becb17b06 100644 --- a/godot-codegen/src/util.rs +++ b/godot-codegen/src/util.rs @@ -306,6 +306,11 @@ fn to_rust_type_uncached(ty: &str, ctx: &mut Context) -> RustTy { if is_const { ty = ty.replace("const ", ""); } + // .trim() is necessary here, as the Godot extension API + // places a space between a type and its stars if it's a + // double pointer. That is, Godot writes "int*" but, if it's a + // double pointer, then it writes "int **" instead (with a + // space in the middle). let inner_type = to_rust_type(ty.trim(), ctx); return RustTy::RawPointer { inner: Box::new(inner_type), diff --git a/godot-core/src/builtin/meta/signature.rs b/godot-core/src/builtin/meta/signature.rs index c759ed639..f4cedef32 100644 --- a/godot-core/src/builtin/meta/signature.rs +++ b/godot-core/src/builtin/meta/signature.rs @@ -9,10 +9,7 @@ use godot_ffi::VariantType; use std::fmt::Debug; #[doc(hidden)] -pub trait SignatureTuple { - type Params; - type Ret; - +pub trait VarcallSignatureTuple: PtrcallSignatureTuple { fn variant_type(index: i32) -> VariantType; fn property_info(index: i32, param_name: &str) -> PropertyInfo; fn param_metadata(index: i32) -> sys::GDExtensionClassMethodArgumentMetadata; @@ -25,6 +22,12 @@ pub trait SignatureTuple { func: fn(sys::GDExtensionClassInstancePtr, Self::Params) -> Self::Ret, method_name: &str, ); +} + +#[doc(hidden)] +pub trait PtrcallSignatureTuple { + type Params; + type Ret; // Note: this method imposes extra bounds on GodotFfi, which may not be implemented for user types. // We could fall back to varcalls in such cases, and not require GodotFfi categorically. @@ -58,19 +61,16 @@ use crate::builtin::meta::*; use crate::builtin::{FromVariant, ToVariant, Variant}; use crate::obj::GodotClass; -macro_rules! impl_signature_for_tuple { +macro_rules! impl_varcall_signature_for_tuple { ( $R:ident $(, $Pn:ident : $n:literal)* ) => { #[allow(unused_variables)] - impl<$R, $($Pn,)*> SignatureTuple for ($R, $($Pn,)*) + impl<$R, $($Pn,)*> VarcallSignatureTuple for ($R, $($Pn,)*) where $R: VariantMetadata + ToVariant + sys::GodotFuncMarshal + Debug, $( $Pn: VariantMetadata + FromVariant + sys::GodotFuncMarshal + Debug, )* { - type Params = ($($Pn,)*); - type Ret = $R; - #[inline] fn variant_type(index: i32) -> sys::VariantType { match index { @@ -122,8 +122,23 @@ macro_rules! impl_signature_for_tuple { varcall_return::<$R>(func(instance_ptr, args), ret, err) } + } + }; +} + +macro_rules! impl_ptrcall_signature_for_tuple { + ( + $R:ident + $(, $Pn:ident : $n:literal)* + ) => { + #[allow(unused_variables)] + impl<$R, $($Pn,)*> PtrcallSignatureTuple for ($R, $($Pn,)*) + where $R: sys::GodotFuncMarshal + Debug, + $( $Pn: sys::GodotFuncMarshal + Debug, )* + { + type Params = ($($Pn,)*); + type Ret = $R; - #[inline] unsafe fn ptrcall( instance_ptr: sys::GDExtensionClassInstancePtr, args_ptr: *const sys::GDExtensionConstTypePtr, @@ -219,14 +234,25 @@ fn return_error(method_name: &str, arg: &impl Debug) -> ! { panic!("{method_name}: return type {return_ty} is unable to store value {arg:?}",); } -impl_signature_for_tuple!(R); -impl_signature_for_tuple!(R, P0: 0); -impl_signature_for_tuple!(R, P0: 0, P1: 1); -impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2); -impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3); -impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4); -impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5); -impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6); -impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7); -impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7, P8: 8); -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); +impl_varcall_signature_for_tuple!(R); +impl_ptrcall_signature_for_tuple!(R); +impl_varcall_signature_for_tuple!(R, P0: 0); +impl_ptrcall_signature_for_tuple!(R, P0: 0); +impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1); +impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1); +impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2); +impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2); +impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3); +impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3); +impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4); +impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4); +impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5); +impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5); +impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6); +impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6); +impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7); +impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7); +impl_varcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7, P8: 8); +impl_ptrcall_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7, P8: 8); +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); +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); diff --git a/godot-core/src/builtin/variant/impls.rs b/godot-core/src/builtin/variant/impls.rs index 4442a3811..76ba245c8 100644 --- a/godot-core/src/builtin/variant/impls.rs +++ b/godot-core/src/builtin/variant/impls.rs @@ -263,71 +263,3 @@ impl VariantMetadata for T { sys::GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT32 } } - -impl ToVariant for *mut T { - fn to_variant(&self) -> Variant { - (*self as i64).to_variant() - } -} - -impl ToVariant for *const T { - fn to_variant(&self) -> Variant { - (*self as i64).to_variant() - } -} - -impl FromVariant for *mut T { - fn try_from_variant(variant: &Variant) -> Result { - let n = i64::try_from_variant(variant)?; - Ok(n as Self) - } -} - -impl FromVariant for *const T { - fn try_from_variant(variant: &Variant) -> Result { - let n = i64::try_from_variant(variant)?; - Ok(n as Self) - } -} - -impl VariantMetadata for *mut T { - fn variant_type() -> VariantType { - VariantType::Int - } - - fn property_info(property_name: &str) -> PropertyInfo { - PropertyInfo { - variant_type: Self::variant_type(), - class_name: Self::class_name(), - property_name: StringName::from(property_name), - hint: global::PropertyHint::PROPERTY_HINT_INT_IS_POINTER, - hint_string: GodotString::from("pointer"), - usage: global::PropertyUsageFlags::PROPERTY_USAGE_DEFAULT, - } - } - - fn param_metadata() -> sys::GDExtensionClassMethodArgumentMetadata { - sys::GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64 - } -} - -impl VariantMetadata for *const T { - fn variant_type() -> VariantType { - VariantType::Int - } - - fn property_info(property_name: &str) -> PropertyInfo { - PropertyInfo { - variant_type: Self::variant_type(), - class_name: Self::class_name(), - property_name: StringName::from(property_name), - hint: global::PropertyHint::PROPERTY_HINT_INT_IS_POINTER, - hint_string: GodotString::from("pointer"), - usage: global::PropertyUsageFlags::PROPERTY_USAGE_DEFAULT, - } - } - - fn param_metadata() -> sys::GDExtensionClassMethodArgumentMetadata { - sys::GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64 - } -} diff --git a/godot-core/src/macros.rs b/godot-core/src/macros.rs index 184cbcf4e..f316e193c 100644 --- a/godot-core/src/macros.rs +++ b/godot-core/src/macros.rs @@ -62,7 +62,7 @@ macro_rules! gdext_call_signature_method { $method_name:ident, $ptrcall_type:path ) => { - ::ptrcall::<$Class>( + ::ptrcall::<$Class>( $instance_ptr, $args, $ret, @@ -79,7 +79,7 @@ macro_rules! gdext_call_signature_method { $func:expr, $method_name:ident ) => { - ::varcall::<$Class>( + ::varcall::<$Class>( $instance_ptr, $args, $ret, diff --git a/itest/rust/src/native_structures_test.rs b/itest/rust/src/native_structures_test.rs index c3b0f180e..e66fb0c5f 100644 --- a/itest/rust/src/native_structures_test.rs +++ b/itest/rust/src/native_structures_test.rs @@ -70,7 +70,7 @@ impl TextServerExtensionVirtual for TestTextServer { } #[itest] -fn test_native_structures() { +fn test_native_structures_codegen() { // Test construction of a few simple types. let _ = AudioFrame { left: 0.0,