@@ -119,6 +119,77 @@ unsafe extern "C" fn ffi_deinitialize_layer<E: ExtensionLibrary>(
119
119
} ) ;
120
120
}
121
121
122
+ #[ cfg( since_api = "4.3" ) ]
123
+ /// # Safety
124
+ ///
125
+ /// The Godot binding must have been initialized before calling this function.
126
+ ///
127
+ /// If "experimental-threads" is not enabled, then this must be called from the same thread that the bindings were initialized from.
128
+ unsafe fn register_docs ( ) {
129
+ use crate :: registry:: plugin:: PluginItem ;
130
+ use std:: collections:: { hash_map:: Entry , HashMap } ;
131
+ #[ derive( Default ) ]
132
+ struct DocPieces {
133
+ /// base, description, members
134
+ definition : [ & ' static str ; 3 ] ,
135
+ /// methods, signals, constants
136
+ inherent : [ & ' static str ; 3 ] ,
137
+ imethods : & ' static str ,
138
+ }
139
+
140
+ let mut map = HashMap :: < & ' static str , DocPieces > :: new ( ) ;
141
+ crate :: private:: iterate_plugins ( |x| match x. item {
142
+ PluginItem :: InherentImpl { docs, .. } => match map. entry ( x. class_name . as_str ( ) ) {
143
+ Entry :: Occupied ( x) => x. into_mut ( ) . inherent = docs,
144
+ Entry :: Vacant ( x) => drop ( x. insert ( DocPieces {
145
+ inherent : docs,
146
+ ..Default :: default ( )
147
+ } ) ) ,
148
+ } ,
149
+ PluginItem :: ITraitImpl { docs, .. } => match map. entry ( x. class_name . as_str ( ) ) {
150
+ Entry :: Occupied ( x) => x. into_mut ( ) . imethods = docs,
151
+ Entry :: Vacant ( x) => drop ( x. insert ( DocPieces {
152
+ imethods : docs,
153
+ ..Default :: default ( )
154
+ } ) ) ,
155
+ } ,
156
+ PluginItem :: Struct { docs, .. } => match map. entry ( x. class_name . as_str ( ) ) {
157
+ Entry :: Occupied ( x) => x. into_mut ( ) . definition = docs,
158
+ Entry :: Vacant ( x) => drop ( x. insert ( DocPieces {
159
+ definition : docs,
160
+ ..Default :: default ( )
161
+ } ) ) ,
162
+ } ,
163
+ } ) ;
164
+ for (
165
+ class,
166
+ DocPieces {
167
+ definition : [ base, desc, members] ,
168
+ inherent : [ methods, signals, constants] ,
169
+ imethods,
170
+ } ,
171
+ ) in map
172
+ {
173
+ let brief = desc. lines ( ) . next ( ) . unwrap_or_default ( ) ;
174
+ let xml = format ! (
175
+ r#"
176
+ <?xml version="1.0" encoding="UTF-8"?>
177
+ <class name="{class}" inherits="{base}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
178
+ <brief_description>{brief}</brief_description>
179
+ <description>{desc}</description>
180
+ <methods>{methods}{imethods}</methods>
181
+ <constants>{constants}</constants>
182
+ <signals>{signals}</signals>
183
+ <members>{members}</members>
184
+ </class>"#
185
+ ) ;
186
+ crate :: sys:: interface_fn!( editor_help_load_xml_from_utf8_chars_and_len) (
187
+ xml. as_ptr ( ) . cast ( ) ,
188
+ xml. len ( ) as i64 ,
189
+ ) ;
190
+ }
191
+ }
192
+
122
193
/// Tasks needed to be done by gdext internally upon loading an initialization level. Called before user code.
123
194
fn gdext_on_level_init ( level : InitLevel ) {
124
195
// SAFETY: we are in the main thread, during initialization, no other logic is happening.
@@ -136,6 +207,8 @@ fn gdext_on_level_init(level: InitLevel) {
136
207
ensure_godot_features_compatible ( ) ;
137
208
}
138
209
InitLevel :: Editor => {
210
+ #[ cfg( since_api = "4.3" ) ]
211
+ register_docs ( ) ;
139
212
sys:: load_class_method_table ( sys:: ClassApiLevel :: Editor ) ;
140
213
}
141
214
}
0 commit comments