summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt9
-rw-r--r--binding_generator.py223
-rw-r--r--gdextension/extension_api.json5
-rw-r--r--include/godot_cpp/core/type_info.hpp19
-rw-r--r--include/godot_cpp/templates/safe_refcount.hpp2
-rw-r--r--test/project/main.gd6
-rw-r--r--test/src/example.cpp22
-rw-r--r--test/src/example.h3
-rw-r--r--tools/web.py2
9 files changed, 203 insertions, 88 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9609061..af62675 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -124,10 +124,6 @@ else()
endif()
endif()
-if (GODOT_ENABLE_HOT_RELOAD)
- set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -D HOT_RELOAD_ENABLED")
-endif()
-
# Generate source from the bindings file
find_package(Python3 3.4 REQUIRED) # pathlib should be present
if(GENERATE_TEMPLATE_GET_NODE)
@@ -170,6 +166,11 @@ target_compile_features(${PROJECT_NAME}
cxx_std_17
)
+if(GODOT_ENABLE_HOT_RELOAD)
+ target_compile_definitions(${PROJECT_NAME} PUBLIC HOT_RELOAD_ENABLED)
+ target_compile_options(${PROJECT_NAME} PUBLIC $<${compiler_is_gnu}:-fno-gnu-unique>)
+endif()
+
target_compile_definitions(${PROJECT_NAME} PUBLIC
$<$<CONFIG:Debug>:
DEBUG_ENABLED
diff --git a/binding_generator.py b/binding_generator.py
index e7609b2..71afe04 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -542,8 +542,14 @@ def generate_builtin_bindings(api, output_dir, build_config):
builtin_header.append("")
+ includes = []
for builtin in builtin_classes:
- builtin_header.append(f"#include <godot_cpp/variant/{camel_to_snake(builtin)}.hpp>")
+ includes.append(f"godot_cpp/variant/{camel_to_snake(builtin)}.hpp")
+
+ includes.sort()
+
+ for include in includes:
+ builtin_header.append(f"#include <{include}>")
builtin_header.append("")
@@ -599,11 +605,10 @@ def generate_builtin_class_vararg_method_implements_header(builtin_classes):
continue
result += make_varargs_template(
- method, "is_static" in method and method["is_static"], class_name, False, False, True
+ method, "is_static" in method and method["is_static"], class_name, False, True
)
result.append("")
- result.append("")
result.append(f"#endif // ! {header_guard}")
return "\n".join(result)
@@ -628,38 +633,53 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
# Special cases.
if class_name == "String":
+ result.append("#include <godot_cpp/classes/global_constants.hpp>")
result.append("#include <godot_cpp/variant/char_string.hpp>")
result.append("#include <godot_cpp/variant/char_utils.hpp>")
- result.append("#include <godot_cpp/classes/global_constants.hpp>")
+ result.append("")
if class_name == "PackedStringArray":
result.append("#include <godot_cpp/variant/string.hpp>")
+ result.append("")
if class_name == "PackedColorArray":
result.append("#include <godot_cpp/variant/color.hpp>")
+ result.append("")
if class_name == "PackedVector2Array":
result.append("#include <godot_cpp/variant/vector2.hpp>")
+ result.append("")
if class_name == "PackedVector3Array":
result.append("#include <godot_cpp/variant/vector3.hpp>")
+ result.append("")
if class_name == "PackedVector4Array":
result.append("#include <godot_cpp/variant/vector4.hpp>")
+ result.append("")
if is_packed_array(class_name):
result.append("#include <godot_cpp/core/error_macros.hpp>")
result.append("#include <initializer_list>")
+ result.append("")
if class_name == "Array":
result.append("#include <godot_cpp/variant/array_helpers.hpp>")
+ result.append("")
if class_name == "Callable":
result.append("#include <godot_cpp/variant/callable_custom.hpp>")
-
- for include in fully_used_classes:
- if include == "TypedArray":
- result.append("#include <godot_cpp/variant/typed_array.hpp>")
- else:
- result.append(f"#include <godot_cpp/{get_include_path(include)}>")
+ result.append("")
if len(fully_used_classes) > 0:
+ includes = []
+ for include in fully_used_classes:
+ if include == "TypedArray":
+ includes.append("godot_cpp/variant/typed_array.hpp")
+ else:
+ includes.append(f"godot_cpp/{get_include_path(include)}")
+
+ includes.sort()
+
+ for include in includes:
+ result.append(f"#include <{include}>")
+
result.append("")
result.append("#include <gdextension_interface.h>")
@@ -737,7 +757,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append("public:")
result.append(
- f"\t_FORCE_INLINE_ GDExtensionTypePtr _native_ptr() const {{ return const_cast<uint8_t (*)[{snake_class_name}_SIZE]>(&opaque); }}"
+ f"\t_FORCE_INLINE_ GDExtensionTypePtr _native_ptr() const {{ return const_cast<uint8_t(*)[{snake_class_name}_SIZE]>(&opaque); }}"
)
copy_constructor_index = -1
@@ -852,14 +872,14 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
if "operators" in builtin_api:
for operator in builtin_api["operators"]:
- if operator["name"] not in ["in", "xor"]:
+ if is_valid_cpp_operator(operator["name"]):
if "right_type" in operator:
result.append(
- f'\t{correct_type(operator["return_type"])} operator{operator["name"]}({type_for_parameter(operator["right_type"])}p_other) const;'
+ f'\t{correct_type(operator["return_type"])} operator{get_operator_cpp_name(operator["name"])}({type_for_parameter(operator["right_type"])}p_other) const;'
)
else:
result.append(
- f'\t{correct_type(operator["return_type"])} operator{operator["name"].replace("unary", "")}() const;'
+ f'\t{correct_type(operator["return_type"])} operator{get_operator_cpp_name(operator["name"])}() const;'
)
# Copy assignment.
@@ -918,7 +938,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append(f"\tconst {return_type} *ptr() const;")
result.append(f"\t{return_type} *ptrw();")
iterators = """
- struct Iterator {
+ struct Iterator {
_FORCE_INLINE_ $TYPE &operator*() const {
return *elem_ptr;
}
@@ -980,19 +1000,17 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
}
_FORCE_INLINE_ ConstIterator end() const {
return ConstIterator(ptr() + size());
- }
-"""
+ }"""
result.append(iterators.replace("$TYPE", return_type))
init_list = """
- _FORCE_INLINE_ $CLASS(std::initializer_list<$TYPE> p_init) {
+ _FORCE_INLINE_ $CLASS(std::initializer_list<$TYPE> p_init) {
ERR_FAIL_COND(resize(p_init.size()) != 0);
size_t i = 0;
for (const $TYPE &element : p_init) {
set(i++, element);
}
- }
-"""
+ }"""
result.append(init_list.replace("$TYPE", return_type).replace("$CLASS", class_name))
if class_name == "Array":
@@ -1031,7 +1049,9 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append("")
result.append("} // namespace godot")
+ result.append("")
result.append(f"#endif // ! {header_guard}")
+ result.append("")
return "\n".join(result)
@@ -1045,7 +1065,6 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
add_header(f"{snake_class_name}.cpp", result)
- result.append("")
result.append(f"#include <godot_cpp/variant/{snake_class_name}.hpp>")
result.append("")
result.append("#include <godot_cpp/core/binder_common.hpp>")
@@ -1054,10 +1073,16 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append("")
# Only used since the "fully used" is included in header already.
- for include in used_classes:
- result.append(f"#include <godot_cpp/{get_include_path(include)}>")
-
if len(used_classes) > 0:
+ includes = []
+ for included in used_classes:
+ includes.append(f"godot_cpp/{get_include_path(included)}")
+
+ includes.sort()
+
+ for included in includes:
+ result.append(f"#include <{included}>")
+
result.append("")
result.append("#include <godot_cpp/core/builtin_ptrcall.hpp>")
@@ -1291,10 +1316,10 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
if "operators" in builtin_api:
for operator in builtin_api["operators"]:
- if operator["name"] not in ["in", "xor"]:
+ if is_valid_cpp_operator(operator["name"]):
if "right_type" in operator:
result.append(
- f'{correct_type(operator["return_type"])} {class_name}::operator{operator["name"]}({type_for_parameter(operator["right_type"])}p_other) const {{'
+ f'{correct_type(operator["return_type"])} {class_name}::operator{get_operator_cpp_name(operator["name"])}({type_for_parameter(operator["right_type"])}p_other) const {{'
)
(encode, arg_name) = get_encoded_arg("other", operator["right_type"], None)
result += encode
@@ -1304,10 +1329,10 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append("}")
else:
result.append(
- f'{correct_type(operator["return_type"])} {class_name}::operator{operator["name"].replace("unary", "")}() const {{'
+ f'{correct_type(operator["return_type"])} {class_name}::operator{get_operator_cpp_name(operator["name"])}() const {{'
)
result.append(
- f'\treturn internal::_call_builtin_operator_ptr<{get_gdextension_type(correct_type(operator["return_type"]))}>(_method_bindings.operator_{get_operator_id_name(operator["name"])}, (GDExtensionConstTypePtr)&opaque, (GDExtensionConstTypePtr)nullptr);'
+ f'\treturn internal::_call_builtin_operator_ptr<{get_gdextension_type(correct_type(operator["return_type"]))}>(_method_bindings.operator_{get_operator_id_name(operator["name"])}, (GDExtensionConstTypePtr)&opaque, (GDExtensionConstTypePtr) nullptr);'
)
result.append("}")
result.append("")
@@ -1343,6 +1368,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append("")
result.append("} //namespace godot")
+ result.append("")
return "\n".join(result)
@@ -1518,11 +1544,18 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
result.append("")
- for included in used_classes:
- result.append(f"#include <godot_cpp/{get_include_path(included)}>")
+ if len(used_classes) > 0:
+ includes = []
+ for included in used_classes:
+ includes.append(f"godot_cpp/{get_include_path(included)}")
+
+ includes.sort()
- if len(used_classes) == 0:
+ for include in includes:
+ result.append(f"#include <{include}>")
+ else:
result.append("#include <godot_cpp/core/method_ptrcall.hpp>")
+
result.append("")
result.append("namespace godot {")
@@ -1562,16 +1595,23 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
result.append("")
- for included in fully_used_classes:
- if included == "TypedArray":
- result.append("#include <godot_cpp/variant/typed_array.hpp>")
- else:
- result.append(f"#include <godot_cpp/{get_include_path(included)}>")
+ if len(fully_used_classes) > 0:
+ includes = []
+ for included in fully_used_classes:
+ if included == "TypedArray":
+ includes.append("godot_cpp/variant/typed_array.hpp")
+ else:
+ includes.append(f"godot_cpp/{get_include_path(included)}")
+
+ includes.sort()
+
+ for include in includes:
+ result.append(f"#include <{include}>")
+
+ result.append("")
if class_name == "EditorPlugin":
result.append("#include <godot_cpp/classes/editor_plugin_registration.hpp>")
-
- if len(fully_used_classes) > 0:
result.append("")
if class_name != "Object" and class_name != "ClassDBSingleton":
@@ -1610,7 +1650,6 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
result.append("")
result.append("public:")
- result.append("")
if "enums" in class_api:
for enum_api in class_api["enums"]:
@@ -1643,6 +1682,10 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
vararg = "is_vararg" in method and method["is_vararg"]
+ if vararg:
+ result.append("")
+ result.append("private:")
+
method_signature = "\t"
method_signature += make_signature(
class_name, method, for_header=True, use_template_get_node=use_template_get_node
@@ -1650,6 +1693,8 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
result.append(method_signature + ";")
if vararg:
+ result.append("")
+ result.append("public:")
# Add templated version.
result += make_varargs_template(method)
@@ -1664,6 +1709,8 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
)
result.append(method_signature + ";")
+ result.append("")
+
result.append("protected:")
# T is the custom class we want to register (from which the call initiates, going up the inheritance chain),
# B is its base class (can be a custom class too, that's why we pass it).
@@ -1680,7 +1727,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
# If the method is different from the base class, it means T overrides it, so it needs to be bound.
# Note that with an `if constexpr`, the code inside the `if` will not even be compiled if the
# condition returns false (in such cases it can't compile due to ambiguity).
- f"\t\tif constexpr (!std::is_same_v<decltype(&B::{method_name}),decltype(&T::{method_name})>) {{"
+ f"\t\tif constexpr (!std::is_same_v<decltype(&B::{method_name}), decltype(&T::{method_name})>) {{"
)
result.append(f"\t\t\tBIND_VIRTUAL_METHOD(T, {method_name});")
result.append("\t\t}")
@@ -1708,7 +1755,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
if class_name == "WorkerThreadPool":
result.append("\tenum {")
- result.append("\tINVALID_TASK_ID = -1")
+ result.append("\t\tINVALID_TASK_ID = -1")
result.append("\t};")
result.append("\ttypedef int64_t TaskID;")
result.append("\ttypedef int64_t GroupID;")
@@ -1720,8 +1767,6 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
)
if class_name == "Object":
- result.append("")
-
result.append("\ttemplate <typename T>")
result.append("\tstatic T *cast_to(Object *p_object);")
@@ -1736,7 +1781,6 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
"\tT *get_node(const NodePath &p_path) const { return Object::cast_to<T>(get_node_internal(p_path)); }"
)
- result.append("")
result.append("};")
result.append("")
@@ -1820,7 +1864,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
result.append(method_body)
result.append("\t} \\")
- result.append("\t;")
+ result.append("\t")
result.append("")
result.append("#define CLASSDB_SINGLETON_VARIANT_CAST \\")
@@ -1832,10 +1876,11 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
else:
result.append(f'\tVARIANT_ENUM_CAST({class_api["alias_for"]}::{enum_api["name"]}); \\')
- result.append("\t;")
+ result.append("\t")
result.append("")
result.append(f"#endif // ! {header_guard}")
+ result.append("")
return "\n".join(result)
@@ -1857,10 +1902,16 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result.append("#include <godot_cpp/core/error_macros.hpp>")
result.append("")
- for included in used_classes:
- result.append(f"#include <godot_cpp/{get_include_path(included)}>")
-
if len(used_classes) > 0:
+ includes = []
+ for included in used_classes:
+ includes.append(f"godot_cpp/{get_include_path(included)}")
+
+ includes.sort()
+
+ for included in includes:
+ result.append(f"#include <{included}>")
+
result.append("")
result.append("namespace godot {")
@@ -2010,8 +2061,8 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result.append(method_signature)
result.append("")
+ result.append("} // namespace godot")
result.append("")
- result.append("} // namespace godot ")
return "\n".join(result)
@@ -2039,23 +2090,24 @@ def generate_global_constants(api, output_dir):
header.append("namespace godot {")
header.append("")
- for constant in api["global_constants"]:
- header.append(f'\tconst int64_t {escape_identifier(constant["name"])} = {constant["value"]};')
+ if len(api["global_constants"]) > 0:
+ for constant in api["global_constants"]:
+ header.append(f'const int64_t {escape_identifier(constant["name"])} = {constant["value"]};')
- header.append("")
+ header.append("")
for enum_def in api["global_enums"]:
if enum_def["name"].startswith("Variant."):
continue
if enum_def["is_bitfield"]:
- header.append(f'\tenum {enum_def["name"]} : uint64_t {{')
+ header.append(f'enum {enum_def["name"]} : uint64_t {{')
else:
- header.append(f'\tenum {enum_def["name"]} {{')
+ header.append(f'enum {enum_def["name"]} {{')
for value in enum_def["values"]:
- header.append(f'\t\t{value["name"]} = {value["value"]},')
- header.append("\t};")
+ header.append(f'\t{value["name"]} = {value["value"]},')
+ header.append("};")
header.append("")
header.append("} // namespace godot")
@@ -2174,11 +2226,17 @@ def generate_utility_functions(api, output_dir):
vararg = "is_vararg" in function and function["is_vararg"]
+ if vararg:
+ header.append("")
+ header.append("private:")
+
function_signature = "\t"
function_signature += make_signature("UtilityFunctions", function, for_header=True, static=True)
header.append(function_signature + ";")
if vararg:
+ header.append("")
+ header.append("public:")
# Add templated version.
header += make_varargs_template(function, static=True)
@@ -2199,8 +2257,8 @@ def generate_utility_functions(api, output_dir):
source.append("#include <godot_cpp/variant/utility_functions.hpp>")
source.append("")
- source.append("#include <godot_cpp/core/error_macros.hpp>")
source.append("#include <godot_cpp/core/engine_ptrcall.hpp>")
+ source.append("#include <godot_cpp/core/error_macros.hpp>")
source.append("")
source.append("namespace godot {")
source.append("")
@@ -2302,7 +2360,7 @@ def make_function_parameters(parameters, include_default=False, for_builtin=Fals
signature.append(parameter)
if is_vararg:
- signature.append("const Args&... p_args")
+ signature.append("const Args &...p_args")
return ", ".join(signature)
@@ -2360,9 +2418,6 @@ def make_signature(
if "is_virtual" in function_data and function_data["is_virtual"]:
function_signature += "virtual "
- if is_vararg:
- function_signature += "private: "
-
if static:
function_signature += "static "
@@ -2415,7 +2470,6 @@ def make_varargs_template(
function_data,
static=False,
class_befor_signature="",
- with_public_declare=True,
with_indent=True,
for_builtin_classes=False,
):
@@ -2423,10 +2477,7 @@ def make_varargs_template(
function_signature = ""
- if with_public_declare:
- function_signature = "public: "
-
- function_signature += "template <typename... Args> "
+ result.append("template <typename... Args>")
if static:
function_signature += "static "
@@ -2469,7 +2520,7 @@ def make_varargs_template(
function_signature += " {"
result.append(function_signature)
- args_array = f"\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args {{ "
+ args_array = f"\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args{{ "
for argument in method_arguments:
if argument["type"] == "Variant":
args_array += escape_argument(argument["name"])
@@ -2719,8 +2770,8 @@ def correct_type(type_name, meta=None, use_alias=True):
if meta is not None:
if "int" in meta:
return f"{meta}_t"
- elif meta in type_conversion:
- return type_conversion[type_name]
+ elif "char" in meta:
+ return f"{meta}_t"
else:
return meta
if type_name in type_conversion:
@@ -2832,6 +2883,38 @@ def get_operator_id_name(op):
return op_id_map[op]
+def get_operator_cpp_name(op):
+ op_cpp_map = {
+ "==": "==",
+ "!=": "!=",
+ "<": "<",
+ "<=": "<=",
+ ">": ">",
+ ">=": ">=",
+ "+": "+",
+ "-": "-",
+ "*": "*",
+ "/": "/",
+ "unary-": "-",
+ "unary+": "+",
+ "%": "%",
+ "<<": "<<",
+ ">>": ">>",
+ "&": "&",
+ "|": "|",
+ "^": "^",
+ "~": "~",
+ "and": "&&",
+ "or": "||",
+ "not": "!",
+ }
+ return op_cpp_map[op]
+
+
+def is_valid_cpp_operator(op):
+ return op not in ["**", "xor", "in"]
+
+
def get_default_value_for_type(type_name):
if type_name == "int":
return "0"
diff --git a/gdextension/extension_api.json b/gdextension/extension_api.json
index c9c7e92..10c2f34 100644
--- a/gdextension/extension_api.json
+++ b/gdextension/extension_api.json
@@ -3,9 +3,9 @@
"version_major": 4,
"version_minor": 3,
"version_patch": 0,
- "version_status": "rc3",
+ "version_status": "stable",
"version_build": "official",
- "version_full_name": "Godot Engine v4.3.rc3.official"
+ "version_full_name": "Godot Engine v4.3.stable.official"
},
"builtin_class_sizes": [
{
@@ -29907,7 +29907,6 @@
{
"type": "bool",
"name": "capture_included",
- "setter": "_set_capture_included",
"getter": "is_capture_included"
}
]
diff --git a/include/godot_cpp/core/type_info.hpp b/include/godot_cpp/core/type_info.hpp
index f368988..b78f7e7 100644
--- a/include/godot_cpp/core/type_info.hpp
+++ b/include/godot_cpp/core/type_info.hpp
@@ -397,16 +397,17 @@ MAKE_TYPED_ARRAY_INFO(Callable, Variant::CALLABLE)
MAKE_TYPED_ARRAY_INFO(Signal, Variant::SIGNAL)
MAKE_TYPED_ARRAY_INFO(Dictionary, Variant::DICTIONARY)
MAKE_TYPED_ARRAY_INFO(Array, Variant::ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedByteArray, Variant::PACKED_BYTE_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedInt32Array, Variant::PACKED_INT32_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedInt64Array, Variant::PACKED_INT64_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedStringArray, Variant::PACKED_STRING_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
/*
-MAKE_TYPED_ARRAY_INFO(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<int32_t>, Variant::PACKED_INT32_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<int64_t>, Variant::PACKED_INT64_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<float>, Variant::PACKED_FLOAT32_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<double>, Variant::PACKED_FLOAT64_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<String>, Variant::PACKED_STRING_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
MAKE_TYPED_ARRAY_INFO(IPAddress, Variant::STRING)
*/
diff --git a/include/godot_cpp/templates/safe_refcount.hpp b/include/godot_cpp/templates/safe_refcount.hpp
index 12e6840..98cb04b 100644
--- a/include/godot_cpp/templates/safe_refcount.hpp
+++ b/include/godot_cpp/templates/safe_refcount.hpp
@@ -132,7 +132,7 @@ public:
}
}
- _ALWAYS_INLINE_ explicit SafeNumeric<T>(T p_value = static_cast<T>(0)) {
+ _ALWAYS_INLINE_ explicit SafeNumeric(T p_value = static_cast<T>(0)) {
set(p_value);
}
};
diff --git a/test/project/main.gd b/test/project/main.gd
index dadd4de..b2625b9 100644
--- a/test/project/main.gd
+++ b/test/project/main.gd
@@ -270,6 +270,12 @@ func _ready():
assert_equal(example_child.get_value1(), 11)
assert_equal(example_child.get_value2(), 22)
+ # Test that the extension's library path is absolute and valid.
+ var library_path = Example.test_library_path()
+ assert_equal(library_path.begins_with("res://"), false)
+ assert_equal(library_path, ProjectSettings.globalize_path(library_path))
+ assert_equal(FileAccess.file_exists(library_path), true)
+
exit_with_status()
func _on_Example_custom_signal(signal_name, value):
diff --git a/test/src/example.cpp b/test/src/example.cpp
index a941889..8075f55 100644
--- a/test/src/example.cpp
+++ b/test/src/example.cpp
@@ -204,6 +204,7 @@ void Example::_bind_methods() {
ClassDB::bind_method(D_METHOD("test_str_utility"), &Example::test_str_utility);
ClassDB::bind_method(D_METHOD("test_string_is_forty_two"), &Example::test_string_is_forty_two);
ClassDB::bind_method(D_METHOD("test_string_resize"), &Example::test_string_resize);
+ ClassDB::bind_method(D_METHOD("test_typed_array_of_packed"), &Example::test_typed_array_of_packed);
ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_ops);
ClassDB::bind_method(D_METHOD("test_vector_init_list"), &Example::test_vector_init_list);
@@ -248,6 +249,8 @@ void Example::_bind_methods() {
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);
+ ClassDB::bind_static_method("Example", D_METHOD("test_library_path"), &Example::test_library_path);
+
{
MethodInfo mi;
mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
@@ -424,6 +427,19 @@ String Example::test_string_resize(String p_string) const {
return p_string;
}
+TypedArray<PackedInt32Array> Example::test_typed_array_of_packed() const {
+ TypedArray<PackedInt32Array> arr;
+ PackedInt32Array packed_arr1;
+ packed_arr1.push_back(1);
+ packed_arr1.push_back(2);
+ arr.push_back(packed_arr1);
+ PackedInt32Array packed_arr2;
+ packed_arr2.push_back(3);
+ packed_arr2.push_back(4);
+ arr.push_back(packed_arr2);
+ return arr;
+}
+
int Example::test_vector_ops() const {
PackedInt32Array arr;
arr.push_back(10);
@@ -695,6 +711,12 @@ String Example::test_use_engine_singleton() const {
return OS::get_singleton()->get_name();
}
+String Example::test_library_path() {
+ String library_path;
+ internal::gdextension_interface_get_library_path(internal::library, library_path._native_ptr());
+ return library_path;
+}
+
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 7f3dfaa..6d88cf1 100644
--- a/test/src/example.h
+++ b/test/src/example.h
@@ -134,6 +134,7 @@ public:
String test_str_utility() const;
bool test_string_is_forty_two(const String &p_str) const;
String test_string_resize(String p_original) const;
+ TypedArray<PackedInt32Array> test_typed_array_of_packed() const;
int test_vector_ops() const;
int test_vector_init_list() const;
@@ -194,6 +195,8 @@ public:
GDVIRTUAL1(_do_something_virtual_with_control, Control *);
String test_use_engine_singleton() const;
+
+ static String test_library_path();
};
VARIANT_ENUM_CAST(Example::Constants);
diff --git a/tools/web.py b/tools/web.py
index dea42b2..c8f07c5 100644
--- a/tools/web.py
+++ b/tools/web.py
@@ -39,7 +39,7 @@ def generate(env):
env.Append(LINKFLAGS=["-sUSE_PTHREADS=1"])
# Build as side module (shared library).
- env.Append(CPPFLAGS=["-sSIDE_MODULE=1"])
+ env.Append(CCFLAGS=["-sSIDE_MODULE=1"])
env.Append(LINKFLAGS=["-sSIDE_MODULE=1"])
# Force wasm longjmp mode.