From 014132d4c03290448d214d22a07e1f84fdd931c6 Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Wed, 6 Sep 2023 19:32:55 +0200 Subject: [PATCH 1/7] Ensure `const` correctness for wrappers (cherry picked from commit f651df5e7a74f4ee357b4db41880b31535e660a8) --- include/godot_cpp/classes/wrapped.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp index 9a01672f..63126f27 100644 --- a/include/godot_cpp/classes/wrapped.hpp +++ b/include/godot_cpp/classes/wrapped.hpp @@ -132,16 +132,16 @@ protected: return (void(::godot::Wrapped::*)(::godot::List<::godot::PropertyInfo> * p_list) const) & m_class::_get_property_list; \ } \ \ - static bool (::godot::Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) { \ - return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name)) & m_class::_property_can_revert; \ + static bool (::godot::Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) const { \ + return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name) const) & m_class::_property_can_revert; \ } \ \ - static bool (::godot::Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, ::godot::Variant &) { \ - return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name, ::godot::Variant &)) & m_class::_property_get_revert; \ + static bool (::godot::Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, ::godot::Variant &) const { \ + return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name, ::godot::Variant &) const) & m_class::_property_get_revert; \ } \ \ - static ::godot::String (::godot::Wrapped::*_get_to_string())() { \ - return (::godot::String(::godot::Wrapped::*)()) & m_class::_to_string; \ + static ::godot::String (::godot::Wrapped::*_get_to_string())() const { \ + return (::godot::String(::godot::Wrapped::*)() const) & m_class::_to_string; \ } \ \ template \ @@ -338,15 +338,15 @@ protected: return nullptr; \ } \ \ - static bool (Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) { \ + static bool (Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) const { \ return nullptr; \ } \ \ - static bool (Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, Variant &) { \ + static bool (Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, Variant &) const { \ return nullptr; \ } \ \ - static String (Wrapped::*_get_to_string())() { \ + static String (Wrapped::*_get_to_string())() const { \ return nullptr; \ } \ \ From 354ed1e79dafce483abeab8c0cc4359008708a8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 19:13:12 +0000 Subject: [PATCH 2/7] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] (cherry picked from commit 5d4ff639306f04f5614bdbb4124ad22c30694e9d) --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/static_checks.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30c76682..7e616927 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,7 +83,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive @@ -168,7 +168,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive @@ -192,7 +192,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive @@ -216,7 +216,7 @@ jobs: runs-on: windows-2019 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index 16cbb8b4..f3c588ae 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Azure repositories are not reliable, we need to prevent Azure giving us packages. - name: Make apt sources.list use the default Ubuntu repositories From dcd7a69512f38f2c521d49f0d10ed30e7bc0964b Mon Sep 17 00:00:00 2001 From: David Snopek Date: Tue, 15 Aug 2023 17:35:59 -0500 Subject: [PATCH 3/7] Ensure that PtrToArg specializations for native structs are used (cherry picked from commit 3cd3f2415057d90bbb5831f4caee63100d5d8e3c) --- binding_generator.py | 6 ++++++ include/godot_cpp/core/method_ptrcall.hpp | 2 ++ 2 files changed, 8 insertions(+) diff --git a/binding_generator.py b/binding_generator.py index 49664d14..443e8611 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -1142,6 +1142,12 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node): else: fully_used_classes.add("Wrapped") + # In order to ensure that PtrToArg specializations for native structs are + # always used, let's move any of them into 'fully_used_classes'. + for type_name in used_classes: + if is_struct_type(type_name) and not is_included_struct_type(type_name): + fully_used_classes.add(type_name) + for type_name in fully_used_classes: if type_name in used_classes: used_classes.remove(type_name) diff --git a/include/godot_cpp/core/method_ptrcall.hpp b/include/godot_cpp/core/method_ptrcall.hpp index a85cbc94..32f3f459 100644 --- a/include/godot_cpp/core/method_ptrcall.hpp +++ b/include/godot_cpp/core/method_ptrcall.hpp @@ -168,6 +168,7 @@ MAKE_PTRARG_BY_REFERENCE(Variant); template struct PtrToArg { + static_assert(std::is_base_of::value, "Cannot encode non-Object value as an Object"); _FORCE_INLINE_ static T *convert(const void *p_ptr) { return reinterpret_cast(godot::internal::get_object_instance_binding(*reinterpret_cast(const_cast(p_ptr)))); } @@ -179,6 +180,7 @@ struct PtrToArg { template struct PtrToArg { + static_assert(std::is_base_of::value, "Cannot encode non-Object value as an Object"); _FORCE_INLINE_ static const T *convert(const void *p_ptr) { return reinterpret_cast(godot::internal::get_object_instance_binding(*reinterpret_cast(const_cast(p_ptr)))); } From dd8e1def679af551bf668ec3824d3a684d521e87 Mon Sep 17 00:00:00 2001 From: DmitriySalnikov Date: Sat, 9 Sep 2023 11:55:53 +0300 Subject: [PATCH 4/7] [SCons] Fixed crashes in several scripts (cherry picked from commit 0e5975dd266234ab45acbd88168e8550ea3e4419) --- SConstruct | 1 - tools/android.py | 2 +- tools/godotcpp.py | 7 ++++--- tools/javascript.py | 2 +- tools/macos.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/SConstruct b/SConstruct index 7c652f8f..e8817b07 100644 --- a/SConstruct +++ b/SConstruct @@ -5,7 +5,6 @@ import platform import sys import subprocess from binding_generator import scons_generate_bindings, scons_emit_files -from SCons.Errors import UserError EnsureSConsVersion(4, 0) diff --git a/tools/android.py b/tools/android.py index 4735345e..0e688551 100644 --- a/tools/android.py +++ b/tools/android.py @@ -29,7 +29,7 @@ def generate(env): if env["arch"] not in ("arm64", "x86_64", "arm32", "x86_32"): print("Only arm64, x86_64, arm32, and x86_32 are supported on Android. Exiting.") - Exit() + env.Exit(1) if sys.platform == "win32" or sys.platform == "msys": my_spawn.configure(env) diff --git a/tools/godotcpp.py b/tools/godotcpp.py index 60cd34b4..969f8c41 100644 --- a/tools/godotcpp.py +++ b/tools/godotcpp.py @@ -3,6 +3,7 @@ import os, sys, platform from SCons.Variables import EnumVariable, PathVariable, BoolVariable from SCons.Tool import Tool from SCons.Builder import Builder +from SCons.Errors import UserError from binding_generator import scons_generate_bindings, scons_emit_files @@ -226,7 +227,7 @@ def generate(env): env["arch"] = "x86_32" else: print("Unsupported CPU architecture: " + host_machine) - Exit() + env.Exit(1) print("Building for architecture " + env["arch"] + " on platform " + env["platform"]) @@ -284,8 +285,8 @@ def _godot_cpp(env): ) # Forces bindings regeneration. if env["generate_bindings"]: - AlwaysBuild(bindings) - NoCache(bindings) + env.AlwaysBuild(bindings) + env.NoCache(bindings) # Sources to compile sources = [] diff --git a/tools/javascript.py b/tools/javascript.py index 42c601d2..1d8009eb 100644 --- a/tools/javascript.py +++ b/tools/javascript.py @@ -8,7 +8,7 @@ def exists(env): def generate(env): if env["arch"] not in ("wasm32"): print("Only wasm32 supported on web. Exiting.") - Exit() + env.Exit(1) if "EM_CONFIG" in os.environ: env["ENV"] = os.environ diff --git a/tools/macos.py b/tools/macos.py index 34a755ab..0c75e4a7 100644 --- a/tools/macos.py +++ b/tools/macos.py @@ -20,7 +20,7 @@ def exists(env): def generate(env): if env["arch"] not in ("universal", "arm64", "x86_64"): print("Only universal, arm64, and x86_64 are supported on macOS. Exiting.") - Exit() + env.Exit(1) if sys.platform == "darwin": # Use clang on macOS by default From 3be7ec4162493d2fd16b64c443bf502e4a15d9c5 Mon Sep 17 00:00:00 2001 From: David Snopek Date: Mon, 14 Aug 2023 15:59:46 -0500 Subject: [PATCH 5/7] Check that GDExtension is opened by compatible Godot version (cherry picked from commit fecb2959b4e99393c86537cfe5a26c7b753bc11d) --- src/godot.cpp | 53 +++++++++++++++++++++++++++++--------- test/project/project.godot | 2 +- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/godot.cpp b/src/godot.cpp index e6ad172b..419836a2 100644 --- a/src/godot.cpp +++ b/src/godot.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -192,9 +193,15 @@ GDExtensionBinding::Callback GDExtensionBinding::init_callback = nullptr; GDExtensionBinding::Callback GDExtensionBinding::terminate_callback = nullptr; GDExtensionInitializationLevel GDExtensionBinding::minimum_initialization_level = GDEXTENSION_INITIALIZATION_CORE; -#define LOAD_PROC_ADDRESS(m_name, m_type) \ - internal::gdextension_interface_##m_name = (m_type)p_get_proc_address(#m_name); \ - ERR_FAIL_NULL_V_MSG(internal::gdextension_interface_##m_name, false, "Unable to load GDExtension interface function " #m_name "()") +#define ERR_PRINT_EARLY(m_msg) \ + internal::gdextension_interface_print_error(m_msg, FUNCTION_STR, __FILE__, __LINE__, false) + +#define LOAD_PROC_ADDRESS(m_name, m_type) \ + internal::gdextension_interface_##m_name = (m_type)p_get_proc_address(#m_name); \ + if (!internal::gdextension_interface_##m_name) { \ + ERR_PRINT_EARLY("Unable to load GDExtension interface function " #m_name "()"); \ + return false; \ + } // Partial definition of the legacy interface so we can detect it and show an error. typedef struct { @@ -217,14 +224,15 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge if (raw_interface[0] == 4 && raw_interface[1] == 0) { // Use the legacy interface only to give a nice error. LegacyGDExtensionInterface *legacy_interface = (LegacyGDExtensionInterface *)p_get_proc_address; - internal::gdextension_interface_print_error_with_message = (GDExtensionInterfacePrintErrorWithMessage)legacy_interface->print_error_with_message; - ERR_FAIL_V_MSG(false, "Cannot load a GDExtension built for Godot 4.1+ in Godot 4.0."); + internal::gdextension_interface_print_error = (GDExtensionInterfacePrintError)legacy_interface->print_error; + ERR_PRINT_EARLY("Cannot load a GDExtension built for Godot 4.1+ in Godot 4.0."); + return false; } - // Load the "print_error_with_message" function first (needed by the ERR_FAIL_NULL_V_MSG() macro). - internal::gdextension_interface_print_error_with_message = (GDExtensionInterfacePrintErrorWithMessage)p_get_proc_address("print_error_with_message"); - if (!internal::gdextension_interface_print_error_with_message) { - printf("ERROR: Unable to load GDExtension interface function print_error_with_message().\n"); + // Load the "print_error" function first (needed by the ERR_PRINT_EARLY() macro). + internal::gdextension_interface_print_error = (GDExtensionInterfacePrintError)p_get_proc_address("print_error"); + if (!internal::gdextension_interface_print_error) { + printf("ERROR: Unable to load GDExtension interface function print_error().\n"); return false; } @@ -233,6 +241,29 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge internal::token = p_library; LOAD_PROC_ADDRESS(get_godot_version, GDExtensionInterfaceGetGodotVersion); + internal::gdextension_interface_get_godot_version(&internal::godot_version); + + // Check that godot-cpp was compiled using an extension_api.json older or at the + // same version as the Godot that is loading it. + bool compatible; + if (internal::godot_version.major != GODOT_VERSION_MAJOR) { + compatible = internal::godot_version.major > GODOT_VERSION_MAJOR; + } else if (internal::godot_version.minor != GODOT_VERSION_MINOR) { + compatible = internal::godot_version.minor > GODOT_VERSION_MINOR; + } else { + compatible = internal::godot_version.patch >= GODOT_VERSION_PATCH; + } + if (!compatible) { + // We need to use snprintf() here because vformat() uses Variant, and we haven't loaded + // the GDExtension interface far enough to use Variants yet. + char msg[128]; + snprintf(msg, 128, "Cannot load a GDExtension built for Godot %d.%d.%d using an older version of Godot (%d.%d.%d).", + GODOT_VERSION_MAJOR, GODOT_VERSION_MINOR, GODOT_VERSION_PATCH, + internal::godot_version.major, internal::godot_version.minor, internal::godot_version.patch); + ERR_PRINT_EARLY(msg); + return false; + } + LOAD_PROC_ADDRESS(mem_alloc, GDExtensionInterfaceMemAlloc); LOAD_PROC_ADDRESS(mem_realloc, GDExtensionInterfaceMemRealloc); LOAD_PROC_ADDRESS(mem_free, GDExtensionInterfaceMemFree); @@ -368,9 +399,6 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge LOAD_PROC_ADDRESS(editor_add_plugin, GDExtensionInterfaceEditorAddPlugin); LOAD_PROC_ADDRESS(editor_remove_plugin, GDExtensionInterfaceEditorRemovePlugin); - // Load the Godot version. - internal::gdextension_interface_get_godot_version(&internal::godot_version); - r_initialization->initialize = initialize_level; r_initialization->deinitialize = deinitialize_level; r_initialization->minimum_initialization_level = minimum_initialization_level; @@ -384,6 +412,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge } #undef LOAD_PROC_ADDRESS +#undef ERR_PRINT_EARLY void GDExtensionBinding::initialize_level(void *userdata, GDExtensionInitializationLevel p_level) { ClassDB::current_level = p_level; diff --git a/test/project/project.godot b/test/project/project.godot index 3ed679b4..eafcad30 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.1") config/icon="res://icon.png" [native_extensions] From 590e26790282b5928d9d1dae1c6543c5252726d3 Mon Sep 17 00:00:00 2001 From: David Snopek Date: Fri, 15 Sep 2023 14:08:27 -0500 Subject: [PATCH 6/7] Load 'print_error_with_message' function (cherry picked from commit 634ed09ec0220f73f81e8400ad70f8619edfdbff) --- src/godot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/godot.cpp b/src/godot.cpp index 419836a2..9855f656 100644 --- a/src/godot.cpp +++ b/src/godot.cpp @@ -267,7 +267,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge LOAD_PROC_ADDRESS(mem_alloc, GDExtensionInterfaceMemAlloc); LOAD_PROC_ADDRESS(mem_realloc, GDExtensionInterfaceMemRealloc); LOAD_PROC_ADDRESS(mem_free, GDExtensionInterfaceMemFree); - LOAD_PROC_ADDRESS(print_error, GDExtensionInterfacePrintError); + LOAD_PROC_ADDRESS(print_error_with_message, GDExtensionInterfacePrintErrorWithMessage); LOAD_PROC_ADDRESS(print_warning, GDExtensionInterfacePrintWarning); LOAD_PROC_ADDRESS(print_warning_with_message, GDExtensionInterfacePrintWarningWithMessage); LOAD_PROC_ADDRESS(print_script_error, GDExtensionInterfacePrintScriptError); From bc82ae8b0b4a096806008d12c7996eb6c366a543 Mon Sep 17 00:00:00 2001 From: David Snopek Date: Thu, 6 Jul 2023 21:16:27 -0500 Subject: [PATCH 7/7] Add static methods to `ClassDB` for the methods bound to the `ClassDB` singleton (cherry picked from commit 6f913563d88f6f3d51f50ed1f9432c909b621d5b) --- binding_generator.py | 70 +++++++++++++++++++++++---- include/godot_cpp/classes/wrapped.hpp | 9 ++-- include/godot_cpp/core/class_db.hpp | 4 ++ 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/binding_generator.py b/binding_generator.py index 443e8611..7491103e 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -97,9 +97,10 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False): files.append(str(source_filename.as_posix())) for engine_class in api["classes"]: - # TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings. + # Generate code for the ClassDB singleton under a different name. if engine_class["name"] == "ClassDB": - continue + engine_class["name"] = "ClassDBSingleton" + engine_class["alias_for"] = "ClassDB" header_filename = include_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".hpp") source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp") if headers: @@ -1038,21 +1039,23 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node): # First create map of classes and singletons. for class_api in api["classes"]: - # TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings. + # Generate code for the ClassDB singleton under a different name. if class_api["name"] == "ClassDB": - continue + class_api["name"] = "ClassDBSingleton" + class_api["alias_for"] = "ClassDB" engine_classes[class_api["name"]] = class_api["is_refcounted"] for native_struct in api["native_structures"]: engine_classes[native_struct["name"]] = False native_structures.append(native_struct["name"]) for singleton in api["singletons"]: + # Generate code for the ClassDB singleton under a different name. + if singleton["name"] == "ClassDB": + singleton["name"] = "ClassDBSingleton" + singleton["alias_for"] = "ClassDB" singletons.append(singleton["name"]) for class_api in api["classes"]: - # TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings. - if class_api["name"] == "ClassDB": - continue # Check used classes for header include. used_classes = set() fully_used_classes = set() @@ -1250,7 +1253,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us if len(fully_used_classes) > 0: result.append("") - if class_name != "Object": + if class_name != "Object" and class_name != "ClassDBSingleton": result.append("#include ") result.append("") result.append("#include ") @@ -1271,7 +1274,10 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us inherits = class_api["inherits"] if "inherits" in class_api else "Wrapped" result.append(f"class {class_name} : public {inherits} {{") - result.append(f"\tGDEXTENSION_CLASS({class_name}, {inherits})") + if "alias_for" in class_api: + result.append(f"\tGDEXTENSION_CLASS_ALIAS({class_name}, {class_api['alias_for']}, {inherits})") + else: + result.append(f"\tGDEXTENSION_CLASS({class_name}, {inherits})") result.append("") result.append("public:") @@ -1429,6 +1435,51 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us result.append(f'VARIANT_ENUM_CAST({class_name}::{enum_api["name"]});') result.append("") + if class_name == "ClassDBSingleton": + result.append("#define CLASSDB_SINGLETON_FORWARD_METHODS \\") + for method in class_api["methods"]: + # ClassDBSingleton shouldn't have any static or vararg methods, but if some appear later, lets skip them. + if vararg: + continue + if "is_static" in method and method["is_static"]: + continue + + method_signature = "\tstatic " + if "return_type" in method: + method_signature += f'{correct_type(method["return_type"])} ' + elif "return_value" in method: + method_signature += ( + correct_type(method["return_value"]["type"], method["return_value"].get("meta", None)) + " " + ) + else: + method_signature += "void " + + method_signature += f'{method["name"]}(' + + method_arguments = [] + if "arguments" in method: + method_arguments = method["arguments"] + + method_signature += make_function_parameters( + method_arguments, include_default=True, for_builtin=True, is_vararg=False + ) + + method_signature += ") { \\" + + result.append(method_signature) + + method_body = "\t\t" + if "return_type" in method or "return_value" in method: + method_body += "return " + method_body += f'ClassDBSingleton::get_singleton()->{method["name"]}(' + method_body += ", ".join(map(lambda x: escape_identifier(x["name"]), method_arguments)) + method_body += "); \\" + + result.append(method_body) + result.append("\t} \\") + result.append("\t;") + result.append("") + result.append(f"#endif // ! {header_guard}") return "\n".join(result) @@ -2325,6 +2376,7 @@ def escape_identifier(id): "operator": "_operator", "typeof": "type_of", "typename": "type_name", + "enum": "_enum", } if id in cpp_keywords_map: return cpp_keywords_map[id] diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp index 63126f27..00d36798 100644 --- a/include/godot_cpp/classes/wrapped.hpp +++ b/include/godot_cpp/classes/wrapped.hpp @@ -306,7 +306,7 @@ public: }; // Don't use this for your classes, use GDCLASS() instead. -#define GDEXTENSION_CLASS(m_class, m_inherits) \ +#define GDEXTENSION_CLASS_ALIAS(m_class, m_alias_for, m_inherits) \ private: \ void operator=(const m_class &p_rval) {} \ \ @@ -354,7 +354,7 @@ public: static void initialize_class() {} \ \ static ::godot::StringName &get_class_static() { \ - static ::godot::StringName string_name = ::godot::StringName(#m_class); \ + static ::godot::StringName string_name = ::godot::StringName(#m_alias_for); \ return string_name; \ } \ \ @@ -379,6 +379,9 @@ public: _gde_binding_free_callback, \ _gde_binding_reference_callback, \ }; \ - m_class() : m_class(#m_class) {} + m_class() : m_class(#m_alias_for) {} + +// Don't use this for your classes, use GDCLASS() instead. +#define GDEXTENSION_CLASS(m_class, m_inherits) GDEXTENSION_CLASS_ALIAS(m_class, m_class, m_inherits) #endif // GODOT_WRAPPED_HPP diff --git a/include/godot_cpp/core/class_db.hpp b/include/godot_cpp/core/class_db.hpp index b1625bf2..26dfb7eb 100644 --- a/include/godot_cpp/core/class_db.hpp +++ b/include/godot_cpp/core/class_db.hpp @@ -38,6 +38,8 @@ #include #include +#include + #include #include #include @@ -146,6 +148,8 @@ public: static void initialize(GDExtensionInitializationLevel p_level); static void deinitialize(GDExtensionInitializationLevel p_level); + + CLASSDB_SINGLETON_FORWARD_METHODS; }; #define BIND_CONSTANT(m_constant) \