Skip to content

Commit 404124b

Browse files
committed
Link from class docs to signal collection type
1 parent c961170 commit 404124b

File tree

3 files changed

+44
-23
lines changed

3 files changed

+44
-23
lines changed

godot-codegen/src/generator/classes.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,16 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
137137
// Associated "sidecar" module is made public if there are other symbols related to the class, which are not
138138
// in top-level godot::classes module (notification enums are not in the sidecar, but in godot::classes::notify).
139139
// This checks if token streams (i.e. code) is empty.
140-
let has_sidecar_module = !enums.is_empty() || !builders.is_empty();
140+
let has_sidecar_module = !enums.is_empty() || !builders.is_empty() || signal_types.is_some();
141141

142142
let class_doc = docs::make_class_doc(
143143
class_name,
144144
base_ident_opt,
145145
notification_enum.is_some(),
146146
has_sidecar_module,
147+
signal_types.is_some(),
147148
);
149+
148150
let module_doc = docs::make_module_doc(class_name);
149151

150152
let virtual_trait = virtual_traits::make_virtual_methods_trait(

godot-codegen/src/generator/docs.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//!
1010
//! Single module for documentation, rather than having it in each symbol-specific file, so it's easier to keep docs consistent.
1111
12+
use crate::generator::signals;
1213
use crate::models::domain::{ModName, TyName};
1314
use crate::special_cases;
1415
use proc_macro2::Ident;
@@ -18,6 +19,7 @@ pub fn make_class_doc(
1819
base_ident_opt: Option<Ident>,
1920
has_notification_enum: bool,
2021
has_sidecar_module: bool,
22+
has_signal_collection: bool,
2123
) -> String {
2224
let TyName { rust_ty, godot_ty } = class_name;
2325

@@ -29,15 +31,28 @@ pub fn make_class_doc(
2931
.to_string()
3032
};
3133

32-
let notify_line = if has_notification_enum {
33-
format!("* [`{rust_ty}Notification`][crate::classes::notify::{rust_ty}Notification]: notification type\n")
34+
let (sidecar_signal_lines, module_name);
35+
if has_sidecar_module {
36+
let module = ModName::from_godot(&class_name.godot_ty).rust_mod;
37+
38+
sidecar_signal_lines = format!("* [`{module}`][crate::classes::{module}]: sidecar module with related enum/flag types\n");
39+
module_name = Some(module);
40+
} else {
41+
sidecar_signal_lines = String::new();
42+
module_name = None;
43+
};
44+
45+
let signal_line = if has_signal_collection {
46+
let signal_coll = signals::make_collection_name(class_name);
47+
let module = module_name.expect("signal implies presence of sidecar module");
48+
49+
format!("* [`{signal_coll}`][crate::classes::{module}::{signal_coll}]: signal collection\n")
3450
} else {
3551
String::new()
3652
};
3753

38-
let sidecar_line = if has_sidecar_module {
39-
let module_name = ModName::from_godot(&class_name.godot_ty).rust_mod;
40-
format!("* [`{module_name}`][crate::classes::{module_name}]: sidecar module with related enum/flag types\n")
54+
let notify_line = if has_notification_enum {
55+
format!("* [`{rust_ty}Notification`][crate::classes::notify::{rust_ty}Notification]: notification type\n")
4156
} else {
4257
String::new()
4358
};
@@ -59,8 +74,9 @@ pub fn make_class_doc(
5974
{inherits_line}\n\n\
6075
\
6176
Related symbols:\n\n\
62-
{sidecar_line}\
77+
{sidecar_signal_lines}\
6378
* [`{trait_name}`][crate::classes::{trait_name}]: virtual methods\n\
79+
{signal_line}\
6480
{notify_line}\
6581
\n\n\
6682
See also [Godot docs for `{godot_ty}`]({online_link}).\n\n{notes}",

godot-codegen/src/generator/signals.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ pub fn make_class_signals(
2121
class: &Class,
2222
signals: &[ClassSignal],
2323
_ctx: &mut Context,
24-
) -> TokenStream {
24+
) -> Option<TokenStream> {
2525
if signals.is_empty() {
26-
return TokenStream::new();
26+
return None;
2727
}
2828

2929
let all_params: Vec<SignalParams> = signals
@@ -38,10 +38,16 @@ pub fn make_class_signals(
3838
.zip(all_params.iter())
3939
.map(|(signal, params)| make_signal_individual_struct(signal, params));
4040

41-
quote! {
42-
#signal_collection_struct
43-
#( #signal_types )*
44-
}
41+
Some(quote! {
42+
#[cfg(since_api = "4.2")]
43+
pub use signals::*;
44+
45+
#[cfg(since_api = "4.2")]
46+
mod signals {
47+
#signal_collection_struct
48+
#( #signal_types )*
49+
}
50+
})
4551
}
4652

4753
// Used outside, to document class with links to this type.
@@ -86,17 +92,14 @@ fn make_signal_collection(
8692

8793
quote! {
8894
#[doc = #collection_docs]
89-
#[cfg(since_api = "4.2")]
9095
pub struct #collection_struct_name<'c> {
9196
__gd: &'c mut Gd<re_export::#class_name>,
9297
}
9398

94-
#[cfg(since_api = "4.2")]
9599
impl<'c> #collection_struct_name<'c> {
96100
#( #provider_methods )*
97101
}
98102

99-
#[cfg(since_api = "4.2")]
100103
impl crate::obj::WithSignals for re_export::#class_name {
101104
type SignalCollection<'c> = #collection_struct_name<'c>;
102105
#[doc(hidden)]
@@ -126,29 +129,29 @@ fn make_signal_individual_struct(signal: &ClassSignal, params: &SignalParams) ->
126129
let class_ty = quote! { re_export::#class_name };
127130
let param_tuple = quote! { ( #type_list ) };
128131

132+
// Embedded in `mod signals`.
129133
quote! {
130-
#[cfg(since_api = "4.2")]
131134
pub struct #individual_struct_name<'c> {
132-
pub typed: crate::registry::signal::TypedSignal<'c, #class_ty, #param_tuple>,
135+
typed: Self::TypedSignal,
133136
}
134137

135-
#[cfg(since_api = "4.2")]
136-
impl #individual_struct_name<'_> {
138+
impl<'c> #individual_struct_name<'c> {
139+
type ParamTuple = #param_tuple;
140+
type TypedSignal = crate::registry::signal::TypedSignal<'c, #class_ty, Self::ParamTuple>;
141+
137142
pub fn emit(&mut self, #param_list) {
138143
self.typed.emit_tuple( (#name_list) );
139144
}
140145
}
141146

142-
#[cfg(since_api = "4.2")]
143147
impl<'c> std::ops::Deref for #individual_struct_name<'c> {
144-
type Target = crate::registry::signal::TypedSignal<'c, #class_ty, #param_tuple>;
148+
type Target = Self::TypedSignal;
145149

146150
fn deref(&self) -> &Self::Target {
147151
&self.typed
148152
}
149153
}
150154

151-
#[cfg(since_api = "4.2")]
152155
impl std::ops::DerefMut for #individual_struct_name<'_> {
153156
fn deref_mut(&mut self) -> &mut Self::Target {
154157
&mut self.typed

0 commit comments

Comments
 (0)