Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions gdextension/gdextension_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#ifndef GDEXTENSION_INTERFACE_H
#define GDEXTENSION_INTERFACE_H
#pragma once

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

typedef void *GDExtensionClassLibraryPtr;

/* Passed a pointer to a PackedStringArray that should be filled with the classes that may be used by the GDExtension. */
typedef void (*GDExtensionEditorGetClassesUsedCallback)(GDExtensionTypePtr p_packed_string_array);

/* Method */

typedef enum {
Expand Down Expand Up @@ -3078,8 +3080,22 @@ typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars)(const char *
*/
typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen)(const char *p_data, GDExtensionInt p_size);

/**
* @name editor_register_get_classes_used_callback
* @since 4.5
*
* Registers a callback that Godot can call to get the list of all classes (from ClassDB) that may be used by the calling GDExtension.
*
* This is used by the editor to generate a build profiles (in "Tools" > "Engine Compilation Configuration Editor..." > "Detect from project"),
* in order to recompile Godot with only the classes used.
* 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.
* If a GDExtension doesn't register a callback, Godot will assume that it could be using any classes.
*
* @param p_library A pointer the library received by the GDExtension's entry point function.
* @param p_callback The callback to retrieve the list of classes used.
*/
typedef void (*GDExtensionInterfaceEditorRegisterGetClassesUsedCallback)(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback);

#ifdef __cplusplus
}
#endif

#endif // GDEXTENSION_INTERFACE_H
2 changes: 2 additions & 0 deletions include/godot_cpp/core/class_db.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ class ClassDB {
instance_binding_callbacks[p_name] = p_callbacks;
}

static void _editor_get_classes_used_callback(GDExtensionTypePtr p_packed_string_array);

static void _register_engine_singleton(const StringName &p_class_name, Object *p_singleton) {
std::lock_guard<std::mutex> lock(engine_singletons_mutex);
std::unordered_map<StringName, Object *>::const_iterator i = engine_singletons.find(p_class_name);
Expand Down
1 change: 1 addition & 0 deletions include/godot_cpp/godot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ extern "C" GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_inter
extern "C" GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path;
extern "C" GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin;
extern "C" GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin;
extern "C" GDExtensionInterfaceEditorRegisterGetClassesUsedCallback gdextension_interface_editor_register_get_classes_used_callback;
extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars;
extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len;
extern "C" GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw;
Expand Down
9 changes: 9 additions & 0 deletions src/core/class_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,15 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_
}
}

void ClassDB::_editor_get_classes_used_callback(GDExtensionTypePtr p_packed_string_array) {
PackedStringArray *arr = reinterpret_cast<PackedStringArray *>(p_packed_string_array);
arr->resize(instance_binding_callbacks.size());
int index = 0;
for (const std::pair<StringName, const GDExtensionInstanceBindingCallbacks *> &pair : instance_binding_callbacks) {
(*arr)[index++] = pair.first;
}
}

void ClassDB::initialize_class(const ClassInfo &p_cl) {
}

Expand Down
4 changes: 4 additions & 0 deletions src/godot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_interface_classd
GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path = nullptr;
GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin = nullptr;
GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin = nullptr;
GDExtensionInterfaceEditorRegisterGetClassesUsedCallback gdextension_interface_editor_register_get_classes_used_callback = nullptr;
GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars = nullptr;
GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len = nullptr;
GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw = nullptr;
Expand Down Expand Up @@ -486,6 +487,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
LOAD_PROC_ADDRESS(get_library_path, GDExtensionInterfaceGetLibraryPath);
LOAD_PROC_ADDRESS(editor_add_plugin, GDExtensionInterfaceEditorAddPlugin);
LOAD_PROC_ADDRESS(editor_remove_plugin, GDExtensionInterfaceEditorRemovePlugin);
LOAD_PROC_ADDRESS(editor_register_get_classes_used_callback, GDExtensionInterfaceEditorRegisterGetClassesUsedCallback);
LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars);
LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars_and_len, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen);
LOAD_PROC_ADDRESS(image_ptrw, GDExtensionInterfaceImagePtrw);
Expand Down Expand Up @@ -521,6 +523,8 @@ void GDExtensionBinding::initialize_level(void *p_userdata, GDExtensionInitializ
level_initialized[p_level]++;

if ((ModuleInitializationLevel)p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
internal::gdextension_interface_editor_register_get_classes_used_callback(internal::library, &ClassDB::_editor_get_classes_used_callback);

const internal::DocData &doc_data = internal::get_doc_data();
if (doc_data.is_valid()) {
doc_data.load_data();
Expand Down