Skip to content

Commit 08fd033

Browse files
authored
Merge pull request #1743 from dsnopek/get-used-classes
Register the classes used with the Godot editor
2 parents 195188f + aed195f commit 08fd033

File tree

5 files changed

+36
-4
lines changed

5 files changed

+36
-4
lines changed

gdextension/gdextension_interface.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
2929
/**************************************************************************/
3030

31-
#ifndef GDEXTENSION_INTERFACE_H
32-
#define GDEXTENSION_INTERFACE_H
31+
#pragma once
3332

3433
/* This is a C class header, you can copy it and use it directly in your own binders.
3534
* Together with the JSON file, you should be able to generate any binder.
@@ -401,6 +400,9 @@ typedef struct {
401400

402401
typedef void *GDExtensionClassLibraryPtr;
403402

403+
/* Passed a pointer to a PackedStringArray that should be filled with the classes that may be used by the GDExtension. */
404+
typedef void (*GDExtensionEditorGetClassesUsedCallback)(GDExtensionTypePtr p_packed_string_array);
405+
404406
/* Method */
405407

406408
typedef enum {
@@ -3078,8 +3080,22 @@ typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars)(const char *
30783080
*/
30793081
typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen)(const char *p_data, GDExtensionInt p_size);
30803082

3083+
/**
3084+
* @name editor_register_get_classes_used_callback
3085+
* @since 4.5
3086+
*
3087+
* Registers a callback that Godot can call to get the list of all classes (from ClassDB) that may be used by the calling GDExtension.
3088+
*
3089+
* This is used by the editor to generate a build profiles (in "Tools" > "Engine Compilation Configuration Editor..." > "Detect from project"),
3090+
* in order to recompile Godot with only the classes used.
3091+
* In the provided callback, the GDExtension should provide the list of classes that _may_ be used statically, thus the time of invocation shouldn't matter.
3092+
* If a GDExtension doesn't register a callback, Godot will assume that it could be using any classes.
3093+
*
3094+
* @param p_library A pointer the library received by the GDExtension's entry point function.
3095+
* @param p_callback The callback to retrieve the list of classes used.
3096+
*/
3097+
typedef void (*GDExtensionInterfaceEditorRegisterGetClassesUsedCallback)(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback);
3098+
30813099
#ifdef __cplusplus
30823100
}
30833101
#endif
3084-
3085-
#endif // GDEXTENSION_INTERFACE_H

include/godot_cpp/core/class_db.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ class ClassDB {
167167
instance_binding_callbacks[p_name] = p_callbacks;
168168
}
169169

170+
static void _editor_get_classes_used_callback(GDExtensionTypePtr p_packed_string_array);
171+
170172
static void _register_engine_singleton(const StringName &p_class_name, Object *p_singleton) {
171173
std::lock_guard<std::mutex> lock(engine_singletons_mutex);
172174
std::unordered_map<StringName, Object *>::const_iterator i = engine_singletons.find(p_class_name);

include/godot_cpp/godot.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ extern "C" GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_inter
197197
extern "C" GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path;
198198
extern "C" GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin;
199199
extern "C" GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin;
200+
extern "C" GDExtensionInterfaceEditorRegisterGetClassesUsedCallback gdextension_interface_editor_register_get_classes_used_callback;
200201
extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars;
201202
extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len;
202203
extern "C" GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw;

src/core/class_db.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,15 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_
388388
}
389389
}
390390

391+
void ClassDB::_editor_get_classes_used_callback(GDExtensionTypePtr p_packed_string_array) {
392+
PackedStringArray *arr = reinterpret_cast<PackedStringArray *>(p_packed_string_array);
393+
arr->resize(instance_binding_callbacks.size());
394+
int index = 0;
395+
for (const std::pair<StringName, const GDExtensionInstanceBindingCallbacks *> &pair : instance_binding_callbacks) {
396+
(*arr)[index++] = pair.first;
397+
}
398+
}
399+
391400
void ClassDB::initialize_class(const ClassInfo &p_cl) {
392401
}
393402

src/godot.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_interface_classd
204204
GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path = nullptr;
205205
GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin = nullptr;
206206
GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin = nullptr;
207+
GDExtensionInterfaceEditorRegisterGetClassesUsedCallback gdextension_interface_editor_register_get_classes_used_callback = nullptr;
207208
GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars = nullptr;
208209
GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len = nullptr;
209210
GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw = nullptr;
@@ -486,6 +487,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
486487
LOAD_PROC_ADDRESS(get_library_path, GDExtensionInterfaceGetLibraryPath);
487488
LOAD_PROC_ADDRESS(editor_add_plugin, GDExtensionInterfaceEditorAddPlugin);
488489
LOAD_PROC_ADDRESS(editor_remove_plugin, GDExtensionInterfaceEditorRemovePlugin);
490+
LOAD_PROC_ADDRESS(editor_register_get_classes_used_callback, GDExtensionInterfaceEditorRegisterGetClassesUsedCallback);
489491
LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars);
490492
LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars_and_len, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen);
491493
LOAD_PROC_ADDRESS(image_ptrw, GDExtensionInterfaceImagePtrw);
@@ -521,6 +523,8 @@ void GDExtensionBinding::initialize_level(void *p_userdata, GDExtensionInitializ
521523
level_initialized[p_level]++;
522524

523525
if ((ModuleInitializationLevel)p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
526+
internal::gdextension_interface_editor_register_get_classes_used_callback(internal::library, &ClassDB::_editor_get_classes_used_callback);
527+
524528
const internal::DocData &doc_data = internal::get_doc_data();
525529
if (doc_data.is_valid()) {
526530
doc_data.load_data();

0 commit comments

Comments
 (0)