@@ -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,9 @@ 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 ( util:: extract_cfg_attrs ( external_attributes) . into_iter ( ) . collect ( ) ) ;
106
123
signal_name_strs. push ( signature. name . to_string ( ) ) ;
107
124
signal_parameters_count. push ( param_names. len ( ) ) ;
108
125
signal_parameters. push ( param_array_decl) ;
@@ -164,20 +181,23 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
164
181
use :: godot:: sys;
165
182
166
183
#(
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
- ) ;
184
+ #( #signal_cfg_attrs) *
185
+ {
186
+ let parameters_info: [ :: godot:: builtin:: meta:: PropertyInfo ; #signal_parameters_count] = #signal_parameters;
187
+
188
+ let mut parameters_info_sys: [ :: godot:: sys:: GDExtensionPropertyInfo ; #signal_parameters_count] =
189
+ std:: array:: from_fn( |i| parameters_info[ i] . property_sys( ) ) ;
190
+
191
+ let signal_name = :: godot:: builtin:: StringName :: from( #signal_name_strs) ;
192
+
193
+ sys:: interface_fn!( classdb_register_extension_class_signal) (
194
+ sys:: get_library( ) ,
195
+ #class_name_obj. string_sys( ) ,
196
+ signal_name. string_sys( ) ,
197
+ parameters_info_sys. as_ptr( ) ,
198
+ sys:: GDExtensionInt :: from( #signal_parameters_count as i64 ) ,
199
+ ) ;
200
+ } ;
181
201
) *
182
202
}
183
203
}
@@ -203,9 +223,11 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
203
223
Ok ( result)
204
224
}
205
225
206
- fn process_godot_fns ( decl : & mut Impl ) -> Result < ( Vec < FuncDefinition > , Vec < Function > ) , Error > {
226
+ fn process_godot_fns (
227
+ decl : & mut Impl ,
228
+ ) -> Result < ( Vec < FuncDefinition > , Vec < SignalDefinition > ) , Error > {
207
229
let mut func_definitions = vec ! [ ] ;
208
- let mut signal_signatures = vec ! [ ] ;
230
+ let mut signal_definitions = vec ! [ ] ;
209
231
210
232
let mut removed_indexes = vec ! [ ] ;
211
233
for ( index, item) in decl. body_items . iter_mut ( ) . enumerate ( ) {
@@ -259,9 +281,13 @@ fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<FuncDefinition>, Vec<Functi
259
281
if method. return_ty . is_some ( ) {
260
282
return attr. bail ( "return types are not supported" , method) ;
261
283
}
284
+ let external_attributes = method. attributes . clone ( ) ;
262
285
let sig = util:: reduce_to_signature ( method) ;
263
286
264
- signal_signatures. push ( sig. clone ( ) ) ;
287
+ signal_definitions. push ( SignalDefinition {
288
+ signature : sig,
289
+ external_attributes,
290
+ } ) ;
265
291
removed_indexes. push ( index) ;
266
292
}
267
293
BoundAttrType :: Const ( _) => {
@@ -280,7 +306,7 @@ fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<FuncDefinition>, Vec<Functi
280
306
decl. body_items . remove ( index) ;
281
307
}
282
308
283
- Ok ( ( func_definitions, signal_signatures ) )
309
+ Ok ( ( func_definitions, signal_definitions ) )
284
310
}
285
311
286
312
fn process_godot_constants ( decl : & mut Impl ) -> Result < Vec < Constant > , Error > {
0 commit comments