summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--README.md2
-rw-r--r--binding_generator.py27
-rw-r--r--gdextension/extension_api.json401
-rw-r--r--gdextension/gdextension_interface.h107
-rw-r--r--include/godot_cpp/classes/wrapped.hpp5
-rw-r--r--include/godot_cpp/core/class_db.hpp20
-rw-r--r--include/godot_cpp/core/method_bind.hpp2
-rw-r--r--include/godot_cpp/godot.hpp10
-rw-r--r--include/godot_cpp/templates/local_vector.hpp4
-rw-r--r--include/godot_cpp/variant/aabb.hpp2
-rw-r--r--include/godot_cpp/variant/rect2.hpp14
-rw-r--r--include/godot_cpp/variant/rect2i.hpp14
-rw-r--r--include/godot_cpp/variant/vector2.hpp10
-rw-r--r--include/godot_cpp/variant/vector2i.hpp11
-rw-r--r--include/godot_cpp/variant/vector3.hpp11
-rw-r--r--include/godot_cpp/variant/vector3i.hpp11
-rw-r--r--include/godot_cpp/variant/vector4.hpp11
-rw-r--r--include/godot_cpp/variant/vector4i.hpp11
-rw-r--r--src/core/class_db.cpp18
-rw-r--r--src/godot.cpp58
-rw-r--r--src/variant/packed_arrays.cpp19
-rw-r--r--src/variant/vector2.cpp12
-rw-r--r--src/variant/vector2i.cpp18
-rw-r--r--src/variant/vector3.cpp19
-rw-r--r--src/variant/vector3i.cpp21
-rw-r--r--src/variant/vector4.cpp21
-rw-r--r--src/variant/vector4i.cpp24
-rw-r--r--test/SConstruct4
-rw-r--r--test/doc_classes/Example.xml25
-rw-r--r--test/project/main.gd3
-rw-r--r--test/project/project.godot2
-rw-r--r--test/src/example.cpp7
-rw-r--r--test/src/example.h2
-rw-r--r--tools/godotcpp.py48
35 files changed, 920 insertions, 56 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8925852..08a9228 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -173,7 +173,7 @@ jobs:
./godot-artifacts/godot.linuxbsd.editor.x86_64.mono --headless --version
cd test
# Need to run the editor so .godot is generated... but it crashes! Ignore that :-)
- (cd project && (timeout 10 ../../godot-artifacts/godot.linuxbsd.editor.x86_64.mono --editor --headless --quit >/dev/null 2>&1 || true))
+ (cd project && (timeout 30 ../../godot-artifacts/godot.linuxbsd.editor.x86_64.mono --import --headless >/dev/null 2>&1 || true))
GODOT=../godot-artifacts/godot.linuxbsd.editor.x86_64.mono ./run-tests.sh
- name: Upload artifact
diff --git a/README.md b/README.md
index ca9a738..c96e466 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ This repository contains the *C++ bindings* for the [**Godot Engine**](https://
- [**Compatibility**](#compatibility)
- [**Contributing**](#contributing)
- [**Getting started**](#getting-started)
-- [**Included example**](#included-example)
+- [**Examples and templates**](#examples-and-templates)
## Versioning
diff --git a/binding_generator.py b/binding_generator.py
index 972cbf9..71d9e6b 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -545,6 +545,8 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append("#include <godot_cpp/variant/vector2.hpp>")
if class_name == "PackedVector3Array":
result.append("#include <godot_cpp/variant/vector3.hpp>")
+ if class_name == "PackedVector4Array":
+ result.append("#include <godot_cpp/variant/vector4.hpp>")
if is_packed_array(class_name):
result.append("#include <godot_cpp/core/error_macros.hpp>")
@@ -1504,6 +1506,10 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
result.append(f"\tGDEXTENSION_CLASS({class_name}, {inherits})")
result.append("")
+ if is_singleton:
+ result.append(f"\tstatic {class_name} *singleton;")
+ result.append("")
+
result.append("public:")
result.append("")
@@ -1584,6 +1590,11 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
result.append("\t}")
result.append("")
+
+ if is_singleton:
+ result.append(f"\t~{class_name}();")
+ result.append("")
+
result.append("public:")
# Special cases.
@@ -1733,6 +1744,7 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result.append(f"#include <godot_cpp/classes/{snake_class_name}.hpp>")
result.append("")
+ result.append("#include <godot_cpp/core/class_db.hpp>")
result.append("#include <godot_cpp/core/engine_ptrcall.hpp>")
result.append("#include <godot_cpp/core/error_macros.hpp>")
result.append("")
@@ -1747,9 +1759,10 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result.append("")
if is_singleton:
+ result.append(f"{class_name} *{class_name}::singleton = nullptr;")
+ result.append("")
result.append(f"{class_name} *{class_name}::get_singleton() {{")
# We assume multi-threaded access is OK because each assignment will assign the same value every time
- result.append(f"\tstatic {class_name} *singleton = nullptr;")
result.append("\tif (unlikely(singleton == nullptr)) {")
result.append(
f"\t\tGDExtensionObjectPtr singleton_obj = internal::gdextension_interface_global_get_singleton({class_name}::get_class_static()._native_ptr());"
@@ -1763,11 +1776,22 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result.append("#ifdef DEBUG_ENABLED")
result.append("\t\tERR_FAIL_NULL_V(singleton, nullptr);")
result.append("#endif // DEBUG_ENABLED")
+ result.append("\t\tif (likely(singleton)) {")
+ result.append(f"\t\t\tClassDB::_register_engine_singleton({class_name}::get_class_static(), singleton);")
+ result.append("\t\t}")
result.append("\t}")
result.append("\treturn singleton;")
result.append("}")
result.append("")
+ result.append(f"{class_name}::~{class_name}() {{")
+ result.append("\tif (singleton == this) {")
+ result.append(f"\t\tClassDB::_unregister_engine_singleton({class_name}::get_class_static());")
+ result.append("\t\tsingleton = nullptr;")
+ result.append("\t}")
+ result.append("}")
+ result.append("")
+
if "methods" in class_api:
for method in class_api["methods"]:
if method["is_virtual"]:
@@ -2445,6 +2469,7 @@ def is_packed_array(type_name):
"PackedStringArray",
"PackedVector2Array",
"PackedVector3Array",
+ "PackedVector4Array",
]
diff --git a/gdextension/extension_api.json b/gdextension/extension_api.json
index cfd5ebe..ca9d02b 100644
--- a/gdextension/extension_api.json
+++ b/gdextension/extension_api.json
@@ -164,6 +164,10 @@
"size": 8
},
{
+ "name": "PackedVector4Array",
+ "size": 8
+ },
+ {
"name": "Variant",
"size": 24
}
@@ -325,6 +329,10 @@
"size": 16
},
{
+ "name": "PackedVector4Array",
+ "size": 16
+ },
+ {
"name": "Variant",
"size": 24
}
@@ -486,6 +494,10 @@
"size": 8
},
{
+ "name": "PackedVector4Array",
+ "size": 8
+ },
+ {
"name": "Variant",
"size": 40
}
@@ -647,6 +659,10 @@
"size": 16
},
{
+ "name": "PackedVector4Array",
+ "size": 16
+ },
+ {
"name": "Variant",
"size": 40
}
@@ -3932,8 +3948,12 @@
"value": 37
},
{
- "name": "TYPE_MAX",
+ "name": "TYPE_PACKED_VECTOR4_ARRAY",
"value": 38
+ },
+ {
+ "name": "TYPE_MAX",
+ "value": 39
}
]
},
@@ -6292,6 +6312,16 @@
"name": "!=",
"right_type": "PackedColorArray",
"return_type": "bool"
+ },
+ {
+ "name": "==",
+ "right_type": "PackedVector4Array",
+ "return_type": "bool"
+ },
+ {
+ "name": "!=",
+ "right_type": "PackedVector4Array",
+ "return_type": "bool"
}
],
"constructors": [
@@ -7445,6 +7475,11 @@
"name": "%",
"right_type": "PackedColorArray",
"return_type": "String"
+ },
+ {
+ "name": "%",
+ "right_type": "PackedVector4Array",
+ "return_type": "String"
}
],
"methods": [
@@ -12334,6 +12369,11 @@
"name": "in",
"right_type": "Array",
"return_type": "bool"
+ },
+ {
+ "name": "in",
+ "right_type": "PackedVector4Array",
+ "return_type": "bool"
}
],
"methods": [
@@ -17144,6 +17184,11 @@
"name": "%",
"right_type": "PackedColorArray",
"return_type": "String"
+ },
+ {
+ "name": "%",
+ "right_type": "PackedVector4Array",
+ "return_type": "String"
}
],
"methods": [
@@ -19972,6 +20017,15 @@
"type": "PackedColorArray"
}
]
+ },
+ {
+ "index": 12,
+ "arguments": [
+ {
+ "name": "from",
+ "type": "PackedVector4Array"
+ }
+ ]
}
],
"has_destructor": true
@@ -23636,6 +23690,351 @@
}
],
"has_destructor": true
+ },
+ {
+ "name": "PackedVector4Array",
+ "indexing_return_type": "Vector4",
+ "is_keyed": false,
+ "operators": [
+ {
+ "name": "==",
+ "right_type": "Variant",
+ "return_type": "bool"
+ },
+ {
+ "name": "!=",
+ "right_type": "Variant",
+ "return_type": "bool"
+ },
+ {
+ "name": "not",
+ "return_type": "bool"
+ },
+ {
+ "name": "in",
+ "right_type": "Dictionary",
+ "return_type": "bool"
+ },
+ {
+ "name": "in",
+ "right_type": "Array",
+ "return_type": "bool"
+ },
+ {
+ "name": "==",
+ "right_type": "PackedVector4Array",
+ "return_type": "bool"
+ },
+ {
+ "name": "!=",
+ "right_type": "PackedVector4Array",
+ "return_type": "bool"
+ },
+ {
+ "name": "+",
+ "right_type": "PackedVector4Array",
+ "return_type": "PackedVector4Array"
+ }
+ ],
+ "methods": [
+ {
+ "name": "size",
+ "return_type": "int",
+ "is_vararg": false,
+ "is_const": true,
+ "is_static": false,
+ "hash": 3173160232
+ },
+ {
+ "name": "is_empty",
+ "return_type": "bool",
+ "is_vararg": false,
+ "is_const": true,
+ "is_static": false,
+ "hash": 3918633141
+ },
+ {
+ "name": "set",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 1350366223,
+ "arguments": [
+ {
+ "name": "index",
+ "type": "int"
+ },
+ {
+ "name": "value",
+ "type": "Vector4"
+ }
+ ]
+ },
+ {
+ "name": "push_back",
+ "return_type": "bool",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 3289167688,
+ "arguments": [
+ {
+ "name": "value",
+ "type": "Vector4"
+ }
+ ]
+ },
+ {
+ "name": "append",
+ "return_type": "bool",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 3289167688,
+ "arguments": [
+ {
+ "name": "value",
+ "type": "Vector4"
+ }
+ ]
+ },
+ {
+ "name": "append_array",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 537428395,
+ "arguments": [
+ {
+ "name": "array",
+ "type": "PackedVector4Array"
+ }
+ ]
+ },
+ {
+ "name": "remove_at",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 2823966027,
+ "arguments": [
+ {
+ "name": "index",
+ "type": "int"
+ }
+ ]
+ },
+ {
+ "name": "insert",
+ "return_type": "int",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 11085009,
+ "arguments": [
+ {
+ "name": "at_index",
+ "type": "int"
+ },
+ {
+ "name": "value",
+ "type": "Vector4"
+ }
+ ]
+ },
+ {
+ "name": "fill",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 3761353134,
+ "arguments": [
+ {
+ "name": "value",
+ "type": "Vector4"
+ }
+ ]
+ },
+ {
+ "name": "resize",
+ "return_type": "int",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 848867239,
+ "arguments": [
+ {
+ "name": "new_size",
+ "type": "int"
+ }
+ ]
+ },
+ {
+ "name": "clear",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 3218959716
+ },
+ {
+ "name": "has",
+ "return_type": "bool",
+ "is_vararg": false,
+ "is_const": true,
+ "is_static": false,
+ "hash": 88913544,
+ "arguments": [
+ {
+ "name": "value",
+ "type": "Vector4"
+ }
+ ]
+ },
+ {
+ "name": "reverse",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 3218959716
+ },
+ {
+ "name": "slice",
+ "return_type": "PackedVector4Array",
+ "is_vararg": false,
+ "is_const": true,
+ "is_static": false,
+ "hash": 2942803855,
+ "arguments": [
+ {
+ "name": "begin",
+ "type": "int"
+ },
+ {
+ "name": "end",
+ "type": "int",
+ "default_value": "2147483647"
+ }
+ ]
+ },
+ {
+ "name": "to_byte_array",
+ "return_type": "PackedByteArray",
+ "is_vararg": false,
+ "is_const": true,
+ "is_static": false,
+ "hash": 247621236
+ },
+ {
+ "name": "sort",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 3218959716
+ },
+ {
+ "name": "bsearch",
+ "return_type": "int",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 735671678,
+ "arguments": [
+ {
+ "name": "value",
+ "type": "Vector4"
+ },
+ {
+ "name": "before",
+ "type": "bool",
+ "default_value": "true"
+ }
+ ]
+ },
+ {
+ "name": "duplicate",
+ "return_type": "PackedVector4Array",
+ "is_vararg": false,
+ "is_const": false,
+ "is_static": false,
+ "hash": 3186305013
+ },
+ {
+ "name": "find",
+ "return_type": "int",
+ "is_vararg": false,
+ "is_const": true,
+ "is_static": false,
+ "hash": 3091171314,
+ "arguments": [
+ {
+ "name": "value",
+ "type": "Vector4"
+ },
+ {
+ "name": "from",
+ "type": "int",
+ "default_value": "0"
+ }
+ ]
+ },
+ {
+ "name": "rfind",
+ "return_type": "int",
+ "is_vararg": false,
+ "is_const": true,
+ "is_static": false,
+ "hash": 3091171314,
+ "arguments": [
+ {
+ "name": "value",
+ "type": "Vector4"
+ },
+ {
+ "name": "from",
+ "type": "int",
+ "default_value": "-1"
+ }
+ ]
+ },
+ {
+ "name": "count",
+ "return_type": "int",
+ "is_vararg": false,
+ "is_const": true,
+ "is_static": false,
+ "hash": 3956594488,
+ "arguments": [
+ {
+ "name": "value",
+ "type": "Vector4"
+ }
+ ]
+ }
+ ],
+ "constructors": [
+ {
+ "index": 0
+ },
+ {
+ "index": 1,
+ "arguments": [
+ {
+ "name": "from",
+ "type": "PackedVector4Array"
+ }
+ ]
+ },
+ {
+ "index": 2,
+ "arguments": [
+ {
+ "name": "from",
+ "type": "Array"
+ }
+ ]
+ }
+ ],
+ "has_destructor": true
}
],
"classes": [
diff --git a/gdextension/gdextension_interface.h b/gdextension/gdextension_interface.h
index 60ec8d4..2ed31da 100644
--- a/gdextension/gdextension_interface.h
+++ b/gdextension/gdextension_interface.h
@@ -96,6 +96,7 @@ typedef enum {
GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR2_ARRAY,
GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR3_ARRAY,
GDEXTENSION_VARIANT_TYPE_PACKED_COLOR_ARRAY,
+ GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR4_ARRAY,
GDEXTENSION_VARIANT_TYPE_VARIANT_MAX
} GDExtensionVariantType;
@@ -256,6 +257,7 @@ typedef struct {
typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExtensionClassInstancePtr p_instance, uint32_t *r_count);
typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list);
+typedef void (*GDExtensionClassFreePropertyList2)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count);
typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name);
typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
typedef GDExtensionBool (*GDExtensionClassValidateProperty)(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property);
@@ -333,7 +335,7 @@ typedef struct {
GDExtensionClassSet set_func;
GDExtensionClassGet get_func;
GDExtensionClassGetPropertyList get_property_list_func;
- GDExtensionClassFreePropertyList free_property_list_func;
+ GDExtensionClassFreePropertyList2 free_property_list_func;
GDExtensionClassPropertyCanRevert property_can_revert_func;
GDExtensionClassPropertyGetRevert property_get_revert_func;
GDExtensionClassValidateProperty validate_property_func;
@@ -1963,32 +1965,6 @@ typedef uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndex)(GDExtension
typedef const uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
/**
- * @name packed_color_array_operator_index
- * @since 4.1
- *
- * Gets a pointer to a color in a PackedColorArray.
- *
- * @param p_self A pointer to a PackedColorArray object.
- * @param p_index The index of the Color to get.
- *
- * @return A pointer to the requested Color.
- */
-typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index);
-
-/**
- * @name packed_color_array_operator_index_const
- * @since 4.1
- *
- * Gets a const pointer to a color in a PackedColorArray.
- *
- * @param p_self A const pointer to a const PackedColorArray object.
- * @param p_index The index of the Color to get.
- *
- * @return A const pointer to the requested Color.
- */
-typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
-
-/**
* @name packed_float32_array_operator_index
* @since 4.1
*
@@ -2171,6 +2147,58 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndex
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
/**
+ * @name packed_vector4_array_operator_index
+ * @since 4.3
+ *
+ * Gets a pointer to a Vector4 in a PackedVector4Array.
+ *
+ * @param p_self A pointer to a PackedVector4Array object.
+ * @param p_index The index of the Vector4 to get.
+ *
+ * @return A pointer to the requested Vector4.
+ */
+typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector4ArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index);
+
+/**
+ * @name packed_vector4_array_operator_index_const
+ * @since 4.3
+ *
+ * Gets a const pointer to a Vector4 in a PackedVector4Array.
+ *
+ * @param p_self A const pointer to a PackedVector4Array object.
+ * @param p_index The index of the Vector4 to get.
+ *
+ * @return A const pointer to the requested Vector4.
+ */
+typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector4ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
+
+/**
+ * @name packed_color_array_operator_index
+ * @since 4.1
+ *
+ * Gets a pointer to a color in a PackedColorArray.
+ *
+ * @param p_self A pointer to a PackedColorArray object.
+ * @param p_index The index of the Color to get.
+ *
+ * @return A pointer to the requested Color.
+ */
+typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index);
+
+/**
+ * @name packed_color_array_operator_index_const
+ * @since 4.1
+ *
+ * Gets a const pointer to a color in a PackedColorArray.
+ *
+ * @param p_self A const pointer to a PackedColorArray object.
+ * @param p_index The index of the Color to get.
+ *
+ * @return A const pointer to the requested Color.
+ */
+typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
+
+/**
* @name array_operator_index
* @since 4.1
*
@@ -2835,6 +2863,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 a 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 a 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/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp
index ce8c968..ceed378 100644
--- a/include/godot_cpp/classes/wrapped.hpp
+++ b/include/godot_cpp/classes/wrapped.hpp
@@ -78,7 +78,7 @@ protected:
static GDExtensionBool set_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value) { return false; }
static GDExtensionBool get_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
static const GDExtensionPropertyInfo *get_property_list_bind(GDExtensionClassInstancePtr p_instance, uint32_t *r_count) { return nullptr; }
- static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) {}
+ static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count) {}
static GDExtensionBool property_can_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name) { return false; }
static GDExtensionBool property_get_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
static GDExtensionBool validate_property_bind(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property) { return false; }
@@ -292,11 +292,10 @@ public:
return ::godot::internal::create_c_property_list(plist_cpp, r_count); \
} \
\
- static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) { \
+ static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count) { \
if (p_instance) { \
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
cls->plist_owned.clear(); \
- /* TODO `GDExtensionClassFreePropertyList` is ill-defined, we need a non-const pointer to free this. */ \
::godot::internal::free_c_property_list(const_cast<GDExtensionPropertyInfo *>(p_list)); \
} \
} \
diff --git a/include/godot_cpp/core/class_db.hpp b/include/godot_cpp/core/class_db.hpp
index 31ebddc..8ef7f8e 100644
--- a/include/godot_cpp/core/class_db.hpp
+++ b/include/godot_cpp/core/class_db.hpp
@@ -45,6 +45,7 @@
#include <godot_cpp/variant/callable_method_pointer.hpp>
#include <list>
+#include <mutex>
#include <set>
#include <string>
#include <unordered_map>
@@ -104,6 +105,8 @@ private:
static std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *> instance_binding_callbacks;
// Used to remember the custom class registration order.
static std::vector<StringName> class_register_order;
+ static std::unordered_map<StringName, Object *> engine_singletons;
+ static std::mutex engine_singletons_mutex;
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const void **p_defs, int p_defcount);
static void initialize_class(const ClassInfo &cl);
@@ -153,6 +156,21 @@ public:
instance_binding_callbacks[p_name] = p_callbacks;
}
+ 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);
+ if (i != engine_singletons.end()) {
+ ERR_FAIL_COND((*i).second != p_singleton);
+ return;
+ }
+ engine_singletons[p_class_name] = p_singleton;
+ }
+
+ static void _unregister_engine_singleton(const StringName &p_class_name) {
+ std::lock_guard<std::mutex> lock(engine_singletons_mutex);
+ engine_singletons.erase(p_class_name);
+ }
+
template <typename N, typename M, typename... VarArgs>
static MethodBind *bind_method(N p_method_name, M p_method, VarArgs... p_args);
@@ -229,7 +247,7 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
T::set_bind, // GDExtensionClassSet set_func;
T::get_bind, // GDExtensionClassGet get_func;
T::has_get_property_list() ? T::get_property_list_bind : nullptr, // GDExtensionClassGetPropertyList get_property_list_func;
- T::free_property_list_bind, // GDExtensionClassFreePropertyList free_property_list_func;
+ T::free_property_list_bind, // GDExtensionClassFreePropertyList2 free_property_list_func;
T::property_can_revert_bind, // GDExtensionClassPropertyCanRevert property_can_revert_func;
T::property_get_revert_bind, // GDExtensionClassPropertyGetRevert property_get_revert_func;
T::validate_property_bind, // GDExtensionClassValidateProperty validate_property_func;
diff --git a/include/godot_cpp/core/method_bind.hpp b/include/godot_cpp/core/method_bind.hpp
index 4afd7b8..eabd6ec 100644
--- a/include/godot_cpp/core/method_bind.hpp
+++ b/include/godot_cpp/core/method_bind.hpp
@@ -412,6 +412,7 @@ public:
method = p_method;
generate_argument_types(sizeof...(P));
set_argument_count(sizeof...(P));
+ set_const(true);
}
};
@@ -578,6 +579,7 @@ public:
generate_argument_types(sizeof...(P));
set_argument_count(sizeof...(P));
set_return(true);
+ set_const(true);
}
};
diff --git a/include/godot_cpp/godot.hpp b/include/godot_cpp/godot.hpp
index 5a62930..822363d 100644
--- a/include/godot_cpp/godot.hpp
+++ b/include/godot_cpp/godot.hpp
@@ -148,6 +148,8 @@ extern "C" GDExtensionInterfacePackedVector2ArrayOperatorIndex gdextension_inter
extern "C" GDExtensionInterfacePackedVector2ArrayOperatorIndexConst gdextension_interface_packed_vector2_array_operator_index_const;
extern "C" GDExtensionInterfacePackedVector3ArrayOperatorIndex gdextension_interface_packed_vector3_array_operator_index;
extern "C" GDExtensionInterfacePackedVector3ArrayOperatorIndexConst gdextension_interface_packed_vector3_array_operator_index_const;
+extern "C" GDExtensionInterfacePackedVector4ArrayOperatorIndex gdextension_interface_packed_vector4_array_operator_index;
+extern "C" GDExtensionInterfacePackedVector4ArrayOperatorIndexConst gdextension_interface_packed_vector4_array_operator_index_const;
extern "C" GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index;
extern "C" GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const;
extern "C" GDExtensionInterfaceArrayRef gdextension_interface_array_ref;
@@ -160,6 +162,7 @@ extern "C" GDExtensionInterfaceObjectDestroy gdextension_interface_object_destro
extern "C" GDExtensionInterfaceGlobalGetSingleton gdextension_interface_global_get_singleton;
extern "C" GDExtensionInterfaceObjectGetInstanceBinding gdextension_interface_object_get_instance_binding;
extern "C" GDExtensionInterfaceObjectSetInstanceBinding gdextension_interface_object_set_instance_binding;
+extern "C" GDExtensionInterfaceObjectFreeInstanceBinding gdextension_interface_object_free_instance_binding;
extern "C" GDExtensionInterfaceObjectSetInstance gdextension_interface_object_set_instance;
extern "C" GDExtensionInterfaceObjectGetClassName gdextension_interface_object_get_class_name;
extern "C" GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to;
@@ -190,6 +193,13 @@ 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;
+
+class DocDataRegistration {
+public:
+ DocDataRegistration(const char *p_hash, int p_uncompressed_size, int p_compressed_size, const unsigned char *p_data);
+};
} // namespace internal
diff --git a/include/godot_cpp/templates/local_vector.hpp b/include/godot_cpp/templates/local_vector.hpp
index 5dad32e..10af2a9 100644
--- a/include/godot_cpp/templates/local_vector.hpp
+++ b/include/godot_cpp/templates/local_vector.hpp
@@ -257,6 +257,10 @@ public:
return -1;
}
+ bool has(const T &p_val) const {
+ return find(p_val) != -1;
+ }
+
template <typename C>
void sort_custom() {
U len = count;
diff --git a/include/godot_cpp/variant/aabb.hpp b/include/godot_cpp/variant/aabb.hpp
index f344f2c..b827112 100644
--- a/include/godot_cpp/variant/aabb.hpp
+++ b/include/godot_cpp/variant/aabb.hpp
@@ -103,7 +103,7 @@ struct _NO_DISCARD_ AABB {
_FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */
_FORCE_INLINE_ AABB abs() const {
- return AABB(Vector3(position.x + MIN(size.x, (real_t)0), position.y + MIN(size.y, (real_t)0), position.z + MIN(size.z, (real_t)0)), size.abs());
+ return AABB(position + size.minf(0), size.abs());
}
Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const;
diff --git a/include/godot_cpp/variant/rect2.hpp b/include/godot_cpp/variant/rect2.hpp
index c37134d..e643035 100644
--- a/include/godot_cpp/variant/rect2.hpp
+++ b/include/godot_cpp/variant/rect2.hpp
@@ -154,14 +154,12 @@ struct _NO_DISCARD_ Rect2 {
return Rect2();
}
- new_rect.position.x = Math::max(p_rect.position.x, position.x);
- new_rect.position.y = Math::max(p_rect.position.y, position.y);
+ new_rect.position = p_rect.position.max(position);
Point2 p_rect_end = p_rect.position + p_rect.size;
Point2 end = position + size;
- new_rect.size.x = Math::min(p_rect_end.x, end.x) - new_rect.position.x;
- new_rect.size.y = Math::min(p_rect_end.y, end.y) - new_rect.position.y;
+ new_rect.size = p_rect_end.min(end) - new_rect.position;
return new_rect;
}
@@ -174,11 +172,9 @@ struct _NO_DISCARD_ Rect2 {
#endif
Rect2 new_rect;
- new_rect.position.x = Math::min(p_rect.position.x, position.x);
- new_rect.position.y = Math::min(p_rect.position.y, position.y);
+ new_rect.position = p_rect.position.min(position);
- new_rect.size.x = Math::max(p_rect.position.x + p_rect.size.x, position.x + size.x);
- new_rect.size.y = Math::max(p_rect.position.y + p_rect.size.y, position.y + size.y);
+ new_rect.size = (p_rect.position + p_rect.size).max(position + size);
new_rect.size = new_rect.size - new_rect.position; // Make relative again.
@@ -284,7 +280,7 @@ struct _NO_DISCARD_ Rect2 {
}
_FORCE_INLINE_ Rect2 abs() const {
- return Rect2(Point2(position.x + Math::min(size.x, (real_t)0), position.y + Math::min(size.y, (real_t)0)), size.abs());
+ return Rect2(position + size.minf(0), size.abs());
}
Vector2 get_support(const Vector2 &p_normal) const {
diff --git a/include/godot_cpp/variant/rect2i.hpp b/include/godot_cpp/variant/rect2i.hpp
index c2a15ac..eff4958 100644
--- a/include/godot_cpp/variant/rect2i.hpp
+++ b/include/godot_cpp/variant/rect2i.hpp
@@ -97,14 +97,12 @@ struct _NO_DISCARD_ Rect2i {
return Rect2i();
}
- new_rect.position.x = Math::max(p_rect.position.x, position.x);
- new_rect.position.y = Math::max(p_rect.position.y, position.y);
+ new_rect.position = p_rect.position.max(position);
Point2i p_rect_end = p_rect.position + p_rect.size;
Point2i end = position + size;
- new_rect.size.x = Math::min(p_rect_end.x, end.x) - new_rect.position.x;
- new_rect.size.y = Math::min(p_rect_end.y, end.y) - new_rect.position.y;
+ new_rect.size = p_rect_end.min(end) - new_rect.position;
return new_rect;
}
@@ -117,11 +115,9 @@ struct _NO_DISCARD_ Rect2i {
#endif
Rect2i new_rect;
- new_rect.position.x = Math::min(p_rect.position.x, position.x);
- new_rect.position.y = Math::min(p_rect.position.y, position.y);
+ new_rect.position = p_rect.position.min(position);
- new_rect.size.x = Math::max(p_rect.position.x + p_rect.size.x, position.x + size.x);
- new_rect.size.y = Math::max(p_rect.position.y + p_rect.size.y, position.y + size.y);
+ new_rect.size = (p_rect.position + p_rect.size).max(position + size);
new_rect.size = new_rect.size - new_rect.position; // Make relative again.
@@ -219,7 +215,7 @@ struct _NO_DISCARD_ Rect2i {
}
_FORCE_INLINE_ Rect2i abs() const {
- return Rect2i(Point2i(position.x + Math::min(size.x, 0), position.y + Math::min(size.y, 0)), size.abs());
+ return Rect2i(position + size.mini(0), size.abs());
}
_FORCE_INLINE_ void set_end(const Vector2i &p_end) {
diff --git a/include/godot_cpp/variant/vector2.hpp b/include/godot_cpp/variant/vector2.hpp
index fe4d05a..8f08985 100644
--- a/include/godot_cpp/variant/vector2.hpp
+++ b/include/godot_cpp/variant/vector2.hpp
@@ -91,10 +91,18 @@ struct _NO_DISCARD_ Vector2 {
return Vector2(MIN(x, p_vector2.x), MIN(y, p_vector2.y));
}
+ Vector2 minf(real_t p_scalar) const {
+ return Vector2(MIN(x, p_scalar), MIN(y, p_scalar));
+ }
+
Vector2 max(const Vector2 &p_vector2) const {
return Vector2(MAX(x, p_vector2.x), MAX(y, p_vector2.y));
}
+ Vector2 maxf(real_t p_scalar) const {
+ return Vector2(MAX(x, p_scalar), MAX(y, p_scalar));
+ }
+
real_t distance_to(const Vector2 &p_vector2) const;
real_t distance_squared_to(const Vector2 &p_vector2) const;
real_t angle_to(const Vector2 &p_vector2) const;
@@ -169,7 +177,9 @@ struct _NO_DISCARD_ Vector2 {
Vector2 ceil() const;
Vector2 round() const;
Vector2 snapped(const Vector2 &p_by) const;
+ Vector2 snappedf(real_t p_by) const;
Vector2 clamp(const Vector2 &p_min, const Vector2 &p_max) const;
+ Vector2 clampf(real_t p_min, real_t p_max) const;
real_t aspect() const { return width / height; }
operator String() const;
diff --git a/include/godot_cpp/variant/vector2i.hpp b/include/godot_cpp/variant/vector2i.hpp
index afeaeea..0d787c3 100644
--- a/include/godot_cpp/variant/vector2i.hpp
+++ b/include/godot_cpp/variant/vector2i.hpp
@@ -83,10 +83,18 @@ struct _NO_DISCARD_ Vector2i {
return Vector2i(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y));
}
+ Vector2i mini(int32_t p_scalar) const {
+ return Vector2i(MIN(x, p_scalar), MIN(y, p_scalar));
+ }
+
Vector2i max(const Vector2i &p_vector2i) const {
return Vector2i(MAX(x, p_vector2i.x), MAX(y, p_vector2i.y));
}
+ Vector2i maxi(int32_t p_scalar) const {
+ return Vector2i(MAX(x, p_scalar), MAX(y, p_scalar));
+ }
+
Vector2i operator+(const Vector2i &p_v) const;
void operator+=(const Vector2i &p_v);
Vector2i operator-(const Vector2i &p_v) const;
@@ -123,7 +131,10 @@ struct _NO_DISCARD_ Vector2i {
real_t aspect() const { return width / (real_t)height; }
Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); }
Vector2i abs() const { return Vector2i(Math::abs(x), Math::abs(y)); }
+ Vector2i snapped(const Vector2i &p_step) const;
+ Vector2i snappedi(int32_t p_step) const;
Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const;
+ Vector2i clampi(int32_t p_min, int32_t p_max) const;
operator String() const;
operator Vector2() const;
diff --git a/include/godot_cpp/variant/vector3.hpp b/include/godot_cpp/variant/vector3.hpp
index 1107bca..f256c38 100644
--- a/include/godot_cpp/variant/vector3.hpp
+++ b/include/godot_cpp/variant/vector3.hpp
@@ -82,10 +82,18 @@ struct _NO_DISCARD_ Vector3 {
return Vector3(MIN(x, p_vector3.x), MIN(y, p_vector3.y), MIN(z, p_vector3.z));
}
+ Vector3 minf(real_t p_scalar) const {
+ return Vector3(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar));
+ }
+
Vector3 max(const Vector3 &p_vector3) const {
return Vector3(MAX(x, p_vector3.x), MAX(y, p_vector3.y), MAX(z, p_vector3.z));
}
+ Vector3 maxf(real_t p_scalar) const {
+ return Vector3(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar));
+ }
+
_FORCE_INLINE_ real_t length() const;
_FORCE_INLINE_ real_t length_squared() const;
@@ -98,7 +106,9 @@ struct _NO_DISCARD_ Vector3 {
_FORCE_INLINE_ void zero();
void snap(const Vector3 p_val);
+ void snapf(real_t p_val);
Vector3 snapped(const Vector3 p_val) const;
+ Vector3 snappedf(real_t p_val) const;
void rotate(const Vector3 &p_axis, const real_t p_angle);
Vector3 rotated(const Vector3 &p_axis, const real_t p_angle) const;
@@ -128,6 +138,7 @@ struct _NO_DISCARD_ Vector3 {
_FORCE_INLINE_ Vector3 ceil() const;
_FORCE_INLINE_ Vector3 round() const;
Vector3 clamp(const Vector3 &p_min, const Vector3 &p_max) const;
+ Vector3 clampf(real_t p_min, real_t p_max) const;
_FORCE_INLINE_ real_t distance_to(const Vector3 &p_to) const;
_FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_to) const;
diff --git a/include/godot_cpp/variant/vector3i.hpp b/include/godot_cpp/variant/vector3i.hpp
index ae5148f..b2cdbbd 100644
--- a/include/godot_cpp/variant/vector3i.hpp
+++ b/include/godot_cpp/variant/vector3i.hpp
@@ -75,10 +75,18 @@ struct _NO_DISCARD_ Vector3i {
return Vector3i(MIN(x, p_vector3i.x), MIN(y, p_vector3i.y), MIN(z, p_vector3i.z));
}
+ Vector3i mini(int32_t p_scalar) const {
+ return Vector3i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar));
+ }
+
Vector3i max(const Vector3i &p_vector3i) const {
return Vector3i(MAX(x, p_vector3i.x), MAX(y, p_vector3i.y), MAX(z, p_vector3i.z));
}
+ Vector3i maxi(int32_t p_scalar) const {
+ return Vector3i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar));
+ }
+
_FORCE_INLINE_ int64_t length_squared() const;
_FORCE_INLINE_ double length() const;
@@ -89,7 +97,10 @@ struct _NO_DISCARD_ Vector3i {
_FORCE_INLINE_ Vector3i abs() const;
_FORCE_INLINE_ Vector3i sign() const;
+ Vector3i snapped(const Vector3i &p_step) const;
+ Vector3i snappedi(int32_t p_step) const;
Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const;
+ Vector3i clampi(int32_t p_min, int32_t p_max) const;
/* Operators */
diff --git a/include/godot_cpp/variant/vector4.hpp b/include/godot_cpp/variant/vector4.hpp
index b20915a..866e522 100644
--- a/include/godot_cpp/variant/vector4.hpp
+++ b/include/godot_cpp/variant/vector4.hpp
@@ -74,10 +74,18 @@ struct _NO_DISCARD_ Vector4 {
return Vector4(MIN(x, p_vector4.x), MIN(y, p_vector4.y), MIN(z, p_vector4.z), MIN(w, p_vector4.w));
}
+ Vector4 minf(real_t p_scalar) const {
+ return Vector4(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar));
+ }
+
Vector4 max(const Vector4 &p_vector4) const {
return Vector4(MAX(x, p_vector4.x), MAX(y, p_vector4.y), MAX(z, p_vector4.z), MAX(w, p_vector4.w));
}
+ Vector4 maxf(real_t p_scalar) const {
+ return Vector4(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar));
+ }
+
_FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Vector4 &p_vec4) const;
bool is_zero_approx() const;
@@ -103,8 +111,11 @@ struct _NO_DISCARD_ Vector4 {
Vector4 posmod(const real_t p_mod) const;
Vector4 posmodv(const Vector4 &p_modv) const;
void snap(const Vector4 &p_step);
+ void snapf(real_t p_step);
Vector4 snapped(const Vector4 &p_step) const;
+ Vector4 snappedf(real_t p_step) const;
Vector4 clamp(const Vector4 &p_min, const Vector4 &p_max) const;
+ Vector4 clampf(real_t p_min, real_t p_max) const;
Vector4 inverse() const;
_FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const;
diff --git a/include/godot_cpp/variant/vector4i.hpp b/include/godot_cpp/variant/vector4i.hpp
index 36f2855..8e9510f 100644
--- a/include/godot_cpp/variant/vector4i.hpp
+++ b/include/godot_cpp/variant/vector4i.hpp
@@ -77,10 +77,18 @@ struct _NO_DISCARD_ Vector4i {
return Vector4i(MIN(x, p_vector4i.x), MIN(y, p_vector4i.y), MIN(z, p_vector4i.z), MIN(w, p_vector4i.w));
}
+ Vector4i mini(int32_t p_scalar) const {
+ return Vector4i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar));
+ }
+
Vector4i max(const Vector4i &p_vector4i) const {
return Vector4i(MAX(x, p_vector4i.x), MAX(y, p_vector4i.y), MAX(z, p_vector4i.z), MAX(w, p_vector4i.w));
}
+ Vector4i maxi(int32_t p_scalar) const {
+ return Vector4i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar));
+ }
+
_FORCE_INLINE_ int64_t length_squared() const;
_FORCE_INLINE_ double length() const;
@@ -91,7 +99,10 @@ struct _NO_DISCARD_ Vector4i {
_FORCE_INLINE_ Vector4i abs() const;
_FORCE_INLINE_ Vector4i sign() const;
+ Vector4i snapped(const Vector4i &p_step) const;
+ Vector4i snappedi(int32_t p_step) const;
Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const;
+ Vector4i clampi(int32_t p_min, int32_t p_max) const;
/* Operators */
diff --git a/src/core/class_db.cpp b/src/core/class_db.cpp
index acead8b..d9a8bf9 100644
--- a/src/core/class_db.cpp
+++ b/src/core/class_db.cpp
@@ -43,6 +43,8 @@ namespace godot {
std::unordered_map<StringName, ClassDB::ClassInfo> ClassDB::classes;
std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *> ClassDB::instance_binding_callbacks;
std::vector<StringName> ClassDB::class_register_order;
+std::unordered_map<StringName, Object *> ClassDB::engine_singletons;
+std::mutex ClassDB::engine_singletons_mutex;
GDExtensionInitializationLevel ClassDB::current_level = GDEXTENSION_INITIALIZATION_CORE;
MethodDefinition D_METHOD(StringName p_name) {
@@ -419,6 +421,22 @@ void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
});
class_register_order.erase(it, class_register_order.end());
}
+
+ if (p_level == GDEXTENSION_INITIALIZATION_CORE) {
+ // Make a new list of the singleton objects, since freeing the instance bindings will lead to
+ // elements getting removed from engine_singletons.
+ std::vector<Object *> singleton_objects;
+ {
+ std::lock_guard<std::mutex> lock(engine_singletons_mutex);
+ singleton_objects.reserve(engine_singletons.size());
+ for (const std::pair<StringName, Object *> &pair : engine_singletons) {
+ singleton_objects.push_back(pair.second);
+ }
+ }
+ for (std::vector<Object *>::iterator i = singleton_objects.begin(); i != singleton_objects.end(); i++) {
+ internal::gdextension_interface_object_free_instance_binding((*i)->_owner, internal::token);
+ }
+ }
}
} // namespace godot
diff --git a/src/godot.cpp b/src/godot.cpp
index 8a031be..a5cefbf 100644
--- a/src/godot.cpp
+++ b/src/godot.cpp
@@ -154,6 +154,8 @@ GDExtensionInterfacePackedVector2ArrayOperatorIndex gdextension_interface_packed
GDExtensionInterfacePackedVector2ArrayOperatorIndexConst gdextension_interface_packed_vector2_array_operator_index_const = nullptr;
GDExtensionInterfacePackedVector3ArrayOperatorIndex gdextension_interface_packed_vector3_array_operator_index = nullptr;
GDExtensionInterfacePackedVector3ArrayOperatorIndexConst gdextension_interface_packed_vector3_array_operator_index_const = nullptr;
+GDExtensionInterfacePackedVector4ArrayOperatorIndex gdextension_interface_packed_vector4_array_operator_index = nullptr;
+GDExtensionInterfacePackedVector4ArrayOperatorIndexConst gdextension_interface_packed_vector4_array_operator_index_const = nullptr;
GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index = nullptr;
GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const = nullptr;
GDExtensionInterfaceArrayRef gdextension_interface_array_ref = nullptr;
@@ -166,6 +168,7 @@ GDExtensionInterfaceObjectDestroy gdextension_interface_object_destroy = nullptr
GDExtensionInterfaceGlobalGetSingleton gdextension_interface_global_get_singleton = nullptr;
GDExtensionInterfaceObjectGetInstanceBinding gdextension_interface_object_get_instance_binding = nullptr;
GDExtensionInterfaceObjectSetInstanceBinding gdextension_interface_object_set_instance_binding = nullptr;
+GDExtensionInterfaceObjectFreeInstanceBinding gdextension_interface_object_free_instance_binding = nullptr;
GDExtensionInterfaceObjectSetInstance gdextension_interface_object_set_instance = nullptr;
GDExtensionInterfaceObjectGetClassName gdextension_interface_object_get_class_name = nullptr;
GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to = nullptr;
@@ -196,6 +199,38 @@ 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;
+
+struct DocData {
+ const char *hash = nullptr;
+ int uncompressed_size = 0;
+ int compressed_size = 0;
+ const unsigned char *data = nullptr;
+
+ inline bool is_valid() const {
+ return hash != nullptr && uncompressed_size > 0 && compressed_size > 0 && data != nullptr;
+ }
+
+ void load_data() const;
+};
+
+static DocData &get_doc_data() {
+ static DocData doc_data;
+ return doc_data;
+}
+
+DocDataRegistration::DocDataRegistration(const char *p_hash, int p_uncompressed_size, int p_compressed_size, const unsigned char *p_data) {
+ DocData &doc_data = get_doc_data();
+ if (doc_data.is_valid()) {
+ printf("ERROR: Attempting to register documentation data when we already have some - discarding.\n");
+ return;
+ }
+ doc_data.hash = p_hash;
+ doc_data.uncompressed_size = p_uncompressed_size;
+ doc_data.compressed_size = p_compressed_size;
+ doc_data.data = p_data;
+}
} // namespace internal
@@ -394,6 +429,8 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
LOAD_PROC_ADDRESS(packed_vector2_array_operator_index_const, GDExtensionInterfacePackedVector2ArrayOperatorIndexConst);
LOAD_PROC_ADDRESS(packed_vector3_array_operator_index, GDExtensionInterfacePackedVector3ArrayOperatorIndex);
LOAD_PROC_ADDRESS(packed_vector3_array_operator_index_const, GDExtensionInterfacePackedVector3ArrayOperatorIndexConst);
+ LOAD_PROC_ADDRESS(packed_vector4_array_operator_index, GDExtensionInterfacePackedVector4ArrayOperatorIndex);
+ LOAD_PROC_ADDRESS(packed_vector4_array_operator_index_const, GDExtensionInterfacePackedVector4ArrayOperatorIndexConst);
LOAD_PROC_ADDRESS(array_operator_index, GDExtensionInterfaceArrayOperatorIndex);
LOAD_PROC_ADDRESS(array_operator_index_const, GDExtensionInterfaceArrayOperatorIndexConst);
LOAD_PROC_ADDRESS(array_ref, GDExtensionInterfaceArrayRef);
@@ -406,6 +443,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
LOAD_PROC_ADDRESS(global_get_singleton, GDExtensionInterfaceGlobalGetSingleton);
LOAD_PROC_ADDRESS(object_get_instance_binding, GDExtensionInterfaceObjectGetInstanceBinding);
LOAD_PROC_ADDRESS(object_set_instance_binding, GDExtensionInterfaceObjectSetInstanceBinding);
+ LOAD_PROC_ADDRESS(object_free_instance_binding, GDExtensionInterfaceObjectFreeInstanceBinding);
LOAD_PROC_ADDRESS(object_set_instance, GDExtensionInterfaceObjectSetInstance);
LOAD_PROC_ADDRESS(object_get_class_name, GDExtensionInterfaceObjectGetClassName);
LOAD_PROC_ADDRESS(object_cast_to, GDExtensionInterfaceObjectCastTo);
@@ -436,6 +474,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;
@@ -465,6 +505,13 @@ void GDExtensionBinding::initialize_level(void *p_userdata, GDExtensionInitializ
ClassDB::initialize(p_level);
}
level_initialized[p_level]++;
+
+ if ((ModuleInitializationLevel)p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
+ const internal::DocData &doc_data = internal::get_doc_data();
+ if (doc_data.is_valid()) {
+ doc_data.load_data();
+ }
+ }
}
void GDExtensionBinding::deinitialize_level(void *p_userdata, GDExtensionInitializationLevel p_level) {
@@ -531,4 +578,15 @@ GDExtensionBool GDExtensionBinding::InitObject::init() const {
return GDExtensionBinding::init(get_proc_address, library, init_data, initialization);
}
+void internal::DocData::load_data() const {
+ PackedByteArray compressed;
+ compressed.resize(compressed_size);
+ memcpy(compressed.ptrw(), data, compressed_size);
+
+ // FileAccess::COMPRESSION_DEFLATE = 1
+ PackedByteArray decompressed = compressed.decompress(uncompressed_size, 1);
+
+ internal::gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len(reinterpret_cast<const char *>(decompressed.ptr()), uncompressed_size);
+}
+
} // namespace godot
diff --git a/src/variant/packed_arrays.cpp b/src/variant/packed_arrays.cpp
index fe8b359..4384f7a 100644
--- a/src/variant/packed_arrays.cpp
+++ b/src/variant/packed_arrays.cpp
@@ -43,6 +43,7 @@
#include <godot_cpp/variant/packed_string_array.hpp>
#include <godot_cpp/variant/packed_vector2_array.hpp>
#include <godot_cpp/variant/packed_vector3_array.hpp>
+#include <godot_cpp/variant/packed_vector4_array.hpp>
namespace godot {
@@ -198,6 +199,24 @@ Vector3 *PackedVector3Array::ptrw() {
return (Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index((GDExtensionTypePtr *)this, 0);
}
+const Vector4 &PackedVector4Array::operator[](int64_t p_index) const {
+ const Vector4 *vec = (const Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
+ return *vec;
+}
+
+Vector4 &PackedVector4Array::operator[](int64_t p_index) {
+ Vector4 *vec = (Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index((GDExtensionTypePtr *)this, p_index);
+ return *vec;
+}
+
+const Vector4 *PackedVector4Array::ptr() const {
+ return (const Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index_const((GDExtensionTypePtr *)this, 0);
+}
+
+Vector4 *PackedVector4Array::ptrw() {
+ return (Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index((GDExtensionTypePtr *)this, 0);
+}
+
const Variant &Array::operator[](int64_t p_index) const {
const Variant *var = (const Variant *)internal::gdextension_interface_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *var;
diff --git a/src/variant/vector2.cpp b/src/variant/vector2.cpp
index ca1ab8f..12201f1 100644
--- a/src/variant/vector2.cpp
+++ b/src/variant/vector2.cpp
@@ -137,12 +137,24 @@ Vector2 Vector2::clamp(const Vector2 &p_min, const Vector2 &p_max) const {
CLAMP(y, p_min.y, p_max.y));
}
+Vector2 Vector2::clampf(real_t p_min, real_t p_max) const {
+ return Vector2(
+ CLAMP(x, p_min, p_max),
+ CLAMP(y, p_min, p_max));
+}
+
Vector2 Vector2::snapped(const Vector2 &p_step) const {
return Vector2(
Math::snapped(x, p_step.x),
Math::snapped(y, p_step.y));
}
+Vector2 Vector2::snappedf(real_t p_step) const {
+ return Vector2(
+ Math::snapped(x, p_step),
+ Math::snapped(y, p_step));
+}
+
Vector2 Vector2::limit_length(const real_t p_len) const {
const real_t l = length();
Vector2 v = *this;
diff --git a/src/variant/vector2i.cpp b/src/variant/vector2i.cpp
index c1c1ab0..4baff3b 100644
--- a/src/variant/vector2i.cpp
+++ b/src/variant/vector2i.cpp
@@ -35,12 +35,30 @@
namespace godot {
+Vector2i Vector2i::snapped(const Vector2i &p_step) const {
+ return Vector2i(
+ Math::snapped(x, p_step.x),
+ Math::snapped(y, p_step.y));
+}
+
+Vector2i Vector2i::snappedi(int32_t p_step) const {
+ return Vector2i(
+ Math::snapped(x, p_step),
+ Math::snapped(y, p_step));
+}
+
Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const {
return Vector2i(
CLAMP(x, p_min.x, p_max.x),
CLAMP(y, p_min.y, p_max.y));
}
+Vector2i Vector2i::clampi(int32_t p_min, int32_t p_max) const {
+ return Vector2i(
+ CLAMP(x, p_min, p_max),
+ CLAMP(y, p_min, p_max));
+}
+
int64_t Vector2i::length_squared() const {
return x * (int64_t)x + y * (int64_t)y;
}
diff --git a/src/variant/vector3.cpp b/src/variant/vector3.cpp
index 9f04340..d2ad6a9 100644
--- a/src/variant/vector3.cpp
+++ b/src/variant/vector3.cpp
@@ -54,18 +54,37 @@ Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const {
CLAMP(z, p_min.z, p_max.z));
}
+Vector3 Vector3::clampf(real_t p_min, real_t p_max) const {
+ return Vector3(
+ CLAMP(x, p_min, p_max),
+ CLAMP(y, p_min, p_max),
+ CLAMP(z, p_min, p_max));
+}
+
void Vector3::snap(const Vector3 p_step) {
x = Math::snapped(x, p_step.x);
y = Math::snapped(y, p_step.y);
z = Math::snapped(z, p_step.z);
}
+void Vector3::snapf(real_t p_step) {
+ x = Math::snapped(x, p_step);
+ y = Math::snapped(y, p_step);
+ z = Math::snapped(z, p_step);
+}
+
Vector3 Vector3::snapped(const Vector3 p_step) const {
Vector3 v = *this;
v.snap(p_step);
return v;
}
+Vector3 Vector3::snappedf(real_t p_step) const {
+ Vector3 v = *this;
+ v.snapf(p_step);
+ return v;
+}
+
Vector3 Vector3::limit_length(const real_t p_len) const {
const real_t l = length();
Vector3 v = *this;
diff --git a/src/variant/vector3i.cpp b/src/variant/vector3i.cpp
index eef05b8..7b25d89 100644
--- a/src/variant/vector3i.cpp
+++ b/src/variant/vector3i.cpp
@@ -35,6 +35,20 @@
namespace godot {
+Vector3i Vector3i::snapped(const Vector3i &p_step) const {
+ return Vector3i(
+ Math::snapped(x, p_step.x),
+ Math::snapped(y, p_step.y),
+ Math::snapped(z, p_step.z));
+}
+
+Vector3i Vector3i::snappedi(int32_t p_step) const {
+ return Vector3i(
+ Math::snapped(x, p_step),
+ Math::snapped(y, p_step),
+ Math::snapped(z, p_step));
+}
+
Vector3i::Axis Vector3i::min_axis_index() const {
return x < y ? (x < z ? Vector3i::AXIS_X : Vector3i::AXIS_Z) : (y < z ? Vector3i::AXIS_Y : Vector3i::AXIS_Z);
}
@@ -50,6 +64,13 @@ Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const {
CLAMP(z, p_min.z, p_max.z));
}
+Vector3i Vector3i::clampi(int32_t p_min, int32_t p_max) const {
+ return Vector3i(
+ CLAMP(x, p_min, p_max),
+ CLAMP(y, p_min, p_max),
+ CLAMP(z, p_min, p_max));
+}
+
Vector3i::operator String() const {
return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")";
}
diff --git a/src/variant/vector4.cpp b/src/variant/vector4.cpp
index 483545e..2f1bb59 100644
--- a/src/variant/vector4.cpp
+++ b/src/variant/vector4.cpp
@@ -173,12 +173,25 @@ void Vector4::snap(const Vector4 &p_step) {
w = Math::snapped(w, p_step.w);
}
+void Vector4::snapf(real_t p_step) {
+ x = Math::snapped(x, p_step);
+ y = Math::snapped(y, p_step);
+ z = Math::snapped(z, p_step);
+ w = Math::snapped(w, p_step);
+}
+
Vector4 Vector4::snapped(const Vector4 &p_step) const {
Vector4 v = *this;
v.snap(p_step);
return v;
}
+Vector4 Vector4::snappedf(real_t p_step) const {
+ Vector4 v = *this;
+ v.snapf(p_step);
+ return v;
+}
+
Vector4 Vector4::inverse() const {
return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w);
}
@@ -191,6 +204,14 @@ Vector4 Vector4::clamp(const Vector4 &p_min, const Vector4 &p_max) const {
CLAMP(w, p_min.w, p_max.w));
}
+Vector4 Vector4::clampf(real_t p_min, real_t p_max) const {
+ return Vector4(
+ CLAMP(x, p_min, p_max),
+ CLAMP(y, p_min, p_max),
+ CLAMP(z, p_min, p_max),
+ CLAMP(w, p_min, p_max));
+}
+
Vector4::operator String() const {
return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ", " + String::num_real(w, false) + ")";
}
diff --git a/src/variant/vector4i.cpp b/src/variant/vector4i.cpp
index f1817dc..b0e330c 100644
--- a/src/variant/vector4i.cpp
+++ b/src/variant/vector4i.cpp
@@ -35,6 +35,22 @@
namespace godot {
+Vector4i Vector4i::snapped(const Vector4i &p_step) const {
+ return Vector4i(
+ Math::snapped(x, p_step.x),
+ Math::snapped(y, p_step.y),
+ Math::snapped(z, p_step.z),
+ Math::snapped(w, p_step.w));
+}
+
+Vector4i Vector4i::snappedi(int32_t p_step) const {
+ return Vector4i(
+ Math::snapped(x, p_step),
+ Math::snapped(y, p_step),
+ Math::snapped(z, p_step),
+ Math::snapped(w, p_step));
+}
+
Vector4i::Axis Vector4i::min_axis_index() const {
uint32_t min_index = 0;
int32_t min_value = x;
@@ -67,6 +83,14 @@ Vector4i Vector4i::clamp(const Vector4i &p_min, const Vector4i &p_max) const {
CLAMP(w, p_min.w, p_max.w));
}
+Vector4i Vector4i::clampi(int32_t p_min, int32_t p_max) const {
+ return Vector4i(
+ CLAMP(x, p_min, p_max),
+ CLAMP(y, p_min, p_max),
+ CLAMP(z, p_min, p_max),
+ CLAMP(w, p_min, p_max));
+}
+
Vector4i::operator String() const {
return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")";
}
diff --git a/test/SConstruct b/test/SConstruct
index 9c25917..7cb25be 100644
--- a/test/SConstruct
+++ b/test/SConstruct
@@ -16,6 +16,10 @@ env = SConscript("../SConstruct")
env.Append(CPPPATH=["src/"])
sources = Glob("src/*.cpp")
+if env["target"] in ["editor", "template_debug"]:
+ doc_data = env.GodotCPPDocData("src/gen/doc_data.gen.cpp", source=Glob("doc_classes/*.xml"))
+ sources.append(doc_data)
+
if env["platform"] == "macos":
library = env.SharedLibrary(
"project/bin/libgdexample.{}.{}.framework/libgdexample.{}.{}".format(
diff --git a/test/doc_classes/Example.xml b/test/doc_classes/Example.xml
new file mode 100644
index 0000000..457709d
--- /dev/null
+++ b/test/doc_classes/Example.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="Example" inherits="Control" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/godotengine/godot/master/doc/class.xsd">
+ <brief_description>
+ A test control defined in GDExtension.
+ </brief_description>
+ <description>
+ A control used for the automated GDExtension tests.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="simple_func">
+ <return type="void" />
+ <description>
+ Tests a simple function call.
+ </description>
+ </method>
+ </methods>
+ <members>
+ </members>
+ <signals>
+ </signals>
+ <constants>
+ </constants>
+</class>
diff --git a/test/project/main.gd b/test/project/main.gd
index 0cfba19..665582f 100644
--- a/test/project/main.gd
+++ b/test/project/main.gd
@@ -256,6 +256,9 @@ func _ready():
assert_equal(example.test_virtual_implemented_in_script("Virtual", 939), "Implemented")
assert_equal(custom_signal_emitted, ["Virtual", 939])
+ # Test that we can access an engine singleton.
+ assert_equal(example.test_use_engine_singleton(), OS.get_name())
+
# Test that notifications happen on both parent and child classes.
var example_child = $ExampleChild
assert_equal(example_child.get_value1(), 11)
diff --git a/test/project/project.godot b/test/project/project.godot
index 4f51c07..df3dd70 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/example.cpp b/test/src/example.cpp
index 3ec8bca..78d7062 100644
--- a/test/src/example.cpp
+++ b/test/src/example.cpp
@@ -11,6 +11,7 @@
#include <godot_cpp/classes/label.hpp>
#include <godot_cpp/classes/multiplayer_api.hpp>
#include <godot_cpp/classes/multiplayer_peer.hpp>
+#include <godot_cpp/classes/os.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
using namespace godot;
@@ -239,6 +240,8 @@ void Example::_bind_methods() {
GDVIRTUAL_BIND(_do_something_virtual, "name", "value");
ClassDB::bind_method(D_METHOD("test_virtual_implemented_in_script"), &Example::test_virtual_implemented_in_script);
+ ClassDB::bind_method(D_METHOD("test_use_engine_singleton"), &Example::test_use_engine_singleton);
+
ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
ClassDB::bind_static_method("Example", D_METHOD("test_static2"), &Example::test_static2);
@@ -671,6 +674,10 @@ String Example::test_virtual_implemented_in_script(const String &p_name, int p_v
return "Unimplemented";
}
+String Example::test_use_engine_singleton() const {
+ return OS::get_singleton()->get_name();
+}
+
void ExampleRuntime::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_prop_value", "value"), &ExampleRuntime::set_prop_value);
ClassDB::bind_method(D_METHOD("get_prop_value"), &ExampleRuntime::get_prop_value);
diff --git a/test/src/example.h b/test/src/example.h
index 0ad9493..1af4e5f 100644
--- a/test/src/example.h
+++ b/test/src/example.h
@@ -186,6 +186,8 @@ public:
GDVIRTUAL2R(String, _do_something_virtual, String, int);
String test_virtual_implemented_in_script(const String &p_name, int p_value);
+
+ String test_use_engine_singleton() const;
};
VARIANT_ENUM_CAST(Example::Constants);
diff --git a/tools/godotcpp.py b/tools/godotcpp.py
index 13a57e9..2e61e2b 100644
--- a/tools/godotcpp.py
+++ b/tools/godotcpp.py
@@ -325,6 +325,51 @@ def options(opts, env):
tool.options(opts)
+def make_doc_source(target, source, env):
+ import zlib
+
+ 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)
+
+ # Use maximum zlib compression level to further reduce file size
+ # (at the cost of initial build times).
+ buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION)
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("\n")
+ g.write("#include <godot_cpp/godot.hpp>\n")
+ g.write("\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 int _doc_data_compressed_size = " + str(len(buf)) + ";\n")
+ g.write("static const unsigned char _doc_data_compressed[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + str(buf[i]) + ",\n")
+ g.write("};\n")
+ g.write("\n")
+
+ g.write(
+ "static godot::internal::DocDataRegistration _doc_data_registration(_doc_data_hash, _doc_data_uncompressed_size, _doc_data_compressed_size, _doc_data_compressed);\n"
+ )
+ g.write("\n")
+
+ 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
@@ -451,7 +496,8 @@ def generate(env):
# Builders
env.Append(
BUILDERS={
- "GodotCPPBindings": Builder(action=Action(scons_generate_bindings, "$GENCOMSTR"), emitter=scons_emit_files)
+ "GodotCPPBindings": Builder(action=Action(scons_generate_bindings, "$GENCOMSTR"), emitter=scons_emit_files),
+ "GodotCPPDocData": Builder(action=make_doc_source),
}
)
env.AddMethod(_godot_cpp, "GodotCPP")