@@ -77,7 +77,7 @@ impl<'a> SignalDetails<'a> {
77
77
78
78
let param_tuple = quote ! { ( #( #param_types, ) * ) } ;
79
79
let signal_name = & original_decl. name ;
80
- let individual_struct_name = format_ident ! ( "{}_{}" , class_name, signal_name) ;
80
+ let individual_struct_name = format_ident ! ( "__godot_Signal_ {}_{}" , class_name, signal_name) ;
81
81
82
82
Ok ( Self {
83
83
original_decl,
@@ -200,10 +200,11 @@ impl SignalCollection {
200
200
} = details;
201
201
202
202
self . collection_methods . push ( quote ! {
203
+ // Deliberately not #[doc(hidden)] for IDE completion.
203
204
#( #signal_cfg_attrs) *
204
205
fn #signal_name( self ) -> #individual_struct_name<' a> {
205
206
#individual_struct_name {
206
- typed: :: godot:: register:: TypedSignal :: new( self . object , #signal_name_str)
207
+ typed: :: godot:: register:: TypedSignal :: new( self . __internal_obj , #signal_name_str)
207
208
}
208
209
}
209
210
} ) ;
@@ -224,23 +225,29 @@ fn make_signal_individual_struct(details: &SignalDetails) -> TokenStream {
224
225
class_name,
225
226
param_names,
226
227
param_tuple,
227
- // signal_name,
228
228
signal_cfg_attrs,
229
229
individual_struct_name,
230
230
..
231
231
} = details;
232
232
233
- // let module_name = format_ident!("__godot_signal_{class_name}_{signal_name}");
234
-
235
- // Module + re-export.
236
- // Could also keep contained in module to reduce namespace pollution, but might make docs a bit more nested.
233
+ // Define the individual types + trait impls. The idea was originally to use a module to reduce namespace pollution:
234
+ // let module_name = format_ident!("__godot_signal_{class_name}_{signal_name}");
235
+ // #(#signal_cfg_attrs)* pub mod #module_name { use super::*; ... }
236
+ // #(#signal_cfg_attrs)* pub(crate) use #module_name::#individual_struct_name;
237
+ // However, there are some challenges:
238
+ // - Visibility becomes a pain to handle (rustc doesn't like re-exporting private symbols as pub, and we can't know the visibility of the
239
+ // surrounding class struct). Having signals always-public is much less of a headache, requires less choice on the user side
240
+ // (pub/pub(crate)/nothing on #[signal]), and likely good enough for the moment.
241
+ // - Not yet clear if we should have each signal + related types in separate module. If #[signal] is supported in #[godot_api(secondary)]
242
+ // impl blocks, then we would have to group them by the impl block. Rust doesn't allow partial modules, so they'd need to have individual
243
+ // names as well, possibly explicitly chosen by the user.
244
+ //
245
+ // For now, #[doc(hidden)] is used in some places to limit namespace pollution at least in IDEs + docs. This also means that the generated
246
+ // code is less observable by the user. If someone comes up with a good idea to handle all this, let us know :)
237
247
quote ! {
238
- // #(#signal_cfg_attrs)*
239
- // mod #module_name {
240
-
241
- // TODO make pub without running into "private type `MySignal` in public interface" errors.
242
248
#( #signal_cfg_attrs) *
243
249
#[ allow( non_camel_case_types) ]
250
+ #[ doc( hidden) ] // Signal struct is hidden, but the method returning it is not (IDE completion).
244
251
struct #individual_struct_name<' a> {
245
252
#[ doc( hidden) ]
246
253
typed: :: godot:: register:: TypedSignal <' a, #class_name, #param_tuple>,
@@ -269,27 +276,26 @@ fn make_signal_individual_struct(details: &SignalDetails) -> TokenStream {
269
276
& mut self . typed
270
277
}
271
278
}
272
-
273
- // #(#signal_cfg_attrs)*
274
- // pub(crate) use #module_name::#individual_struct_name;
275
279
}
276
280
}
277
281
278
- // See also make_func_collection() .
282
+ /// Generates a unspecified-name struct holding methods to access each signal .
279
283
fn make_signal_collection ( class_name : & Ident , collection : SignalCollection ) -> Option < TokenStream > {
280
284
if collection. is_empty ( ) {
281
285
return None ;
282
286
}
283
287
284
- let collection_struct_name = format_ident ! ( "{}Signals " , class_name) ;
288
+ let collection_struct_name = format_ident ! ( "__godot_Signals_{} " , class_name) ;
285
289
let collection_struct_methods = & collection. collection_methods ;
286
290
let individual_structs = collection. individual_structs ;
287
291
288
292
let code = quote ! {
289
293
#[ allow( non_camel_case_types) ]
294
+ #[ doc( hidden) ] // Only on struct, not methods, to allow completion in IDEs.
290
295
pub struct #collection_struct_name<' a> {
291
296
// To allow external call in the future (given Gd<T>, not self), this could be an enum with either BaseMut or &mut Gd<T>/&mut T.
292
- object: :: godot:: register:: ObjectRef <' a, #class_name>
297
+ #[ doc( hidden) ] // Necessary because it's in the same scope as the user-defined class, so appearing in IDE completion.
298
+ __internal_obj: :: godot:: register:: ObjectRef <' a, #class_name>
293
299
}
294
300
295
301
impl <' a> #collection_struct_name<' a> {
@@ -301,14 +307,14 @@ fn make_signal_collection(class_name: &Ident, collection: SignalCollection) -> O
301
307
302
308
fn signals( & mut self ) -> Self :: SignalCollection <' _> {
303
309
Self :: SignalCollection {
304
- object : :: godot:: register:: ObjectRef :: Internal { obj_mut: self }
310
+ __internal_obj : :: godot:: register:: ObjectRef :: Internal { obj_mut: self }
305
311
}
306
312
}
307
313
308
314
#[ doc( hidden) ]
309
315
fn __signals_from_external( external: & Gd <Self >) -> Self :: SignalCollection <' _> {
310
316
Self :: SignalCollection {
311
- object : :: godot:: register:: ObjectRef :: External { gd: external. clone( ) }
317
+ __internal_obj : :: godot:: register:: ObjectRef :: External { gd: external. clone( ) }
312
318
}
313
319
}
314
320
}
0 commit comments