5
5
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
6
*/
7
7
8
+ use std:: collections:: { hash_map:: Entry , HashMap } ;
8
9
use std:: sync:: atomic:: { AtomicBool , Ordering :: Relaxed } ;
9
10
10
11
use godot_ffi as sys;
@@ -13,6 +14,7 @@ use sys::GodotFfi;
13
14
14
15
use crate :: builtin:: { GString , StringName } ;
15
16
use crate :: out;
17
+ use crate :: registry:: plugin:: PluginItem ;
16
18
17
19
pub use sys:: GdextBuild ;
18
20
@@ -119,6 +121,69 @@ unsafe extern "C" fn ffi_deinitialize_layer<E: ExtensionLibrary>(
119
121
} ) ;
120
122
}
121
123
124
+ unsafe fn register ( ) {
125
+ #[ derive( Default ) ]
126
+ struct DocPieces {
127
+ /// base, description
128
+ definition : [ & ' static str ; 2 ] ,
129
+ /// methods, signals, constants
130
+ inherent : [ & ' static str ; 3 ] ,
131
+ imethods : & ' static str ,
132
+ }
133
+
134
+ let mut map = HashMap :: < & ' static str , DocPieces > :: new ( ) ;
135
+ crate :: private:: iterate_plugins ( |x| match x. item {
136
+ PluginItem :: InherentImpl { docs, .. } => match map. entry ( x. class_name . as_str ( ) ) {
137
+ Entry :: Occupied ( x) => x. into_mut ( ) . inherent = docs,
138
+ Entry :: Vacant ( x) => drop ( x. insert ( DocPieces {
139
+ inherent : docs,
140
+ ..Default :: default ( )
141
+ } ) ) ,
142
+ } ,
143
+ PluginItem :: ITraitImpl { docs, .. } => match map. entry ( x. class_name . as_str ( ) ) {
144
+ Entry :: Occupied ( x) => x. into_mut ( ) . imethods = docs,
145
+ Entry :: Vacant ( x) => drop ( x. insert ( DocPieces {
146
+ imethods : docs,
147
+ ..Default :: default ( )
148
+ } ) ) ,
149
+ } ,
150
+ PluginItem :: Struct { docs, .. } => match map. entry ( x. class_name . as_str ( ) ) {
151
+ Entry :: Occupied ( x) => x. into_mut ( ) . definition = docs,
152
+ Entry :: Vacant ( x) => drop ( x. insert ( DocPieces {
153
+ definition : docs,
154
+ ..Default :: default ( )
155
+ } ) ) ,
156
+ } ,
157
+ } ) ;
158
+ for (
159
+ class,
160
+ DocPieces {
161
+ definition : [ base, desc] ,
162
+ inherent : [ methods, signals, constants] ,
163
+ imethods,
164
+ } ,
165
+ ) in map
166
+ {
167
+ let brief = desc. lines ( ) . next ( ) . unwrap_or_default ( ) ;
168
+ let xml = format ! (
169
+ r#"
170
+ <?xml version="1.0" encoding="UTF-8"?>
171
+ <class name="{class}" inherits="{base}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
172
+ <brief_description>{brief}</brief_description>
173
+ <description>{desc}</description>
174
+ <methods>{methods}{imethods}</methods>
175
+ <constants>{constants}</constants>
176
+ <signals>{signals}</signals>
177
+ </class>"#
178
+ ) ;
179
+ // SAFETY: the godot binding is initialized
180
+ crate :: sys:: interface_fn!( editor_help_load_xml_from_utf8_chars_and_len) (
181
+ xml. as_ptr ( ) . cast ( ) ,
182
+ xml. len ( ) as _ ,
183
+ ) ;
184
+ }
185
+ }
186
+
122
187
/// Tasks needed to be done by gdext internally upon loading an initialization level. Called before user code.
123
188
fn gdext_on_level_init ( level : InitLevel ) {
124
189
// SAFETY: we are in the main thread, during initialization, no other logic is happening.
@@ -136,17 +201,8 @@ fn gdext_on_level_init(level: InitLevel) {
136
201
ensure_godot_features_compatible ( ) ;
137
202
}
138
203
InitLevel :: Editor => {
139
- crate :: private:: iterate_plugins ( |x| match x. item {
140
- crate :: registry:: plugin:: PluginItem :: InherentImpl {
141
- register_documentation,
142
- ..
143
- } => register_documentation ( ) ,
144
- // crate::registry::plugin::PluginItem::ITraitImpl {
145
- // register_documentation,
146
- // ..
147
- // } => register_documentation(),
148
- _ => ( ) ,
149
- } ) ;
204
+ #[ cfg( since_api = "4.3" ) ]
205
+ register ( ) ;
150
206
sys:: load_class_method_table ( sys:: ClassApiLevel :: Editor ) ;
151
207
}
152
208
}
0 commit comments