@@ -67,21 +67,35 @@ impl BoundAttr {
67
67
}
68
68
}
69
69
70
+ /// Holds information known from a signal's definition
71
+ struct SignalDefinition {
72
+ /// The signal's function signature.
73
+ signature : Function ,
74
+
75
+ /// The signal's non-gdext attributes (that is, excluding #[signal]).
76
+ external_attributes : Vec < Attribute > ,
77
+ }
78
+
70
79
/// Codegen for `#[godot_api] impl MyType`
71
80
fn transform_inherent_impl ( mut decl : Impl ) -> Result < TokenStream , Error > {
72
81
let class_name = util:: validate_impl ( & decl, None , "godot_api" ) ?;
73
82
let class_name_obj = util:: class_name_obj ( & class_name) ;
74
83
let ( funcs, signals) = process_godot_fns ( & mut decl) ?;
75
84
85
+ let mut signal_cfg_attrs: Vec < Vec < & Attribute > > = Vec :: new ( ) ;
76
86
let mut signal_name_strs: Vec < String > = Vec :: new ( ) ;
77
87
let mut signal_parameters_count: Vec < usize > = Vec :: new ( ) ;
78
88
let mut signal_parameters: Vec < TokenStream > = Vec :: new ( ) ;
79
89
80
- for signature in signals {
90
+ for signal in signals. iter ( ) {
91
+ let SignalDefinition {
92
+ signature,
93
+ external_attributes,
94
+ } = signal;
81
95
let mut param_types: Vec < TyExpr > = Vec :: new ( ) ;
82
96
let mut param_names: Vec < String > = Vec :: new ( ) ;
83
97
84
- for param in signature. params . inner {
98
+ for param in signature. params . inner . iter ( ) {
85
99
match & param. 0 {
86
100
FnParam :: Typed ( param) => {
87
101
param_types. push ( param. ty . clone ( ) ) ;
@@ -103,6 +117,13 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
103
117
]
104
118
} ;
105
119
120
+ // Transport #[cfg] attrs to the FFI glue to ensure signals which were conditionally
121
+ // removed from compilation don't cause errors.
122
+ signal_cfg_attrs. push (
123
+ util:: extract_cfg_attrs ( external_attributes)
124
+ . into_iter ( )
125
+ . collect ( ) ,
126
+ ) ;
106
127
signal_name_strs. push ( signature. name . to_string ( ) ) ;
107
128
signal_parameters_count. push ( param_names. len ( ) ) ;
108
129
signal_parameters. push ( param_array_decl) ;
@@ -164,20 +185,23 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
164
185
use :: godot:: sys;
165
186
166
187
#(
167
- let parameters_info: [ :: godot:: builtin:: meta:: PropertyInfo ; #signal_parameters_count] = #signal_parameters;
168
-
169
- let mut parameters_info_sys: [ :: godot:: sys:: GDExtensionPropertyInfo ; #signal_parameters_count] =
170
- std:: array:: from_fn( |i| parameters_info[ i] . property_sys( ) ) ;
171
-
172
- let signal_name = :: godot:: builtin:: StringName :: from( #signal_name_strs) ;
173
-
174
- sys:: interface_fn!( classdb_register_extension_class_signal) (
175
- sys:: get_library( ) ,
176
- #class_name_obj. string_sys( ) ,
177
- signal_name. string_sys( ) ,
178
- parameters_info_sys. as_ptr( ) ,
179
- sys:: GDExtensionInt :: from( #signal_parameters_count as i64 ) ,
180
- ) ;
188
+ #( #signal_cfg_attrs) *
189
+ {
190
+ let parameters_info: [ :: godot:: builtin:: meta:: PropertyInfo ; #signal_parameters_count] = #signal_parameters;
191
+
192
+ let mut parameters_info_sys: [ :: godot:: sys:: GDExtensionPropertyInfo ; #signal_parameters_count] =
193
+ std:: array:: from_fn( |i| parameters_info[ i] . property_sys( ) ) ;
194
+
195
+ let signal_name = :: godot:: builtin:: StringName :: from( #signal_name_strs) ;
196
+
197
+ sys:: interface_fn!( classdb_register_extension_class_signal) (
198
+ sys:: get_library( ) ,
199
+ #class_name_obj. string_sys( ) ,
200
+ signal_name. string_sys( ) ,
201
+ parameters_info_sys. as_ptr( ) ,
202
+ sys:: GDExtensionInt :: from( #signal_parameters_count as i64 ) ,
203
+ ) ;
204
+ } ;
181
205
) *
182
206
}
183
207
}
@@ -203,9 +227,11 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
203
227
Ok ( result)
204
228
}
205
229
206
- fn process_godot_fns ( decl : & mut Impl ) -> Result < ( Vec < FuncDefinition > , Vec < Function > ) , Error > {
230
+ fn process_godot_fns (
231
+ decl : & mut Impl ,
232
+ ) -> Result < ( Vec < FuncDefinition > , Vec < SignalDefinition > ) , Error > {
207
233
let mut func_definitions = vec ! [ ] ;
208
- let mut signal_signatures = vec ! [ ] ;
234
+ let mut signal_definitions = vec ! [ ] ;
209
235
210
236
let mut removed_indexes = vec ! [ ] ;
211
237
for ( index, item) in decl. body_items . iter_mut ( ) . enumerate ( ) {
@@ -259,9 +285,13 @@ fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<FuncDefinition>, Vec<Functi
259
285
if method. return_ty . is_some ( ) {
260
286
return attr. bail ( "return types are not supported" , method) ;
261
287
}
288
+ let external_attributes = method. attributes . clone ( ) ;
262
289
let sig = util:: reduce_to_signature ( method) ;
263
290
264
- signal_signatures. push ( sig. clone ( ) ) ;
291
+ signal_definitions. push ( SignalDefinition {
292
+ signature : sig,
293
+ external_attributes,
294
+ } ) ;
265
295
removed_indexes. push ( index) ;
266
296
}
267
297
BoundAttrType :: Const ( _) => {
@@ -280,7 +310,7 @@ fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<FuncDefinition>, Vec<Functi
280
310
decl. body_items . remove ( index) ;
281
311
}
282
312
283
- Ok ( ( func_definitions, signal_signatures ) )
313
+ Ok ( ( func_definitions, signal_definitions ) )
284
314
}
285
315
286
316
fn process_godot_constants ( decl : & mut Impl ) -> Result < Vec < Constant > , Error > {
0 commit comments