diff --git a/gdextension/gdextension_interface.h b/gdextension/gdextension_interface.h
index d58f0226..8fda11c6 100644
--- a/gdextension/gdextension_interface.h
+++ b/gdextension/gdextension_interface.h
@@ -2617,6 +2617,31 @@ typedef void (*GDExtensionInterfaceEditorAddPlugin)(GDExtensionConstStringNamePt
*/
typedef void (*GDExtensionInterfaceEditorRemovePlugin)(GDExtensionConstStringNamePtr p_class_name);
+/**
+ * @name editor_help_load_xml_from_utf8_chars
+ * @since 4.3
+ *
+ * Loads new XML-formatted documentation data in the editor.
+ *
+ * The provided pointer can be immediately freed once the function returns.
+ *
+ * @param p_data A pointer to an UTF-8 encoded C string (null terminated).
+ */
+typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars)(const char *p_data);
+
+/**
+ * @name editor_help_load_xml_from_utf8_chars_and_len
+ * @since 4.3
+ *
+ * Loads new XML-formatted documentation data in the editor.
+ *
+ * The provided pointer can be immediately freed once the function returns.
+ *
+ * @param p_data A pointer to an UTF-8 encoded C string.
+ * @param p_size The number of bytes (not code units).
+ */
+typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen)(const char *p_data, GDExtensionInt p_size);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/godot_cpp/godot.hpp b/include/godot_cpp/godot.hpp
index c9e90226..f211b428 100644
--- a/include/godot_cpp/godot.hpp
+++ b/include/godot_cpp/godot.hpp
@@ -187,6 +187,8 @@ 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" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars;
+extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len;
} // namespace internal
diff --git a/src/godot.cpp b/src/godot.cpp
index 5c2aaa65..5d9fac84 100644
--- a/src/godot.cpp
+++ b/src/godot.cpp
@@ -193,6 +193,8 @@ 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;
+GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars = nullptr;
+GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len = nullptr;
} // namespace internal
@@ -430,6 +432,8 @@ 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_help_load_xml_from_utf8_chars, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars);
+ LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars_and_len, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen);
r_initialization->initialize = initialize_level;
r_initialization->deinitialize = deinitialize_level;
diff --git a/test/SConstruct b/test/SConstruct
index 9c25917b..95d8b4d5 100644
--- a/test/SConstruct
+++ b/test/SConstruct
@@ -16,6 +16,9 @@ env = SConscript("../SConstruct")
env.Append(CPPPATH=["src/"])
sources = Glob("src/*.cpp")
+doc_header = env.GodotCPPDocHeader("src/doc_data.gen.h", source=Glob("doc_classes/*.xml"))
+#sources.append(doc_header)
+
if env["platform"] == "macos":
library = env.SharedLibrary(
"project/bin/libgdexample.{}.{}.framework/libgdexample.{}.{}".format(
@@ -40,4 +43,4 @@ else:
source=sources,
)
-Default(library)
+Default(doc_header, library)
diff --git a/test/doc_classes/Example.xml b/test/doc_classes/Example.xml
new file mode 100644
index 00000000..2a28f2c9
--- /dev/null
+++ b/test/doc_classes/Example.xml
@@ -0,0 +1,25 @@
+
+
+
+ A test control defined in GDExtension.
+
+
+ A control used for the automated GDExtension tests.
+
+
+
+
+
+
+
+ Tests a simple function call.
+
+
+
+
+
+
+
+
+
+
diff --git a/test/project/project.godot b/test/project/project.godot
index 4f51c07f..df3dd70f 100644
--- a/test/project/project.godot
+++ b/test/project/project.godot
@@ -12,7 +12,7 @@ config_version=5
config/name="GDExtension Test Project"
run/main_scene="res://main.tscn"
-config/features=PackedStringArray("4.2")
+config/features=PackedStringArray("4.3")
config/icon="res://icon.png"
[native_extensions]
diff --git a/test/src/register_types.cpp b/test/src/register_types.cpp
index 58080d20..4da8c731 100644
--- a/test/src/register_types.cpp
+++ b/test/src/register_types.cpp
@@ -14,9 +14,19 @@
#include "example.h"
#include "tests.h"
+#if defined(TOOLS_ENABLED) || defined(DEBUG_ENABLED)
+#include "doc_data.gen.h"
+#endif
+
using namespace godot;
void initialize_example_module(ModuleInitializationLevel p_level) {
+#if defined(TOOLS_ENABLED) || defined(DEBUG_ENABLED)
+ if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
+ internal::gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len(reinterpret_cast(_doc_data_uncompressed), _doc_data_uncompressed_size);
+ }
+#endif
+
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
diff --git a/tools/godotcpp.py b/tools/godotcpp.py
index 0b02eea2..15fe187e 100644
--- a/tools/godotcpp.py
+++ b/tools/godotcpp.py
@@ -209,6 +209,38 @@ def options(opts, env):
target_tool.options(opts)
+def make_doc_header(target, source, env):
+ dst = str(target[0])
+ g = open(dst, "w", encoding="utf-8")
+ buf = ""
+ docbegin = ""
+ docend = ""
+ for src in source:
+ src_path = str(src)
+ if not src_path.endswith(".xml"):
+ continue
+ with open(src_path, "r", encoding="utf-8") as f:
+ content = f.read()
+ buf += content
+
+ buf = (docbegin + buf + docend).encode("utf-8")
+ decomp_size = len(buf)
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _GODOT_CPP_DOC_DATA_RAW_H\n")
+ g.write("#define _GODOT_CPP_DOC_DATA_RAW_H\n")
+ g.write('static const char *_doc_data_hash = "' + str(hash(buf)) + '";\n')
+ g.write("static const int _doc_data_uncompressed_size = " + str(decomp_size) + ";\n")
+ g.write("static const unsigned char _doc_data_uncompressed[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + str(buf[i]) + ",\n")
+ g.write("};\n")
+
+ g.write("#endif")
+
+ g.close()
+
+
def generate(env):
# Default num_jobs to local cpu count if not user specified.
# SCons has a peculiarity where user-specified options won't be overridden
@@ -317,6 +349,7 @@ def generate(env):
# Builders
env.Append(BUILDERS={"GodotCPPBindings": Builder(action=scons_generate_bindings, emitter=scons_emit_files)})
+ env.Append(BUILDERS={"GodotCPPDocHeader": Builder(action=make_doc_header)})
env.AddMethod(_godot_cpp, "GodotCPP")