Skip to content

Experiment with splitting up signature differently #1042

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

Merged
merged 1 commit into from
Apr 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions godot-codegen/src/generator/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ fn make_builtin_method_definition(
let ptrcall_invocation = quote! {
let method_bind = sys::builtin_method_table().#fptr_access;

<CallSig as PtrcallSignatureTuple>::out_builtin_ptrcall(

Signature::<CallParams, CallRet>::out_builtin_ptrcall(
method_bind,
#builtin_name_str,
#method_name_str,
Expand All @@ -265,7 +266,7 @@ fn make_builtin_method_definition(
let varcall_invocation = quote! {
let method_bind = sys::builtin_method_table().#fptr_access;

<CallSig as VarcallSignatureTuple>::out_builtin_ptrcall_varargs(
Signature::<CallParams, CallRet>::out_builtin_ptrcall_varargs(
method_bind,
#builtin_name_str,
#method_name_str,
Expand Down
4 changes: 2 additions & 2 deletions godot-codegen/src/generator/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ fn make_class_method_definition(
let ptrcall_invocation = quote! {
let method_bind = sys::#get_method_table().#fptr_access;

<CallSig as PtrcallSignatureTuple>::out_class_ptrcall(
Signature::<CallParams, CallRet>::out_class_ptrcall(
method_bind,
#rust_class_name,
#rust_method_name,
Expand All @@ -528,7 +528,7 @@ fn make_class_method_definition(
let varcall_invocation = quote! {
let method_bind = sys::#get_method_table().#fptr_access;

<CallSig as VarcallSignatureTuple>::out_class_varcall(
Signature::<CallParams, CallRet>::out_class_varcall(
method_bind,
#rust_class_name,
#rust_method_name,
Expand Down
4 changes: 2 additions & 2 deletions godot-codegen/src/generator/functions_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,9 @@ pub fn make_function_definition(
let call_sig_decl = {
let return_ty = &sig.return_value().type_tokens();

// Build <'a0, 'a1, ...> for lifetimes.
quote! {
type CallSig #callsig_lifetime_args = ( #return_ty, #(#param_types),* );
type CallRet = #return_ty;
type CallParams #callsig_lifetime_args = (#(#param_types,)*);
}
};

Expand Down
4 changes: 2 additions & 2 deletions godot-codegen/src/generator/utility_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub(crate) fn make_utility_function_definition(function: &UtilityFunction) -> To
let ptrcall_invocation = quote! {
let utility_fn = sys::utility_function_table().#function_ident;

<CallSig as PtrcallSignatureTuple>::out_utility_ptrcall(
Signature::<CallParams, CallRet>::out_utility_ptrcall(
utility_fn,
#function_name_str,
args
Expand All @@ -56,7 +56,7 @@ pub(crate) fn make_utility_function_definition(function: &UtilityFunction) -> To
let varcall_invocation = quote! {
let utility_fn = sys::utility_function_table().#function_ident;

<CallSig as VarcallSignatureTuple>::out_utility_ptrcall_varargs(
Signature::<CallParams, CallRet>::out_utility_ptrcall_varargs(
utility_fn,
#function_name_str,
args,
Expand Down
2 changes: 1 addition & 1 deletion godot-codegen/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn make_imports() -> TokenStream {
quote! {
use godot_ffi as sys;
use crate::builtin::*;
use crate::meta::{AsArg, AsObjectArg, ClassName, CowArg, ObjectArg, ObjectCow, PtrcallSignatureTuple, RefArg, VarcallSignatureTuple};
use crate::meta::{AsArg, AsObjectArg, ClassName, CowArg, InParamTuple, ObjectArg, ObjectCow, OutParamTuple, ParamTuple, RefArg, Signature};
use crate::classes::native::*;
use crate::classes::Object;
use crate::obj::Gd;
Expand Down
13 changes: 0 additions & 13 deletions godot-core/src/meta/godot_convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,6 @@ pub trait FromGodot: Sized + GodotConvert {
}
}

pub(crate) fn into_ffi_variant<T: ToGodot>(value: &T) -> Variant {
let via = value.to_godot();
let ffi = via.to_ffi();
GodotFfiVariant::ffi_to_variant(&ffi)
}

pub(crate) fn try_from_ffi<T: FromGodot>(
ffi: <T::Via as GodotType>::Ffi,
) -> Result<T, ConvertError> {
let via = <T::Via as GodotType>::try_from_ffi(ffi)?;
T::try_from_godot(via)
}

#[macro_export]
macro_rules! impl_godot_as_self {
($T:ty) => {
Expand Down
4 changes: 2 additions & 2 deletions godot-core/src/meta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ mod array_type_info;
mod class_name;
mod godot_convert;
mod method_info;
mod param_tuple;
mod property_info;
mod signature;
mod traits;
Expand All @@ -61,8 +62,7 @@ pub use class_name::ClassName;
pub use godot_convert::{FromGodot, GodotConvert, ToGodot};
pub use traits::{ArrayElement, GodotType, PackedArrayElement};

#[cfg(since_api = "4.2")]
pub use crate::registry::signal::variadic::ParamTuple;
pub use param_tuple::{InParamTuple, OutParamTuple, ParamTuple};

pub(crate) use array_type_info::ArrayTypeInfo;
pub(crate) use traits::{
Expand Down
93 changes: 93 additions & 0 deletions godot-core/src/meta/param_tuple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright (c) godot-rust; Bromeon and contributors.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

use crate::builtin::Variant;

use super::{CallContext, CallResult, PropertyInfo};
use godot_ffi as sys;

mod impls;

/// Represents a parameter list as Rust tuple where each tuple element is one parameter.
///
/// This trait only contains metadata for the parameter list, the actual functionality is contained in [`InParamTuple`] and
/// [`OutParamTuple`].
pub trait ParamTuple: Sized {
/// The number of elements in this parameter list.
const LEN: usize;

/// The param info of the parameter at index `index`.
#[doc(hidden)]
fn param_info(
index: usize,
param_name: &str,
) -> Option<crate::registry::method::MethodParamOrReturnInfo>;

/// The property info of the parameter at index `index`.
fn property_info(index: usize, param_name: &str) -> Option<PropertyInfo> {
Self::param_info(index, param_name).map(|param| param.info)
}

/// Return a string representing the arguments.
fn format_args(&self) -> String;
}

/// Represents a parameter list that is received from some external location (usually Godot).
///
/// As an example, this would be used for user-defined functions that will be called from Godot, however this is _not_ used when
/// calling a Godot function from Rust code.
pub trait InParamTuple: ParamTuple {
/// Converts `args_ptr` to `Self` by first going through [`Variant`].
///
/// # Safety
///
/// - `args_ptr` must be a pointer to an array of length [`Self::LEN`](ParamTuple::LEN)
/// - Each element of `args_ptr` must be reborrowable as a `&Variant` with a lifetime that lasts for the duration of the call.
unsafe fn from_varcall_args(
args_ptr: *const sys::GDExtensionConstVariantPtr,
call_ctx: &CallContext,
) -> CallResult<Self>;

/// Converts `args_ptr` to `Self` directly.
///
/// # Safety
///
/// - `args_ptr` must be a pointer to a valid array of length [`Self::LEN`](ParamTuple::LEN)
/// - each element of `args_ptr` must be of the same type as each element of `Self`
unsafe fn from_ptrcall_args(
args_ptr: *const sys::GDExtensionConstTypePtr,
call_type: sys::PtrcallType,
call_ctx: &CallContext,
) -> Self;

/// Converts `array` to `Self` by calling [`from_variant`](crate::meta::FromGodot::from_variant) on each argument.
fn from_variant_array(array: &[&Variant]) -> Self;
}

/// Represents a parameter list that is used to call some external code.
///
/// As an example, this would be used to call Godot functions through FFI, however this is _not_ used when Godot calls a user-defined
/// function.
pub trait OutParamTuple: ParamTuple {
/// Call `f` on the tuple `self` by first converting `self` to an array of [`Variant`]s.
fn with_variants<F, R>(self, f: F) -> R
where
F: FnOnce(&[Variant]) -> R;

/// Call `f` on the tuple `self` by first converting `self` to an array of [`Variant`] pointers.
fn with_variant_pointers<F, R>(self, f: F) -> R
where
F: FnOnce(&[sys::GDExtensionConstVariantPtr]) -> R;

/// Call `f` on the tuple `self` by first converting `self` to an array of Godot type pointers.
fn with_type_pointers<F, R>(self, f: F) -> R
where
F: FnOnce(&[sys::GDExtensionConstTypePtr]) -> R;

/// Converts `array` to `Self` by calling [`to_variant`](crate::meta::ToGodot::to_variant) on each argument.
fn to_variant_array(&self) -> Vec<Variant>;
}
Loading
Loading