Skip to content

Commit b16deb7

Browse files
authored
Try #279:
2 parents 81f81c6 + 424c879 commit b16deb7

File tree

3 files changed

+66
-30
lines changed

3 files changed

+66
-30
lines changed

godot-core/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ pub mod private {
5252
pub use crate::registry::{callbacks, ClassPlugin, ErasedRegisterFn, PluginComponent};
5353
pub use crate::storage::as_storage;
5454
pub use crate::{
55-
gdext_register_method, gdext_register_method_inner, gdext_virtual_method_callback,
55+
gdext_get_arguments_info, gdext_register_method, gdext_register_method_inner,
56+
gdext_virtual_method_callback,
5657
};
5758

5859
use crate::{log, sys};

godot-core/src/macros.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -229,20 +229,7 @@ macro_rules! gdext_register_method_inner {
229229

230230
// Arguments meta-information
231231
let argument_count = NUM_ARGS as u32;
232-
let mut arguments_info: [PropertyInfo; NUM_ARGS] = {
233-
let mut i = -1i32;
234-
[$(
235-
{
236-
i += 1;
237-
let prop = Sig::property_info(i, stringify!($param));
238-
//OnceArg::new(prop)
239-
prop
240-
},
241-
)*]
242-
};
243-
let mut arguments_info_sys: [sys::GDExtensionPropertyInfo; NUM_ARGS]
244-
= std::array::from_fn(|i| arguments_info[i].property_sys());
245-
// = std::array::from_fn(|i| arguments_info[i].once_sys());
232+
let mut arguments_info: [sys::GDExtensionPropertyInfo; NUM_ARGS] = $crate::gdext_get_arguments_info!(($($RetTy)+, $($ParamTy),*), $( $param, )*);
246233
let mut arguments_metadata: [sys::GDExtensionClassMethodArgumentMetadata; NUM_ARGS]
247234
= std::array::from_fn(|i| Sig::param_metadata(i as i32));
248235

@@ -262,7 +249,7 @@ macro_rules! gdext_register_method_inner {
262249
return_value_info: std::ptr::addr_of_mut!(return_value_info_sys),
263250
return_value_metadata,
264251
argument_count,
265-
arguments_info: arguments_info_sys.as_mut_ptr(),
252+
arguments_info: arguments_info.as_mut_ptr(),
266253
arguments_metadata: arguments_metadata.as_mut_ptr(),
267254
default_argument_count: 0,
268255
default_arguments: std::ptr::null_mut(),
@@ -546,3 +533,25 @@ macro_rules! gdext_ptrcall {
546533
);
547534
};
548535
}
536+
537+
#[doc(hidden)]
538+
#[macro_export]
539+
macro_rules! gdext_get_arguments_info {
540+
(
541+
$Signature:ty,
542+
$($param:ident,)*
543+
) => {
544+
{
545+
use $crate::builtin::meta::*;
546+
547+
let mut i = -1i32;
548+
[$(
549+
{
550+
i += 1;
551+
let prop = <$Signature as SignatureTuple>::property_info(i, stringify!($param)).property_sys();
552+
prop
553+
},
554+
)*]
555+
}
556+
};
557+
}

godot-macros/src/godot_api.rs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::util;
88
use crate::util::bail;
99
use proc_macro2::{Ident, TokenStream};
1010
use quote::quote;
11-
use venial::{AttributeValue, Declaration, Error, Function, Impl, ImplMember};
11+
use venial::{AttributeValue, Declaration, Error, FnParam, Function, Impl, ImplMember, TyExpr};
1212

1313
pub fn transform(input_decl: Declaration) -> Result<TokenStream, Error> {
1414
let decl = match input_decl {
@@ -62,19 +62,41 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
6262
let class_name = util::validate_impl(&decl, None, "godot_api")?;
6363
let class_name_str = class_name.to_string();
6464

65-
//let register_fn = format_ident!("__godot_rust_register_{}", class_name_str);
66-
//#[allow(non_snake_case)]
67-
6865
let (funcs, signals) = process_godot_fns(&mut decl)?;
69-
let signal_name_strs = signals.into_iter().map(|ident| ident.to_string());
66+
67+
let mut signal_name_strs: Vec<String> = Vec::new();
68+
let mut signal_parameters_count: Vec<i64> = Vec::new();
69+
let mut signal_parameters: Vec<TokenStream> = Vec::new();
70+
71+
for signature in signals {
72+
let mut param_types: Vec<TyExpr> = Vec::new();
73+
let mut param_names: Vec<Ident> = Vec::new();
74+
75+
for param in signature.params.inner {
76+
match &param.0 {
77+
FnParam::Typed(param) => {
78+
param_types.push(param.ty.clone());
79+
param_names.push(param.name.clone());
80+
}
81+
FnParam::Receiver(_) => {}
82+
};
83+
}
84+
85+
signal_name_strs.push(signature.name.to_string());
86+
signal_parameters_count.push(param_names.len() as i64);
87+
signal_parameters.push(
88+
quote! {
89+
::godot::private::gdext_get_arguments_info!(((), #(#param_types ),*), #(#param_names, )*).as_ptr()
90+
},
91+
);
92+
}
7093

7194
let prv = quote! { ::godot::private };
7295

7396
let result = quote! {
7497
#decl
7598

7699
impl ::godot::obj::cap::ImplementsGodotApi for #class_name {
77-
//fn __register_methods(_builder: &mut ::godot::builder::ClassBuilder<Self>) {
78100
fn __register_methods() {
79101
#(
80102
::godot::private::gdext_register_method!(#class_name, #funcs);
@@ -83,14 +105,17 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
83105
unsafe {
84106
let class_name = ::godot::builtin::StringName::from(#class_name_str);
85107
use ::godot::sys;
108+
86109
#(
110+
let parameters = #signal_parameters;
87111
let signal_name = ::godot::builtin::StringName::from(#signal_name_strs);
112+
88113
sys::interface_fn!(classdb_register_extension_class_signal)(
89114
sys::get_library(),
90115
class_name.string_sys(),
91116
signal_name.string_sys(),
92-
std::ptr::null(), // NULL only valid for zero parameters, in current impl; maybe better empty slice
93-
0,
117+
parameters,
118+
sys::GDExtensionInt::from(#signal_parameters_count),
94119
);
95120
)*
96121
}
@@ -110,9 +135,9 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
110135
Ok(result)
111136
}
112137

113-
fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<Function>, Vec<Ident>), Error> {
138+
fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<Function>, Vec<Function>), Error> {
114139
let mut func_signatures = vec![];
115-
let mut signal_idents = vec![]; // TODO consider signature
140+
let mut signal_signatures = vec![];
116141

117142
let mut removed_indexes = vec![];
118143
for (index, item) in decl.body_items.iter_mut().enumerate() {
@@ -147,11 +172,12 @@ fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<Function>, Vec<Ident>), Err
147172
func_signatures.push(sig);
148173
}
149174
BoundAttrType::Signal(ref _attr_val) => {
150-
if !method.params.is_empty() || method.return_ty.is_some() {
151-
return attr.bail("parameters and return types not yet supported", method);
175+
if method.return_ty.is_some() {
176+
return attr.bail("return types are not supported", method);
152177
}
178+
let sig = util::reduce_to_signature(method);
153179

154-
signal_idents.push(method.name.clone());
180+
signal_signatures.push(sig.clone());
155181
removed_indexes.push(index);
156182
}
157183
}
@@ -164,7 +190,7 @@ fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<Function>, Vec<Ident>), Err
164190
decl.body_items.remove(index);
165191
}
166192

167-
Ok((func_signatures, signal_idents))
193+
Ok((func_signatures, signal_signatures))
168194
}
169195

170196
fn extract_attributes(method: &Function) -> Result<Option<BoundAttr>, Error> {

0 commit comments

Comments
 (0)