@@ -8,7 +8,7 @@ use crate::util;
8
8
use crate :: util:: bail;
9
9
use proc_macro2:: { Ident , TokenStream } ;
10
10
use quote:: quote;
11
- use venial:: { AttributeValue , Declaration , Error , Function , Impl , ImplMember } ;
11
+ use venial:: { AttributeValue , Declaration , Error , FnParam , Function , Impl , ImplMember , TyExpr } ;
12
12
13
13
pub fn transform ( input_decl : Declaration ) -> Result < TokenStream , Error > {
14
14
let decl = match input_decl {
@@ -62,19 +62,41 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
62
62
let class_name = util:: validate_impl ( & decl, None , "godot_api" ) ?;
63
63
let class_name_str = class_name. to_string ( ) ;
64
64
65
- //let register_fn = format_ident!("__godot_rust_register_{}", class_name_str);
66
- //#[allow(non_snake_case)]
67
-
68
65
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
+ }
70
93
71
94
let prv = quote ! { :: godot:: private } ;
72
95
73
96
let result = quote ! {
74
97
#decl
75
98
76
99
impl :: godot:: obj:: cap:: ImplementsGodotApi for #class_name {
77
- //fn __register_methods(_builder: &mut ::godot::builder::ClassBuilder<Self>) {
78
100
fn __register_methods( ) {
79
101
#(
80
102
:: godot:: private:: gdext_register_method!( #class_name, #funcs) ;
@@ -83,14 +105,17 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
83
105
unsafe {
84
106
let class_name = :: godot:: builtin:: StringName :: from( #class_name_str) ;
85
107
use :: godot:: sys;
108
+
86
109
#(
110
+ let parameters = #signal_parameters;
87
111
let signal_name = :: godot:: builtin:: StringName :: from( #signal_name_strs) ;
112
+
88
113
sys:: interface_fn!( classdb_register_extension_class_signal) (
89
114
sys:: get_library( ) ,
90
115
class_name. string_sys( ) ,
91
116
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 ) ,
94
119
) ;
95
120
) *
96
121
}
@@ -110,9 +135,9 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
110
135
Ok ( result)
111
136
}
112
137
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 > {
114
139
let mut func_signatures = vec ! [ ] ;
115
- let mut signal_idents = vec ! [ ] ; // TODO consider signature
140
+ let mut signal_signatures = vec ! [ ] ;
116
141
117
142
let mut removed_indexes = vec ! [ ] ;
118
143
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
147
172
func_signatures. push ( sig) ;
148
173
}
149
174
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) ;
152
177
}
178
+ let sig = util:: reduce_to_signature ( method) ;
153
179
154
- signal_idents . push ( method . name . clone ( ) ) ;
180
+ signal_signatures . push ( sig . clone ( ) ) ;
155
181
removed_indexes. push ( index) ;
156
182
}
157
183
}
@@ -164,7 +190,7 @@ fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<Function>, Vec<Ident>), Err
164
190
decl. body_items . remove ( index) ;
165
191
}
166
192
167
- Ok ( ( func_signatures, signal_idents ) )
193
+ Ok ( ( func_signatures, signal_signatures ) )
168
194
}
169
195
170
196
fn extract_attributes ( method : & Function ) -> Result < Option < BoundAttr > , Error > {
0 commit comments