Compare commits

..

40 Commits

Author SHA1 Message Date
David Snopek
b724219737 Merge pull request #1895 from dsnopek/gdextension-interface-via-json
Generate GDExtension interface header and loader from JSON
2025-12-22 05:51:55 -06:00
David Snopek
fe68c22c3e Generate GDExtension interface header and loader from JSON 2025-12-18 12:09:41 -06:00
David Snopek
4ae2669dcd Merge pull request #1864 from janos-ijgyarto/master
Added missing namespace prefixes to GDVIRTUAL macros
2025-11-30 06:05:23 -06:00
David Snopek
ee2a174746 Merge pull request #1880 from guillaumeriousat/make-noexcept-flag-private
CMake: Make -fno-exceptions private
2025-11-30 06:05:14 -06:00
David Snopek
8d1a1c847b Merge pull request #1889 from Naros/align-emscripten-4.0.11
Align Emscripten version 4.0.11 with Godot Engine
2025-11-30 06:04:39 -06:00
Chris Cranford
8daf1ea657 Align Emscripten version 4.0.11 with Godot Engine 2025-11-29 09:31:06 -05:00
David Snopek
7f75888cda Merge pull request #1887 from Ivorforce/classes-pointer-stability
Make `ClassDB::classes` pointer-stable again by changing it to `HashMap`
2025-11-27 05:16:13 -06:00
David Snopek
2d7941d0dc Merge pull request #1711 from BenLubar/vector-bsearch-const
Make Vector<T>::bsearch use a const receiver
2025-11-27 05:15:41 -06:00
David Snopek
f47a4d5400 Merge pull request #1869 from enetheru/issue-1830
CMake: Fix missing -sUSE_PTHREADS=1 in web build
2025-11-26 05:05:24 -06:00
Lukas Tenbrink
788edc6bfe Make ClassDB::classes pointer-stable again by changing it to HashMap (from AHashMap). 2025-11-26 11:19:30 +01:00
Guillaume Riou
7d114d8d28 make -fno-exceptions private 2025-11-12 15:17:23 -05:00
David Snopek
44a7d6befe Merge pull request #1878 from dsnopek/linux-disable-static-cpp-by-default
On Linux default `use_static_cpp` to disabled
2025-11-11 10:49:23 -06:00
David Snopek
d033e8abea On Linux default use_static_cpp to disabled 2025-11-01 08:31:46 -05:00
David Snopek
fde93df450 Merge pull request #1875 from dsnopek/tween-smoke-test
Add smoke test with `Tween` to check for issues with handling `RefCounted`
2025-10-29 16:46:25 -05:00
David Snopek
618ee44a23 Add smoke test with Tween to check for issues with handling RefCounted 2025-10-28 14:29:10 -05:00
David Snopek
6c05f1f0b1 Merge pull request #1789 from aaronfranke/header-builders
Add header builders script for `env.GLSL_HEADER` and SVG icons
2025-10-20 10:53:18 -05:00
David Snopek
b14df6e18f Merge pull request #1868 from dsnopek/meta-required
Specifically handle each "meta" value, so new ones don't break code generation
2025-10-20 10:52:31 -05:00
David Snopek
647c7d811f Merge pull request #1861 from Repiteo/revert-cppextpath
Remove `CPPEXTPATH` changes, add error macros
2025-10-20 10:52:21 -05:00
David Snopek
fd0a8a5d0e Merge pull request #1859 from Ivorforce/cmake-docs-move
Migrate cmake docs to the godot docs.
2025-10-20 10:52:10 -05:00
David Snopek
bde278b2c7 Merge pull request #1858 from dementive/update-hashfuncs
Update missing hashfuncs
2025-10-20 10:52:01 -05:00
Samuel Nicholas
42b03da2b1 CMake: Fix missing -sUSE_PTHREADS=1 in web build
- add -sUSE_PTHREADS=1 to link flags
- add =1 to sSIDE_MODULE=1 in compile flags to match scons.
2025-10-20 08:25:55 +10:30
David Snopek
a9773579cb Specifically handle each "meta" value, so new ones don't break code generation 2025-10-18 13:59:24 -05:00
janos-ijgyarto
8c5e038744 Added missing namespace prefixes to GDVIRTUAL macros 2025-10-10 00:11:59 +02:00
Thaddeus Crews
76d1ce6848 Remove CPPEXTPATH changes, add error macros 2025-10-06 13:49:49 -05:00
dementive
fc70347ef7 Update missing hashfuncs 2025-10-05 10:10:12 -05:00
David Snopek
5910c0e8a2 Merge pull request #1839 from dementive/improve-build-time
Replace unordered_map with AHashMap to improve build time
2025-10-05 06:31:45 -05:00
Lukas Tenbrink
c7873e1355 Migrate cmake docs to the godot docs. 2025-10-05 11:10:29 +02:00
dementive
2fd41b7e16 Replace unordered_map with AHashMap 2025-10-04 15:45:25 -05:00
David Snopek
28e8b1a04b Merge pull request #1857 from qqwobble/silenced-warning-call-with-variant
Silenced compiler warning in godot::call_with_variant_args_ret_helper
2025-10-03 12:27:58 -05:00
David Snopek
4218f9370d Merge pull request #1821 from dsnopek/mem-alloc-pad-align
Update to use `mem_alloc2`, `mem_realloc2` and `mem_free2`
2025-10-03 12:26:55 -05:00
=
3eb3069e09 Silenced compiler warning in godot::call_with_variant_args_ret_helper 2025-10-01 21:54:23 +02:00
David Snopek
48d02db27c Update to use mem_alloc2, mem_realloc2 and mem_free2 2025-10-01 08:12:27 -05:00
David Snopek
12db0684b2 Merge pull request #1851 from Staudey/readme-updates
README: Add link to 4.5 branch and fix link to Godot compile docs
2025-09-22 09:21:23 -05:00
Thomas Staudinger
ef63d2e657 README: Add link to 4.5 branch and fix link to Godot compile docs
Signed-off-by: Thomas Staudinger <Staudi.Kaos@gmail.com>
2025-09-21 17:49:08 +02:00
David Snopek
0974e9724b Merge pull request #1841 from dementive/no-std-vector
Use LocalVector instead of std::vector
2025-09-16 17:34:03 -05:00
dementive
0b8e76817b Use LocalVector instead of std::vector 2025-09-16 15:47:41 -05:00
David Snopek
17d13e3edb Merge pull request #1845 from godotengine/contributing-section
Update contributing section in README.md
2025-09-15 16:50:24 -05:00
Lukas Tenbrink
c58dfa4d99 Update contributing section in README.md 2025-09-11 19:48:13 +02:00
Aaron Franke
51008e1556 Add header builders script for env.GLSL_HEADER and SVG icons 2025-08-25 11:16:37 -07:00
Ben Lubar
479d206c50 make Vector<T>::bsearch use a const receiver 2025-02-19 13:52:50 -06:00
60 changed files with 11398 additions and 4559 deletions

View File

@@ -6,7 +6,7 @@ inputs:
required: true
description: Target platform.
em-version:
default: 3.1.62
default: 4.0.11
description: Emscripten version.
windows-compiler:
required: true

View File

@@ -20,7 +20,7 @@ jobs:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
env:
EM_VERSION: 3.1.39
EM_VERSION: 4.0.11
config-flags:
-DCMAKE_C_COMPILER_LAUNCHER=sccache
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache

View File

@@ -87,7 +87,7 @@ jobs:
env:
SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
EM_VERSION: 3.1.39
EM_VERSION: 4.0.11
steps:
- name: Checkout

View File

@@ -4,7 +4,7 @@ default_language_version:
exclude: |
(?x)^(
gdextension/extension_api\.json|
gdextension/gdextension_interface\.h
gdextension/gdextension_interface\.json
)$
repos:

View File

@@ -21,7 +21,8 @@ compromises need to be made to resolve those differences.
As we are attempting to maintain feature parity, and ease of maintenance, these
CMake scripts are built to resemble the SCons build system wherever possible.
Where they are not, we will attempt to document common difference in
doc/cmake.rst and platform specific differences in their respective
the docs (https://docs.godotengine.org/en/latest/tutorials/scripting/cpp/build_system/cmake.html)
and platform specific differences in their respective
cmake/<platform>.cmake file.
The file structure and file content are made to match, if not in content then

View File

@@ -7,6 +7,7 @@
> from Godot's `master` branch.
>
> For users of stable branches, switch to the branch matching your target Godot version:
> - [`4.5`](https://github.com/godotengine/godot-cpp/tree/4.5)
> - [`4.4`](https://github.com/godotengine/godot-cpp/tree/4.4)
> - [`4.3`](https://github.com/godotengine/godot-cpp/tree/4.3)
> - [`4.2`](https://github.com/godotengine/godot-cpp/tree/4.2)
@@ -62,15 +63,11 @@ See [Updating your GDExtension for 4.1](https://docs.godotengine.org/en/latest/t
## Contributing
We greatly appreciate help in maintaining and extending this project. If you
wish to help out, ensure you have an account on GitHub and create a "fork" of
this repository. See [Pull request workflow](https://docs.godotengine.org/en/stable/community/contributing/pr_workflow.html)
for instructions.
Please install clang-format and the [pre-commit](https://pre-commit.com/) Python framework so formatting is done before your changes are submitted. See the [code style guidelines](https://docs.godotengine.org/en/latest/contributing/development/code_style_guidelines.html#pre-commit-hook) for instructions.
wish to help out, please visit the [godot-cpp section of the Contributing docs](https://contributing.godotengine.org/en/latest/other/godot-cpp.html).
## Getting started
You need the same C++ pre-requisites installed that are required for the `godot` repository. Follow the [official build instructions for your target platform](https://docs.godotengine.org/en/latest/contributing/development/compiling/index.html#building-for-target-platforms).
You need the same C++ pre-requisites installed that are required for the `godot` repository. Follow the [official build instructions for your target platform](https://docs.godotengine.org/en/latest/engine_details/development/compiling/index.html).
Getting started with GDExtensions is a bit similar to what it was for 3.x but also a bit different.

View File

@@ -5,6 +5,8 @@ import re
import shutil
from pathlib import Path
from make_interface_header import generate_gdextension_interface_header
def generate_mod_version(argcount, const=False, returns=False):
s = """
@@ -68,11 +70,11 @@ def generate_virtual_version(argcount, const=False, returns=False, required=Fals
s = """#define GDVIRTUAL$VER($RET m_name $ARG)\\
::godot::StringName _gdvirtual_##m_name##_sn = #m_name;\\
_FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST {\\
if (::godot::internal::gdextension_interface_object_has_script_method(_owner, &_gdvirtual_##m_name##_sn)) { \\
if (::godot::gdextension_interface::object_has_script_method(_owner, &_gdvirtual_##m_name##_sn)) { \\
GDExtensionCallError ce;\\
$CALLSIARGS\\
::godot::Variant ret;\\
::godot::internal::gdextension_interface_object_call_script_method(_owner, &_gdvirtual_##m_name##_sn, $CALLSIARGPASS, &ret, &ce);\\
::godot::gdextension_interface::object_call_script_method(_owner, &_gdvirtual_##m_name##_sn, $CALLSIARGPASS, &ret, &ce);\\
if (ce.error == GDEXTENSION_CALL_OK) {\\
$CALLSIRET\\
return true;\\
@@ -83,7 +85,7 @@ def generate_virtual_version(argcount, const=False, returns=False, required=Fals
return false;\\
}\\
_FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const {\\
return ::godot::internal::gdextension_interface_object_has_script_method(_owner, &_gdvirtual_##m_name##_sn); \\
return ::godot::gdextension_interface::object_has_script_method(_owner, &_gdvirtual_##m_name##_sn); \\
}\\
_FORCE_INLINE_ static ::godot::MethodInfo _gdvirtual_##m_name##_get_method_info() {\\
::godot::MethodInfo method_info;\\
@@ -97,7 +99,7 @@ def generate_virtual_version(argcount, const=False, returns=False, required=Fals
sproto = str(argcount)
method_info = ""
method_flags = "METHOD_FLAG_VIRTUAL"
method_flags = "::godot::MethodFlags::METHOD_FLAG_VIRTUAL"
if returns:
sproto += "R"
s = s.replace("$RET", "m_ret,")
@@ -110,14 +112,14 @@ def generate_virtual_version(argcount, const=False, returns=False, required=Fals
if const:
sproto += "C"
method_flags += " | METHOD_FLAG_CONST"
method_flags += " | ::godot::MethodFlags::METHOD_FLAG_CONST"
s = s.replace("$CONST", "const")
else:
s = s.replace("$CONST ", "")
if required:
sproto += "_REQUIRED"
method_flags += " | METHOD_FLAG_VIRTUAL_REQUIRED"
method_flags += " | ::godot::MethodFlags::METHOD_FLAG_VIRTUAL_REQUIRED"
s = s.replace(
"$REQCHECK",
'ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");',
@@ -211,10 +213,14 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
def _get_file_list(api, output_dir, headers=False, sources=False):
files = []
gdextension_gen_folder = Path(output_dir) / "gen" / "include"
core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core"
include_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp"
source_gen_folder = Path(output_dir) / "gen" / "src"
files.append(str((gdextension_gen_folder / "gdextension_interface.h").as_posix()))
files.append(str((core_gen_folder / "gdextension_interface_loader.hpp").as_posix()))
files.append(str((source_gen_folder / "gdextension_interface_loader.cpp").as_posix()))
files.append(str((core_gen_folder / "ext_wrappers.gen.inc").as_posix()))
files.append(str((core_gen_folder / "gdvirtual.gen.inc").as_posix()))
@@ -277,14 +283,18 @@ def print_file_list(api_filepath, output_dir, headers=False, sources=False):
print(*get_file_list(api_filepath, output_dir, headers, sources), sep=";", end=None)
def generate_bindings(api_filepath, use_template_get_node, bits="64", precision="single", output_dir="."):
def generate_bindings(
api_filepath, interface_filepath, use_template_get_node, bits="64", precision="single", output_dir="."
):
api = {}
with open(api_filepath, encoding="utf-8") as api_file:
api = json.load(api_file)
_generate_bindings(api, api_filepath, use_template_get_node, bits, precision, output_dir)
_generate_bindings(api, api_filepath, interface_filepath, use_template_get_node, bits, precision, output_dir)
def _generate_bindings(api, api_filepath, use_template_get_node, bits="64", precision="single", output_dir="."):
def _generate_bindings(
api, api_filepath, interface_filepath, use_template_get_node, bits="64", precision="single", output_dir="."
):
if "precision" in api["header"] and precision != api["header"]["precision"]:
raise Exception(
f"Cannot do a precision={precision} build using '{api_filepath}' which was generated by Godot built with precision={api['header']['precision']}"
@@ -298,6 +308,16 @@ def _generate_bindings(api, api_filepath, use_template_get_node, bits="64", prec
real_t = "double" if precision == "double" else "float"
print("Built-in type config: " + real_t + "_" + bits)
header_lines = []
add_header("gdextension_interface.h", header_lines)
gdextension_gen_folder = Path(output_dir) / "gen" / "include"
gdextension_gen_folder.mkdir(parents=True, exist_ok=True)
generate_gdextension_interface_header(
str((gdextension_gen_folder / "gdextension_interface.h").as_posix()), interface_filepath, header_lines
)
generate_gdextension_interface_loader(interface_filepath, target_dir)
generate_global_constants(api, target_dir)
generate_version_header(api, target_dir)
generate_global_constant_binds(api, target_dir)
@@ -306,6 +326,164 @@ def _generate_bindings(api, api_filepath, use_template_get_node, bits="64", prec
generate_utility_functions(api, target_dir)
def generate_gdextension_interface_loader(interface_filepath, output_dir):
include_gen_folder = Path(output_dir) / "include" / "godot_cpp" / "core"
source_gen_folder = Path(output_dir) / "src"
include_gen_folder.mkdir(parents=True, exist_ok=True)
source_gen_folder.mkdir(parents=True, exist_ok=True)
header_filename = include_gen_folder / "gdextension_interface_loader.hpp"
source_filename = source_gen_folder / "gdextension_interface_loader.cpp"
with open(interface_filepath, "rt") as file:
data = json.load(file)
functions_by_version = {}
for func in data["interface"]:
since = func["since"]
if since not in functions_by_version:
functions_by_version[since] = []
functions_by_version[since].append(func)
with header_filename.open("wt", encoding="utf-8") as header_file:
header_file.write(generate_gdextension_interface_loader_header(functions_by_version))
with source_filename.open("wt", encoding="utf-8") as source_file:
source_file.write(generate_gdextension_interface_loader_source(functions_by_version))
def gdextension_interface_type_name(name):
return "GDExtensionInterface" + "".join(word.capitalize() for word in name.split("_"))
def generate_gdextension_interface_loader_header(data):
result = []
add_header("gdextension_interface_loader.hpp", result)
result.append("#pragma once")
result.append("")
result.append("#include <gdextension_interface.h>")
result.append("#include <godot_cpp/core/version.hpp>")
result.append("")
result.append("namespace godot {")
result.append("")
result.append("namespace gdextension_interface {")
result.append("")
versions = sorted(data.keys())
for version in versions:
(major, minor) = version.split(".")
result.append(f"// Godot 4.{minor} or newer.")
result.append(f"#if GODOT_VERSION_MINOR >= {minor}")
for func in data[version]:
name = func["name"]
fn = gdextension_interface_type_name(name)
if "deprecated" in func:
(deprecated_major, deprecated_minor) = func["deprecated"]["since"].split(".")
result.append(f"#if !defined(DISABLE_DEPRECATED) || GODOT_VERSION_MINOR < {deprecated_minor}")
result.append(f'extern "C" {fn} {name};')
if "deprecated" in func:
result.append("#endif")
result.append(f"#endif // GODOT_VERSION_MINOR >= {minor}")
result.append("")
result.append("} // namespace gdextension_interface")
result.append("")
result.append("namespace internal {")
result.append("")
result.append("bool load_gdextension_interface(GDExtensionInterfaceGetProcAddress p_get_proc_address);")
result.append("")
result.append("} // namespace internal")
result.append("")
result.append("} // namespace godot")
return "\n".join(result)
def generate_gdextension_interface_loader_source(data):
result = []
add_header("gdextension_interface_loader.cpp", result)
result.append("#include <godot_cpp/core/error_macros.hpp>")
result.append("#include <godot_cpp/core/gdextension_interface_loader.hpp>")
result.append("#include <godot_cpp/core/load_proc_address.inc>")
result.append("")
result.append("namespace godot {")
result.append("")
result.append("namespace gdextension_interface {")
result.append("")
versions = sorted(data.keys())
for version in versions:
(major, minor) = version.split(".")
result.append(f"// Godot 4.{minor} or newer.")
result.append(f"#if GODOT_VERSION_MINOR >= {minor}")
for func in data[version]:
name = func["name"]
fn = gdextension_interface_type_name(name)
if "deprecated" in func:
(deprecated_major, deprecated_minor) = func["deprecated"]["since"].split(".")
result.append(f"#if !defined(DISABLE_DEPRECATED) || GODOT_VERSION_MINOR < {deprecated_minor}")
result.append(f"{fn} {name} = nullptr;")
if "deprecated" in func:
result.append("#endif")
result.append(f"#endif // GODOT_VERSION_MINOR >= {minor}")
result.append("")
result.append("} // namespace gdextension_interface")
result.append("")
result.append("namespace internal {")
result.append("")
result.append("bool load_gdextension_interface(GDExtensionInterfaceGetProcAddress p_get_proc_address) {")
for version in versions:
(major, minor) = version.split(".")
result.append(f"\t// Godot 4.{minor} or newer.")
result.append(f"#if GODOT_VERSION_MINOR >= {minor}")
for func in data[version]:
name = func["name"]
fn = gdextension_interface_type_name(name)
if "deprecated" in func:
(deprecated_major, deprecated_minor) = func["deprecated"]["since"].split(".")
result.append(f"#if !defined(DISABLE_DEPRECATED) || GODOT_VERSION_MINOR < {deprecated_minor}")
result.append(f"\tLOAD_PROC_ADDRESS({name}, {fn});")
if "deprecated" in func:
result.append("#endif")
result.append(f"#endif // GODOT_VERSION_MINOR >= {minor}")
result.append("")
result.append("\treturn true;")
result.append("}")
result.append("")
result.append("} // namespace internal")
result.append("")
result.append("} // namespace godot")
return "\n".join(result)
CLASS_ALIASES = {
"ClassDB": "ClassDBSingleton",
}
@@ -1034,18 +1212,18 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append(f"void {class_name}::_init_bindings_constructors_destructor() {{")
result.append(
f"\t_method_bindings.from_variant_constructor = internal::gdextension_interface_get_variant_to_type_constructor({enum_type_name});"
f"\t_method_bindings.from_variant_constructor = ::godot::gdextension_interface::get_variant_to_type_constructor({enum_type_name});"
)
if "constructors" in builtin_api:
for constructor in builtin_api["constructors"]:
result.append(
f"\t_method_bindings.constructor_{constructor['index']} = internal::gdextension_interface_variant_get_ptr_constructor({enum_type_name}, {constructor['index']});"
f"\t_method_bindings.constructor_{constructor['index']} = ::godot::gdextension_interface::variant_get_ptr_constructor({enum_type_name}, {constructor['index']});"
)
if builtin_api["has_destructor"]:
result.append(
f"\t_method_bindings.destructor = internal::gdextension_interface_variant_get_ptr_destructor({enum_type_name});"
f"\t_method_bindings.destructor = ::godot::gdextension_interface::variant_get_ptr_destructor({enum_type_name});"
)
result.append("}")
@@ -1064,36 +1242,36 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
# TODO: Add error check for hash mismatch.
result.append(f'\t_gde_name = StringName("{method["name"]}");')
result.append(
f"\t_method_bindings.method_{method['name']} = internal::gdextension_interface_variant_get_ptr_builtin_method({enum_type_name}, _gde_name._native_ptr(), {method['hash']});"
f"\t_method_bindings.method_{method['name']} = ::godot::gdextension_interface::variant_get_ptr_builtin_method({enum_type_name}, _gde_name._native_ptr(), {method['hash']});"
)
if "members" in builtin_api:
for member in builtin_api["members"]:
result.append(f'\t_gde_name = StringName("{member["name"]}");')
result.append(
f"\t_method_bindings.member_{member['name']}_setter = internal::gdextension_interface_variant_get_ptr_setter({enum_type_name}, _gde_name._native_ptr());"
f"\t_method_bindings.member_{member['name']}_setter = ::godot::gdextension_interface::variant_get_ptr_setter({enum_type_name}, _gde_name._native_ptr());"
)
result.append(
f"\t_method_bindings.member_{member['name']}_getter = internal::gdextension_interface_variant_get_ptr_getter({enum_type_name}, _gde_name._native_ptr());"
f"\t_method_bindings.member_{member['name']}_getter = ::godot::gdextension_interface::variant_get_ptr_getter({enum_type_name}, _gde_name._native_ptr());"
)
if "indexing_return_type" in builtin_api:
result.append(
f"\t_method_bindings.indexed_setter = internal::gdextension_interface_variant_get_ptr_indexed_setter({enum_type_name});"
f"\t_method_bindings.indexed_setter = ::godot::gdextension_interface::variant_get_ptr_indexed_setter({enum_type_name});"
)
result.append(
f"\t_method_bindings.indexed_getter = internal::gdextension_interface_variant_get_ptr_indexed_getter({enum_type_name});"
f"\t_method_bindings.indexed_getter = ::godot::gdextension_interface::variant_get_ptr_indexed_getter({enum_type_name});"
)
if "is_keyed" in builtin_api and builtin_api["is_keyed"]:
result.append(
f"\t_method_bindings.keyed_setter = internal::gdextension_interface_variant_get_ptr_keyed_setter({enum_type_name});"
f"\t_method_bindings.keyed_setter = ::godot::gdextension_interface::variant_get_ptr_keyed_setter({enum_type_name});"
)
result.append(
f"\t_method_bindings.keyed_getter = internal::gdextension_interface_variant_get_ptr_keyed_getter({enum_type_name});"
f"\t_method_bindings.keyed_getter = ::godot::gdextension_interface::variant_get_ptr_keyed_getter({enum_type_name});"
)
result.append(
f"\t_method_bindings.keyed_checker = internal::gdextension_interface_variant_get_ptr_keyed_checker({enum_type_name});"
f"\t_method_bindings.keyed_checker = ::godot::gdextension_interface::variant_get_ptr_keyed_checker({enum_type_name});"
)
if "operators" in builtin_api:
@@ -1106,11 +1284,11 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
f"GDEXTENSION_VARIANT_TYPE_{camel_to_snake(operator['right_type']).upper()}"
)
result.append(
f"\t_method_bindings.operator_{get_operator_id_name(operator['name'])}_{operator['right_type']} = internal::gdextension_interface_variant_get_ptr_operator_evaluator(GDEXTENSION_VARIANT_OP_{get_operator_id_name(operator['name']).upper()}, {enum_type_name}, {right_type_variant_type});"
f"\t_method_bindings.operator_{get_operator_id_name(operator['name'])}_{operator['right_type']} = ::godot::gdextension_interface::variant_get_ptr_operator_evaluator(GDEXTENSION_VARIANT_OP_{get_operator_id_name(operator['name']).upper()}, {enum_type_name}, {right_type_variant_type});"
)
else:
result.append(
f"\t_method_bindings.operator_{get_operator_id_name(operator['name'])} = internal::gdextension_interface_variant_get_ptr_operator_evaluator(GDEXTENSION_VARIANT_OP_{get_operator_id_name(operator['name']).upper()}, {enum_type_name}, GDEXTENSION_VARIANT_TYPE_NIL);"
f"\t_method_bindings.operator_{get_operator_id_name(operator['name'])} = ::godot::gdextension_interface::variant_get_ptr_operator_evaluator(GDEXTENSION_VARIANT_OP_{get_operator_id_name(operator['name']).upper()}, {enum_type_name}, GDEXTENSION_VARIANT_TYPE_NIL);"
)
result.append("}")
@@ -1134,9 +1312,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append(method_signature)
method_call = (
f"\tinternal::_call_builtin_constructor(_method_bindings.constructor_{constructor['index']}, &opaque"
)
method_call = f"\t::godot::internal::_call_builtin_constructor(_method_bindings.constructor_{constructor['index']}, &opaque"
if "arguments" in constructor:
if len(constructor["arguments"]) == 1 and constructor["arguments"][0]["type"] == class_name:
copy_constructor_index = constructor["index"]
@@ -1161,7 +1337,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append(f"{class_name}::{class_name}({class_name} &&p_other) {{")
if needs_copy_instead_of_move(class_name) and copy_constructor_index >= 0:
result.append(
f"\tinternal::_call_builtin_constructor(_method_bindings.constructor_{copy_constructor_index}, &opaque, &p_other);"
f"\t::godot::internal::_call_builtin_constructor(_method_bindings.constructor_{copy_constructor_index}, &opaque, &p_other);"
)
else:
result.append("\tstd::swap(opaque, p_other.opaque);")
@@ -1193,16 +1369,16 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
if "return_type" in method:
return_type = method["return_type"]
if is_enum(return_type):
method_call += f"return ({get_gdextension_type(correct_type(return_type))})internal::_call_builtin_method_ptr_ret<int64_t>("
method_call += f"return ({get_gdextension_type(correct_type(return_type))})::godot::internal::_call_builtin_method_ptr_ret<int64_t>("
elif is_pod_type(return_type) or is_variant(return_type):
method_call += f"return internal::_call_builtin_method_ptr_ret<{get_gdextension_type(correct_type(return_type))}>("
method_call += f"return ::godot::internal::_call_builtin_method_ptr_ret<{get_gdextension_type(correct_type(return_type))}>("
elif is_refcounted(return_type):
method_call += f"return Ref<{return_type}>::_gde_internal_constructor(internal::_call_builtin_method_ptr_ret_obj<{return_type}>("
method_call += f"return Ref<{return_type}>::_gde_internal_constructor(::godot::internal::_call_builtin_method_ptr_ret_obj<{return_type}>("
is_ref = True
else:
method_call += f"return internal::_call_builtin_method_ptr_ret_obj<{return_type}>("
method_call += f"return ::godot::internal::_call_builtin_method_ptr_ret_obj<{return_type}>("
else:
method_call += "internal::_call_builtin_method_ptr_no_ret("
method_call += "::godot::internal::_call_builtin_method_ptr_no_ret("
method_call += f"_method_bindings.method_{method['name']}, "
if "is_static" in method and method["is_static"]:
method_call += "nullptr"
@@ -1235,7 +1411,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
if f"get_{member['name']}" not in method_list:
result.append(f"{correct_type(member['type'])} {class_name}::get_{member['name']}() const {{")
result.append(
f"\treturn internal::_call_builtin_ptr_getter<{correct_type(member['type'])}>(_method_bindings.member_{member['name']}_getter, (GDExtensionConstTypePtr)&opaque);"
f"\treturn ::godot::internal::_call_builtin_ptr_getter<{correct_type(member['type'])}>(_method_bindings.member_{member['name']}_getter, (GDExtensionConstTypePtr)&opaque);"
)
result.append("}")
@@ -1260,7 +1436,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
(encode, arg_name) = get_encoded_arg("other", operator["right_type"], None)
result += encode
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'])}_{operator['right_type']}, (GDExtensionConstTypePtr)&opaque, (GDExtensionConstTypePtr){arg_name});"
f"\treturn ::godot::internal::_call_builtin_operator_ptr<{get_gdextension_type(correct_type(operator['return_type']))}>(_method_bindings.operator_{get_operator_id_name(operator['name'])}_{operator['right_type']}, (GDExtensionConstTypePtr)&opaque, (GDExtensionConstTypePtr){arg_name});"
)
result.append("}")
else:
@@ -1268,7 +1444,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
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 ::godot::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("")
@@ -1285,7 +1461,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
)
result += encode
result.append(
f"\tinternal::_call_builtin_constructor(_method_bindings.constructor_{copy_constructor_index}, &opaque, {arg_name});"
f"\t::godot::internal::_call_builtin_constructor(_method_bindings.constructor_{copy_constructor_index}, &opaque, {arg_name});"
)
result.append("\treturn *this;")
result.append("}")
@@ -1295,7 +1471,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append(f"{class_name} &{class_name}::operator=({class_name} &&p_other) {{")
if needs_copy_instead_of_move(class_name) and copy_constructor_index >= 0:
result.append(
f"\tinternal::_call_builtin_constructor(_method_bindings.constructor_{copy_constructor_index}, &opaque, &p_other);"
f"\t::godot::internal::_call_builtin_constructor(_method_bindings.constructor_{copy_constructor_index}, &opaque, &p_other);"
)
else:
result.append("\tstd::swap(opaque, p_other.opaque);")
@@ -1916,13 +2092,13 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
# We assume multi-threaded access is OK because each assignment will assign the same value every time
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());"
f"\t\tGDExtensionObjectPtr singleton_obj = ::godot::gdextension_interface::global_get_singleton({class_name}::get_class_static()._native_ptr());"
)
result.append("#ifdef DEBUG_ENABLED")
result.append("\t\tERR_FAIL_NULL_V(singleton_obj, nullptr);")
result.append("#endif // DEBUG_ENABLED")
result.append(
f"\t\tsingleton = reinterpret_cast<{class_name} *>(internal::gdextension_interface_object_get_instance_binding(singleton_obj, internal::token, &{class_name}::_gde_binding_callbacks));"
f"\t\tsingleton = reinterpret_cast<{class_name} *>(::godot::gdextension_interface::object_get_instance_binding(singleton_obj, ::godot::gdextension_interface::token, &{class_name}::_gde_binding_callbacks));"
)
result.append("#ifdef DEBUG_ENABLED")
result.append("\t\tERR_FAIL_NULL_V(singleton, nullptr);")
@@ -1957,7 +2133,7 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
# Method body.
result.append(
f'\tstatic GDExtensionMethodBindPtr _gde_method_bind = internal::gdextension_interface_classdb_get_method_bind({class_name}::get_class_static()._native_ptr(), StringName("{method["name"]}")._native_ptr(), {method["hash"]});'
f'\tstatic GDExtensionMethodBindPtr _gde_method_bind = ::godot::gdextension_interface::classdb_get_method_bind({class_name}::get_class_static()._native_ptr(), StringName("{method["name"]}")._native_ptr(), {method["hash"]});'
)
method_call = "\t"
has_return = "return_value" in method and method["return_value"]["type"] != "void"
@@ -1976,34 +2152,30 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
meta_type = method["return_value"]["meta"] if "meta" in method["return_value"] else None
if is_enum(return_type):
if method["is_static"]:
method_call += f"return ({get_gdextension_type(correct_type(return_type, meta_type))})internal::_call_native_mb_ret<int64_t>(_gde_method_bind, nullptr"
method_call += f"return ({get_gdextension_type(correct_type(return_type, meta_type))})::godot::internal::_call_native_mb_ret<int64_t>(_gde_method_bind, nullptr"
else:
method_call += f"return ({get_gdextension_type(correct_type(return_type, meta_type))})internal::_call_native_mb_ret<int64_t>(_gde_method_bind, _owner"
method_call += f"return ({get_gdextension_type(correct_type(return_type, meta_type))})::godot::internal::_call_native_mb_ret<int64_t>(_gde_method_bind, _owner"
elif is_pod_type(return_type) or is_variant(return_type):
if method["is_static"]:
method_call += f"return internal::_call_native_mb_ret<{get_gdextension_type(correct_type(return_type, meta_type))}>(_gde_method_bind, nullptr"
method_call += f"return ::godot::internal::_call_native_mb_ret<{get_gdextension_type(correct_type(return_type, meta_type))}>(_gde_method_bind, nullptr"
else:
method_call += f"return internal::_call_native_mb_ret<{get_gdextension_type(correct_type(return_type, meta_type))}>(_gde_method_bind, _owner"
method_call += f"return ::godot::internal::_call_native_mb_ret<{get_gdextension_type(correct_type(return_type, meta_type))}>(_gde_method_bind, _owner"
elif is_refcounted(return_type):
if method["is_static"]:
method_call += f"return Ref<{return_type}>::_gde_internal_constructor(internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, nullptr"
method_call += f"return Ref<{return_type}>::_gde_internal_constructor(::godot::internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, nullptr"
else:
method_call += f"return Ref<{return_type}>::_gde_internal_constructor(internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, _owner"
method_call += f"return Ref<{return_type}>::_gde_internal_constructor(::godot::internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, _owner"
is_ref = True
else:
if method["is_static"]:
method_call += (
f"return internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, nullptr"
)
method_call += f"return ::godot::internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, nullptr"
else:
method_call += (
f"return internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, _owner"
)
method_call += f"return ::godot::internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, _owner"
else:
if method["is_static"]:
method_call += "internal::_call_native_mb_no_ret(_gde_method_bind, nullptr"
method_call += "::godot::internal::_call_native_mb_no_ret(_gde_method_bind, nullptr"
else:
method_call += "internal::_call_native_mb_no_ret(_gde_method_bind, _owner"
method_call += "::godot::internal::_call_native_mb_no_ret(_gde_method_bind, _owner"
if "arguments" in method:
method_call += ", "
@@ -2020,7 +2192,7 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
else: # vararg.
result.append("\tGDExtensionCallError error;")
result.append("\tVariant ret;")
method_call += "internal::gdextension_interface_object_method_bind_call(_gde_method_bind, _owner, reinterpret_cast<GDExtensionConstVariantPtr *>(p_args), p_arg_count, &ret, &error"
method_call += "::godot::gdextension_interface::object_method_bind_call(_gde_method_bind, _owner, reinterpret_cast<GDExtensionConstVariantPtr *>(p_args), p_arg_count, &ret, &error"
if is_ref:
method_call += ")" # Close Ref<> constructor.
@@ -2253,7 +2425,7 @@ def generate_utility_functions(api, output_dir):
# Function body.
source.append(
f'\tstatic GDExtensionPtrUtilityFunction _gde_function = internal::gdextension_interface_variant_get_ptr_utility_function(StringName("{function["name"]}")._native_ptr(), {function["hash"]});'
f'\tstatic GDExtensionPtrUtilityFunction _gde_function = ::godot::gdextension_interface::variant_get_ptr_utility_function(StringName("{function["name"]}")._native_ptr(), {function["hash"]});'
)
has_return = "return_type" in function and function["return_type"] != "void"
if has_return:
@@ -2268,11 +2440,11 @@ def generate_utility_functions(api, output_dir):
if has_return:
function_call += "return "
if function["return_type"] == "Object":
function_call += "internal::_call_utility_ret_obj(_gde_function"
function_call += "::godot::internal::_call_utility_ret_obj(_gde_function"
else:
function_call += f"internal::_call_utility_ret<{get_gdextension_type(correct_type(function['return_type']))}>(_gde_function"
function_call += f"::godot::internal::_call_utility_ret<{get_gdextension_type(correct_type(function['return_type']))}>(_gde_function"
else:
function_call += "internal::_call_utility_no_ret(_gde_function"
function_call += "::godot::internal::_call_utility_no_ret(_gde_function"
if "arguments" in function:
function_call += ", "
@@ -2745,12 +2917,12 @@ def correct_typed_dictionary(type_name):
def correct_type(type_name, meta=None, use_alias=True):
type_conversion = {"float": "double", "int": "int64_t", "Nil": "Variant"}
if meta is not None:
if "int" in meta:
if meta in ["int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64"]:
return f"{meta}_t"
elif "char" in meta:
return f"{meta}_t"
else:
elif meta in ["float", "double"]:
return meta
elif meta in ["char16", "char32"]:
return f"{meta}_t"
if type_name in type_conversion:
return type_conversion[type_name]
if type_name.startswith("typedarray::"):

View File

@@ -86,6 +86,7 @@ missing. ]]
function(
binding_generator_generate_bindings
API_FILE
INTERFACE_FILE
USE_TEMPLATE_GET_NODE
BITS
PRECISION
@@ -96,6 +97,7 @@ function(
"from binding_generator import generate_bindings"
"generate_bindings(
api_filepath='${API_FILE}',
interface_filepath='${INTERFACE_FILE}',
use_template_get_node='${USE_TEMPLATE_GET_NODE}',
bits='${BITS}',
precision='${PRECISION}',

View File

@@ -22,7 +22,7 @@ Android platforms.
.. _built-in support:https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-android
There is further information and examples in the doc/cmake.rst file.
There is further information and examples in the docs: https://docs.godotengine.org/en/latest/tutorials/scripting/cpp/build_system/cmake.html
]=======================================================================]
@@ -30,8 +30,8 @@ There is further information and examples in the doc/cmake.rst file.
function(android_options)
#[[ Options from SCons
The options below are managed by CMake toolchain files, doc.cmake.rst has
more information
The options below are managed by CMake toolchain files, the docs have more information:
https://docs.godotengine.org/en/latest/tutorials/scripting/cpp/build_system/cmake.html
android_api_level : Target Android API level.
Default = 24

View File

@@ -66,9 +66,6 @@ function(common_compiler_flags)
# The public flag tells CMake that the following options are transient,
# and will propagate to consumers.
PUBLIC
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
# saves around 20% of binary size and very significant build time.
$<${DISABLE_EXCEPTIONS}:$<${NOT_MSVC}:-fno-exceptions>>
# Enabling Debug Symbols
$<${DEBUG_SYMBOLS}:
@@ -95,6 +92,9 @@ function(common_compiler_flags)
# Warnings below, these do not need to propagate to consumers.
PRIVATE
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
# saves around 20% of binary size and very significant build time.
$<${DISABLE_EXCEPTIONS}:$<${NOT_MSVC}:-fno-exceptions>>
$<${IS_MSVC}:
/W4 # Warning level 4 (informational) warnings that aren't off by default.
@@ -170,6 +170,8 @@ function(common_compiler_flags)
$<${IS_MSVC}:$<${DISABLE_EXCEPTIONS}:_HAS_EXCEPTIONS=0>>
$<${THREADS_ENABLED}:THREADS_ENABLED>
$<$<NOT:$<BOOL:${GODOTCPP_DEPRECATED}>>:DISABLE_DEPRECATED>
)
target_link_options(

View File

@@ -155,6 +155,7 @@ function(godotcpp_options)
#TODO optimize
option(GODOTCPP_DEPRECATED "Enable compatibility code for deprecated and removed features" ON)
option(GODOTCPP_DEV_BUILD "Developer build with dev-only debugging code (DEV_ENABLED)" OFF)
#[[ debug_symbols
@@ -248,6 +249,9 @@ function(godotcpp_generate)
set(GODOTCPP_GDEXTENSION_API_FILE "${GODOTCPP_CUSTOM_API_FILE}")
endif()
# Interface json file.
set(GODOTCPP_GDEXTENSION_INTERFACE_FILE "${GODOTCPP_GDEXTENSION_DIR}/gdextension_interface.json")
# Build Profile
if(GODOTCPP_BUILD_PROFILE)
message(STATUS "Using build profile to trim api file")
@@ -262,6 +266,7 @@ function(godotcpp_generate)
endif()
message(STATUS "GODOTCPP_GDEXTENSION_API_FILE = '${GODOTCPP_GDEXTENSION_API_FILE}'")
message(STATUS "GODOTCPP_GDEXTENSION_INTERFACE_FILE = '${GODOTCPP_GDEXTENSION_INTERFACE_FILE}'")
# generate the file list to use
binding_generator_get_file_list( GENERATED_FILES_LIST
@@ -271,6 +276,7 @@ function(godotcpp_generate)
binding_generator_generate_bindings(
"${GODOTCPP_GDEXTENSION_API_FILE}"
"${GODOTCPP_GDEXTENSION_INTERFACE_FILE}"
"${USE_TEMPLATE_GET_NODE}"
"${BITS}"
"${GODOTCPP_PRECISION}"
@@ -351,7 +357,7 @@ function(godotcpp_generate)
target_include_directories(
godot-cpp
${GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE}
PUBLIC include ${CMAKE_CURRENT_BINARY_DIR}/gen/include ${GODOTCPP_GDEXTENSION_DIR}
PUBLIC include ${CMAKE_CURRENT_BINARY_DIR}/gen/include
)
# gersemi: off

View File

@@ -12,9 +12,10 @@ function(linux_options)
#[[ Options from SCons
use_llvm : Use the LLVM compiler
Not implemented as compiler selection is managed by CMake. Look to
doc/cmake.rst for examples.
the docs (https://docs.godotengine.org/en/latest/tutorials/scripting/cpp/build_system/cmake.html)
for examples.
]]
option(GODOTCPP_USE_STATIC_CPP "Link libgcc and libstdc++ statically for better portability" ON)
option(GODOTCPP_USE_STATIC_CPP "Link libgcc and libstdc++ statically for better portability" OFF)
endfunction()
#[===========================[ Target Generation ]===========================]

View File

@@ -21,7 +21,7 @@ function(web_generate)
target_compile_options(
godot-cpp
PUBLIC #
-sSIDE_MODULE
-sSIDE_MODULE=1
-sSUPPORT_LONGJMP=wasm
$<${THREADS_ENABLED}:-sUSE_PTHREADS=1>
)
@@ -33,6 +33,7 @@ function(web_generate)
-sSUPPORT_LONGJMP=wasm
-fvisibility=hidden
-shared
$<${THREADS_ENABLED}:-sUSE_PTHREADS=1>
)
common_compiler_flags()

View File

@@ -62,7 +62,9 @@ function(windows_options)
Default: True
These three options will not implemented as compiler selection is managed
by CMake toolchain files. Look to doc/cmake.rst for examples.
by CMake toolchain files. Look to the docs
(https://docs.godotengine.org/en/latest/tutorials/scripting/cpp/build_system/cmake.html)
for examples.
use_mingw: Use the MinGW compiler instead of MSVC - only effective on Windows
use_llvm: Use the LLVM compiler (MVSC or MinGW depending on the use_mingw flag
mingw_prefix: MinGW prefix

View File

@@ -1,353 +0,0 @@
CMake
=====
.. warning::
The CMake scripts do not have feature parity with the SCons ones at this
stage and are still a work in progress. There are a number of people who
have been working on alternative CMake solutions that are frequently
referenced in the discord chats: Ivan's cmake-rewrite_ branch and
Vorlac's godot-roguelite_ Project
.. _cmake-rewrite: https://github.com/IvanInventor/godot-cpp/tree/cmake-rewrite
.. _godot-roguelite: https://github.com/vorlac/godot-roguelite
Introduction
------------
Compiling godot-cpp independently of an extension project is mainly for
godot-cpp developers, package maintainers, and CI/CD. Look to the
godot-cpp-template_ for a practical example on how to consume the godot-cpp
library as part of a Godot extension.
Configuration examples are listed at the bottom of the page.
.. _godot-cpp-template: https://github.com/godotengine/godot-cpp-template
Debug vs template_debug
-----------------------
Something I've seen come up many times is the conflation of a compilation of c++
source code with debug symbols enabled, and compiling a Godot extension with
debug features enabled. The two concepts are not mutually inclusive.
- debug_features
Enables a pre-processor definition to selectively compile code to help
users of a Godot extension with their own project.
debug features are enabled in editor and template_debug builds, which can be specified during the configure phase like so
``cmake -S . -B cmake-build -DGODOTCPP_TARGET=<target choice>``
- Debug
Sets compiler flags so that debug symbols are generated to help godot
extension developers debug their extension.
``Debug`` is the default build type for CMake projects, to select another it depends on the generator used
For single configuration generators, add to the configure command:
``-DCMAKE_BUILD_TYPE=<type>``
For multi-config generators add to the build command:
``--config <type>``
where ``<type>`` is one of ``Debug``, ``Release``, ``RelWithDebInfo``, ``MinSizeRel``
SCons Deviations
----------------
Not everything from SCons can be perfectly representable in CMake, here are
the notable differences.
- debug_symbols
No longer has an explicit option, and is enabled via Debug-like CMake
build configurations; ``Debug``, ``RelWithDebInfo``.
- dev_build
Does not define ``NDEBUG`` when disabled, ``NDEBUG`` is set via Release-like
CMake build configurations; ``Release``, ``MinSizeRel``.
- arch
CMake sets the architecture via the toolchain files, macos universal is controlled vua the ``CMAKE_OSX_ARCHITECTURES``
property which is copied to targets when they are defined.
- debug_crt
CMake controls linking to windows runtime libraries by copying the value of ``CMAKE_MSVC_RUNTIME_LIBRARIES`` to targets as they are defined.
godot-cpp will set this variable if it isn't already set. so include it before other dependencies to have the value propagate across the projects.
Testing Integration
-------------------
The testing target ``godot-cpp-test`` is guarded by ``GODOTCPP_ENABLE_TESTING`` which is off by default.
To configure and build the godot-cpp project to enable the integration
testing targets the command will look something like:
.. code-block::
# Assuming our current directory is the godot-cpp source root
cmake -S . -B cmake-build -DGODOTCPP_ENABLE_TESTING=YES
cmake --build cmake-build --target godot-cpp-test
Basic walkthrough
-----------------
.. topic:: Clone the git repository
.. code-block::
git clone https://github.com/godotengine/godot-cpp.git
Cloning into 'godot-cpp'...
...
cd godot-cpp
.. topic:: Options
To list the available options CMake use the ``-L[AH]`` option. ``A`` is for
advanced, and ``H`` is for help strings.
.. code-block::
cmake .. -LH
Options are specified on the command line when configuring eg.
.. code-block::
cmake .. -DGODOTCPP_USE_HOT_RELOAD:BOOL=ON \
-DGODOTCPP_PRECISION:STRING=double \
-DCMAKE_BUILD_TYPE:STRING=Debug
Review setting-build-variables_ and build-configurations_ for more information.
.. _setting-build-variables: https://cmake.org/cmake/help/latest/guide/user-interaction/index.html#setting-build-variables
.. _build-configurations: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations
A non-exhaustive list of options:
.. code-block::
// Path to a custom GDExtension API JSON file (takes precedence over `GODOTCPP_GDEXTENSION_DIR`) ( /path/to/custom_api_file )
`GODOTCPP_CUSTOM_API_FILE:FILEPATH=`
// Force disabling exception handling code (ON|OFF)
GODOTCPP_DISABLE_EXCEPTIONS:BOOL=ON
// Path to a custom directory containing GDExtension interface header and API JSON file ( /path/to/gdextension_dir )
GODOTCPP_GDEXTENSION_DIR:PATH=gdextension
// Set the floating-point precision level (single|double)
GODOTCPP_PRECISION:STRING=single
// Enable the extra accounting required to support hot reload. (ON|OFF)
GODOTCPP_USE_HOT_RELOAD:BOOL=
.. topic:: Configure the build
.. code-block::
cmake -S . -B cmake-build -G Ninja
``-S .`` Specifies the source directory
``-B cmake-build`` Specifies the build directory
``-G Ninja`` Specifies the Generator
The source directory in this example is the source code for godot-cpp.
The build directory is so that generated files do not clutter up the source tree.
CMake doesn't build the code, it generates the files that another tool uses
to build the code, in this case Ninja.
To see the list of generators run ``cmake --help``.
.. topic:: Compiling
Tell cmake to invoke the build system it generated in the specified directory.
The default target is template_debug and the default build configuration is Debug.
.. code-block::
cmake --build cmake-build
Examples
--------
Windows and MSVC - Release
~~~~~~~~~~~~~~~~~~~~~~~~~~
So long as CMake is installed from the `CMake Downloads`_ page and in the PATH,
and Microsoft Visual Studio is installed with c++ support, CMake will detect
the MSVC compiler.
Note that Visual Studio is a Multi-Config Generator so the build configuration
needs to be specified at build time ie ``--config Release``
.. _CMake downloads: https://cmake.org/download/
.. code-block::
# Assuming our current directory is the godot-cpp source root
cmake -S . -B cmake-build -DGODOTCPP_ENABLE_TESTING=YES
cmake --build cmake-build -t godot-cpp-test --config Release
MSys2/clang64, "Ninja" - Debug
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Assumes the ming-w64-clang-x86_64-toolchain is installed
Note that Ninja is a Single-Config Generator so the build type
needs to be specified at Configure time.
Using the msys2/clang64 shell
.. code-block::
# Assuming our current directory is the godot-cpp source root
cmake -S . -B cmake-build -G"Ninja" -DGODOTCPP_ENABLE_TESTING=YES -DCMAKE_BUILD_TYPE=Release
cmake --build cmake-build -t godot-cpp-test
MSys2/clang64, "Ninja Multi-Config" - dev_build, Debug Symbols
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Assumes the ming-w64-clang-x86_64-toolchain is installed
This time we are choosing the 'Ninja Multi-Config' generator, so the build
type is specified at build time.
Using the msys2/clang64 shell
.. code-block::
# Assuming our current directory is the godot-cpp source root
cmake -S . -B cmake-build -G"Ninja Multi-Config" -DGODOTCPP_ENABLE_TESTING=YES -DGODOTCPP_DEV_BUILD:BOOL=ON
cmake --build cmake-build -t godot-cpp-test --config Debug
Emscripten for web platform
~~~~~~~~~~~~~~~~~~~~~~~~~~~
I've only tested this on windows so far.
I cloned and installed the latest Emscripten tools to ``c:\emsdk``
At the time of writing that was v3.1.69
I've been using ``C:\emsdk\emsdk.ps1 activate latest`` to enable the
environment from powershell in the current shell.
The ``emcmake.bat`` utility adds the emscripten toolchain to the CMake command
It can also be added manually, the location is listed inside the emcmake.bat file
.. code-block::
# Assuming our current directory is the godot-cpp source root
C:\emsdk\emsdk.ps1 activate latest
emcmake.bat cmake -S . -B cmake-build-web -DCMAKE_BUILD_TYPE=Release
cmake --build cmake-build-web
Android Cross Compile from Windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are two separate paths you can choose when configuring for android.
Use the ``CMAKE_ANDROID_*`` variables specified on the commandline or in your
own toolchain file as listed in the cmake-toolchains_ documentation
.. _cmake-toolchains: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-android-with-the-ndk
Or use the toolchain and scripts provided by the Android SDK and make changes
using the ``ANDROID_*`` variables listed there. Where ``<version>`` is whatever
ndk version you have installed (tested with `28.1.13356709`) and ``<platform>``
is for android sdk platform, (tested with ``android-29``)
.. warning::
The Android SDK website explicitly states that they do not support using
the CMake built-in method, and recommends you stick with their toolchain
files.
.. topic:: Using your own toolchain file as described in the CMake documentation
.. code-block::
# Assuming our current directory is the godot-cpp source root
cmake -S . -B cmake-build --toolchain my_toolchain.cmake
cmake --build cmake-build -t template_release
Doing the equivalent on just using the command line
.. code-block::
# Assuming our current directory is the godot-cpp source root
cmake -S . -B cmake-build \
-DCMAKE_SYSTEM_NAME=Android \
-DCMAKE_SYSTEM_VERSION=<platform> \
-DCMAKE_ANDROID_ARCH_ABI=<arch> \
-DCMAKE_ANDROID_NDK=/path/to/android-ndk
cmake --build cmake-build
.. topic:: Using the toolchain file from the Android SDK
Defaults to minimum supported version( android-16 in my case) and armv7-a.
.. code-block::
# Assuming our current directory is the godot-cpp source root
cmake -S . -B cmake-build --toolchain $ANDROID_HOME/ndk/<version>/build/cmake/android.toolchain.cmake
cmake --build cmake-build
Specify Android platform and ABI
.. code-block::
# Assuming our current directory is the godot-cpp source root
cmake -S . -B cmake-build --toolchain $ANDROID_HOME/ndk/<version>/build/cmake/android.toolchain.cmake \
-DANDROID_PLATFORM:STRING=android-29 \
-DANDROID_ABI:STRING=armeabi-v7a
cmake --build cmake-build
Toolchains
----------
This section attempts to list the host and target combinations that have been
at tested.
Linux Host
~~~~~~~~~~
Macos Host
~~~~~~~~~~
:System: Mac Mini
:OS Name: Sequoia 15.0.1
:Processor: Apple M2
* AppleClang
Windows Host
~~~~~~~~~~~~
:OS Name: Windows 11
:Processor: AMD Ryzen 7 6800HS Creator Edition
* `Microsoft Visual Studio 17 2022 <https://visualstudio.microsoft.com/vs/>`_
* `LLVM <https://llvm.org/>`_
* `LLVM-MinGW <https://github.com/mstorsjo/llvm-mingw/releases>`_
* aarch64-w64-mingw32
* armv7-w64-mingw32
* i686-w64-mingw32
* x86_64-w64-mingw32
* `AndroidSDK <https://developer.android.com/studio/#command-tools>`_
* `Emscripten <https://emscripten.org/>`_
* `MinGW-W64-builds <https://github.com/niXman/mingw-builds-binaries/releases>`_
* `Jetbrains-CLion <https://www.jetbrains.com/clion/>`_
Jetbrains builtin compiler is just the MingW64 above.
* `MSYS2 <https://www.msys2.org/>`_
Necessary reading about MSYS2 `environments <https://www.msys2.org/docs/environments/>`_
* ucrt64
* clang64
* mingw32
* mingw64
* clangarm64

View File

@@ -40,7 +40,7 @@ def generate_doc_source(dst, source):
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"
"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")

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -236,7 +236,7 @@ struct PtrToArg<Ref<T>> {
if (unlikely(!p_ptr)) {
return Ref<T>();
}
return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref))));
return Ref<T>(reinterpret_cast<T *>(::godot::internal::get_object_instance_binding(::godot::gdextension_interface::ref_get_object(ref))));
}
typedef Ref<T> EncodeT;
@@ -248,7 +248,7 @@ struct PtrToArg<Ref<T>> {
// This code assumes that p_ptr points to an unset Ref<T> variable on the Godot side
// so we only set it if we have an object to set.
if (p_val.is_valid()) {
godot::internal::gdextension_interface_ref_set_object(ref, p_val->_owner);
::godot::gdextension_interface::ref_set_object(ref, p_val->_owner);
}
}
};
@@ -262,7 +262,7 @@ struct PtrToArg<const Ref<T> &> {
if (unlikely(!p_ptr)) {
return Ref<T>();
}
return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref))));
return Ref<T>(reinterpret_cast<T *>(::godot::internal::get_object_instance_binding(::godot::gdextension_interface::ref_get_object(ref))));
}
};

View File

@@ -37,7 +37,6 @@
#include <godot_cpp/core/type_info.hpp>
#include <array>
#include <vector>
namespace godot {
@@ -148,7 +147,7 @@ template <typename T>
struct VariantCasterAndValidate {
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDExtensionCallError &r_error) {
GDExtensionVariantType argtype = GDExtensionVariantType(GetTypeInfo<T>::VARIANT_TYPE);
if (!internal::gdextension_interface_variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
if (!::godot::gdextension_interface::variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
r_error.error = GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = p_arg_idx;
@@ -163,7 +162,7 @@ template <typename T>
struct VariantCasterAndValidate<T &> {
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDExtensionCallError &r_error) {
GDExtensionVariantType argtype = GDExtensionVariantType(GetTypeInfo<T>::VARIANT_TYPE);
if (!internal::gdextension_interface_variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
if (!::godot::gdextension_interface::variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
r_error.error = GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = p_arg_idx;
@@ -178,7 +177,7 @@ template <typename T>
struct VariantCasterAndValidate<const T &> {
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDExtensionCallError &r_error) {
GDExtensionVariantType argtype = GDExtensionVariantType(GetTypeInfo<T>::VARIANT_TYPE);
if (!internal::gdextension_interface_variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
if (!::godot::gdextension_interface::variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
r_error.error = GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = p_arg_idx;
@@ -262,6 +261,7 @@ void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), co
#else
r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
#endif
(void)p_args; // Avoid warning.
}
template <typename T, typename R, typename... P, size_t... Is>
@@ -273,7 +273,7 @@ void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) co
#else
r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
#endif
(void)p_args;
(void)p_args; // Avoid warning.
}
template <typename T, typename... P>
@@ -331,7 +331,7 @@ void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, co
}
template <typename T, typename... P>
void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const std::vector<Variant> &default_values) {
void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const LocalVector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
@@ -366,7 +366,7 @@ void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const G
}
template <typename T, typename... P>
void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const, const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const std::vector<Variant> &default_values) {
void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const, const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const LocalVector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
@@ -401,7 +401,7 @@ void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const,
}
template <typename T, typename R, typename... P>
void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error, const std::vector<Variant> &default_values) {
void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error, const LocalVector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
@@ -436,7 +436,7 @@ void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const
}
template <typename T, typename R, typename... P>
void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const, const GDExtensionConstVariantPtr *p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error, const std::vector<Variant> &default_values) {
void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const, const GDExtensionConstVariantPtr *p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error, const LocalVector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
@@ -548,7 +548,7 @@ void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_arg
}
template <typename... P>
void call_with_variant_args_static_dv(void (*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const std::vector<Variant> &default_values) {
void call_with_variant_args_static_dv(void (*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const LocalVector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
@@ -640,7 +640,7 @@ void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_ar
}
template <typename R, typename... P>
void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error, const std::vector<Variant> &default_values) {
void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error, const LocalVector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;

View File

@@ -47,7 +47,7 @@ O *_call_builtin_method_ptr_ret_obj(const GDExtensionPtrBuiltInMethod method, GD
if (ret == nullptr) {
return nullptr;
}
return reinterpret_cast<O *>(internal::get_object_instance_binding(ret));
return reinterpret_cast<O *>(::godot::internal::get_object_instance_binding(ret));
}
template <typename... Args>

View File

@@ -44,19 +44,10 @@
// Needs to come after method_bind and object have been included.
#include <godot_cpp/variant/callable_method_pointer.hpp>
#include <godot_cpp/templates/a_hash_map.hpp>
#include <list>
#include <mutex>
#include <set>
#include <unordered_map>
#include <vector>
// Needed to use StringName as key in `std::unordered_map`
template <>
struct std::hash<godot::StringName> {
std::size_t operator()(godot::StringName const &s) const noexcept {
return s.hash();
}
};
namespace godot {
@@ -94,9 +85,9 @@ public:
StringName name;
StringName parent_name;
GDExtensionInitializationLevel level = GDEXTENSION_INITIALIZATION_SCENE;
std::unordered_map<StringName, MethodBind *> method_map;
AHashMap<StringName, MethodBind *> method_map;
std::set<StringName> signal_names;
std::unordered_map<StringName, VirtualMethod> virtual_methods;
AHashMap<StringName, VirtualMethod> virtual_methods;
std::set<StringName> property_names;
std::set<StringName> constant_names;
// Pointer to the parent custom class, if any. Will be null if the parent class is a Godot class.
@@ -105,11 +96,11 @@ public:
private:
// This may only contain custom classes, not Godot classes
static std::unordered_map<StringName, ClassInfo> classes;
static std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *> instance_binding_callbacks;
static HashMap<StringName, ClassInfo> classes;
static AHashMap<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 LocalVector<StringName> class_register_order;
static AHashMap<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);
@@ -170,9 +161,9 @@ public:
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);
AHashMap<StringName, Object *>::ConstIterator i = engine_singletons.find(p_class_name);
if (i != engine_singletons.end()) {
ERR_FAIL_COND((*i).second != p_singleton);
ERR_FAIL_COND((*i).value != p_singleton);
return;
}
engine_singletons[p_class_name] = p_singleton;
@@ -190,7 +181,7 @@ public:
static MethodBind *bind_static_method(StringName p_class, N p_method_name, M p_method, VarArgs... p_args);
template <typename M>
static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const std::vector<Variant> &p_default_args = std::vector<Variant>{}, bool p_return_nil_is_variant = true);
static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const LocalVector<Variant> &p_default_args = LocalVector<Variant>{}, bool p_return_nil_is_variant = true);
static void add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix);
static void add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix);
@@ -242,10 +233,10 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
cl.name = T::get_class_static();
cl.parent_name = T::get_parent_class_static();
cl.level = current_level;
std::unordered_map<StringName, ClassInfo>::iterator parent_it = classes.find(cl.parent_name);
HashMap<StringName, ClassInfo>::Iterator parent_it = classes.find(cl.parent_name);
if (parent_it != classes.end()) {
// Assign parent if it is also a custom class
cl.parent_ptr = &parent_it->second;
cl.parent_ptr = &parent_it->value;
}
classes[cl.name] = cl;
class_register_order.push_back(cl.name);
@@ -277,7 +268,7 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
(void *)&T::get_class_static(), // void *class_userdata;
};
internal::gdextension_interface_classdb_register_extension_class5(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
::godot::gdextension_interface::classdb_register_extension_class5(::godot::gdextension_interface::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
// call bind_methods etc. to register all members of the class
T::initialize_class();
@@ -330,7 +321,7 @@ MethodBind *ClassDB::bind_static_method(StringName p_class, N p_method_name, M p
}
template <typename M>
MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info, const std::vector<Variant> &p_default_args, bool p_return_nil_is_variant) {
MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info, const LocalVector<Variant> &p_default_args, bool p_return_nil_is_variant) {
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
ERR_FAIL_NULL_V(bind, nullptr);
@@ -339,13 +330,13 @@ MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p
StringName instance_type = bind->get_instance_class();
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(instance_type);
HashMap<StringName, ClassInfo>::Iterator type_it = classes.find(instance_type);
if (type_it == classes.end()) {
memdelete(bind);
ERR_FAIL_V_MSG(nullptr, String("Class '{0}' doesn't exist.").format(Array::make(instance_type)));
}
ClassInfo &type = type_it->second;
ClassInfo &type = type_it->value;
if (type.method_map.find(p_name) != type.method_map.end()) {
memdelete(bind);

View File

@@ -338,4 +338,47 @@ struct is_zero_constructible<const volatile T> : is_zero_constructible<T> {};
template <typename T>
inline constexpr bool is_zero_constructible_v = is_zero_constructible<T>::value;
// Warning suppression helper macros.
#if defined(__clang__)
#define GODOT_CLANG_PRAGMA(m_content) _Pragma(#m_content)
#define GODOT_CLANG_WARNING_PUSH GODOT_CLANG_PRAGMA(clang diagnostic push)
#define GODOT_CLANG_WARNING_IGNORE(m_warning) GODOT_CLANG_PRAGMA(clang diagnostic ignored m_warning)
#define GODOT_CLANG_WARNING_POP GODOT_CLANG_PRAGMA(clang diagnostic pop)
#define GODOT_CLANG_WARNING_PUSH_AND_IGNORE(m_warning) GODOT_CLANG_WARNING_PUSH GODOT_CLANG_WARNING_IGNORE(m_warning)
#else
#define GODOT_CLANG_PRAGMA(m_content)
#define GODOT_CLANG_WARNING_PUSH
#define GODOT_CLANG_WARNING_IGNORE(m_warning)
#define GODOT_CLANG_WARNING_POP
#define GODOT_CLANG_WARNING_PUSH_AND_IGNORE(m_warning)
#endif
#if defined(__GNUC__) && !defined(__clang__)
#define GODOT_GCC_PRAGMA(m_content) _Pragma(#m_content)
#define GODOT_GCC_WARNING_PUSH GODOT_GCC_PRAGMA(GCC diagnostic push)
#define GODOT_GCC_WARNING_IGNORE(m_warning) GODOT_GCC_PRAGMA(GCC diagnostic ignored m_warning)
#define GODOT_GCC_WARNING_POP GODOT_GCC_PRAGMA(GCC diagnostic pop)
#define GODOT_GCC_WARNING_PUSH_AND_IGNORE(m_warning) GODOT_GCC_WARNING_PUSH GODOT_GCC_WARNING_IGNORE(m_warning)
#else
#define GODOT_GCC_PRAGMA(m_content)
#define GODOT_GCC_WARNING_PUSH
#define GODOT_GCC_WARNING_IGNORE(m_warning)
#define GODOT_GCC_WARNING_POP
#define GODOT_GCC_WARNING_PUSH_AND_IGNORE(m_warning)
#endif
#if defined(_MSC_VER) && !defined(__clang__)
#define GODOT_MSVC_PRAGMA(m_content) __pragma(m_content)
#define GODOT_MSVC_WARNING_PUSH GODOT_MSVC_PRAGMA(warning(push))
#define GODOT_MSVC_WARNING_IGNORE(m_warning) GODOT_MSVC_PRAGMA(warning(disable : m_warning))
#define GODOT_MSVC_WARNING_POP GODOT_MSVC_PRAGMA(warning(pop))
#define GODOT_MSVC_WARNING_PUSH_AND_IGNORE(m_warning) GODOT_MSVC_WARNING_PUSH GODOT_MSVC_WARNING_IGNORE(m_warning)
#else
#define GODOT_MSVC_PRAGMA(m_content)
#define GODOT_MSVC_WARNING_PUSH
#define GODOT_MSVC_WARNING_IGNORE(m_warning)
#define GODOT_MSVC_WARNING_POP
#define GODOT_MSVC_WARNING_PUSH_AND_IGNORE(m_warning)
#endif
} //namespace godot

View File

@@ -46,25 +46,25 @@ template <typename O, typename... Args>
O *_call_native_mb_ret_obj(const GDExtensionMethodBindPtr mb, void *instance, const Args &...args) {
GodotObject *ret = nullptr;
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
internal::gdextension_interface_object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
::godot::gdextension_interface::object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
if (ret == nullptr) {
return nullptr;
}
return reinterpret_cast<O *>(internal::get_object_instance_binding(ret));
return reinterpret_cast<O *>(::godot::internal::get_object_instance_binding(ret));
}
template <typename R, typename... Args>
R _call_native_mb_ret(const GDExtensionMethodBindPtr mb, void *instance, const Args &...args) {
typename PtrToArg<R>::EncodeT ret;
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
internal::gdextension_interface_object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
::godot::gdextension_interface::object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
return static_cast<R>(ret);
}
template <typename... Args>
void _call_native_mb_no_ret(const GDExtensionMethodBindPtr mb, void *instance, const Args &...args) {
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
internal::gdextension_interface_object_method_bind_ptrcall(mb, instance, mb_args.data(), nullptr);
::godot::gdextension_interface::object_method_bind_ptrcall(mb, instance, mb_args.data(), nullptr);
}
template <typename R, typename... Args>
@@ -80,7 +80,7 @@ Object *_call_utility_ret_obj(const GDExtensionPtrUtilityFunction func, const Ar
GodotObject *ret = nullptr;
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
func(&ret, mb_args.data(), mb_args.size());
return (Object *)internal::get_object_instance_binding(ret);
return (Object *)::godot::internal::get_object_instance_binding(ret);
}
template <typename... Args>

View File

@@ -0,0 +1,41 @@
/**************************************************************************/
/* load_proc_address.inc */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#pragma once
#define ERR_PRINT_EARLY(m_msg) \
::godot::gdextension_interface::print_error(m_msg, FUNCTION_STR, __FILE__, __LINE__, false)
#define LOAD_PROC_ADDRESS(m_name, m_type) \
::godot::gdextension_interface::m_name = (m_type)p_get_proc_address(#m_name); \
if (!::godot::gdextension_interface::m_name) { \
ERR_PRINT_EARLY("Unable to load GDExtension interface function " #m_name "()"); \
return false; \
}

View File

@@ -112,7 +112,7 @@ void memdelete(T *p_class, typename std::enable_if<!std::is_base_of_v<godot::Wra
template <typename T, std::enable_if_t<std::is_base_of_v<godot::Wrapped, T>, bool> = true>
void memdelete(T *p_class) {
godot::internal::gdextension_interface_object_destroy(p_class->_owner);
::godot::gdextension_interface::object_destroy(p_class->_owner);
}
template <typename T, typename A>

View File

@@ -38,8 +38,7 @@
#include <gdextension_interface.h>
#include <godot_cpp/classes/global_constants.hpp>
#include <vector>
#include <godot_cpp/templates/local_vector.hpp>
namespace godot {
@@ -54,9 +53,9 @@ class MethodBind {
bool _returns = false;
bool _vararg = false;
std::vector<StringName> argument_names;
LocalVector<StringName> argument_names;
GDExtensionVariantType *argument_types = nullptr;
std::vector<Variant> default_arguments;
LocalVector<Variant> default_arguments;
protected:
void _set_const(bool p_const);
@@ -70,7 +69,7 @@ protected:
void set_argument_count(int p_count) { argument_count = p_count; }
public:
_FORCE_INLINE_ const std::vector<Variant> &get_default_arguments() const { return default_arguments; }
_FORCE_INLINE_ const LocalVector<Variant> &get_default_arguments() const { return default_arguments; }
_FORCE_INLINE_ int get_default_argument_count() const { return (int)default_arguments.size(); }
_FORCE_INLINE_ Variant has_default_argument(int p_arg) const {
@@ -101,8 +100,8 @@ public:
PropertyInfo get_argument_info(int p_argument) const;
std::vector<PropertyInfo> get_arguments_info_list() const {
std::vector<PropertyInfo> vec;
LocalVector<PropertyInfo> get_arguments_info_list() const {
LocalVector<PropertyInfo> vec;
// First element is return value
vec.reserve(argument_count + 1);
for (int i = 0; i < argument_count + 1; i++) {
@@ -111,8 +110,8 @@ public:
return vec;
}
void set_argument_names(const std::vector<StringName> &p_names);
std::vector<StringName> get_argument_names() const;
void set_argument_names(const LocalVector<StringName> &p_names);
LocalVector<StringName> get_argument_names() const;
virtual GDExtensionClassMethodArgumentMetadata get_argument_metadata(int p_argument) const = 0;
@@ -133,10 +132,10 @@ public:
_FORCE_INLINE_ bool is_vararg() const { return _vararg; }
_FORCE_INLINE_ bool has_return() const { return _returns; }
void set_default_arguments(const std::vector<Variant> &p_default_arguments) { default_arguments = p_default_arguments; }
void set_default_arguments(const LocalVector<Variant> &p_default_arguments) { default_arguments = p_default_arguments; }
std::vector<GDExtensionClassMethodArgumentMetadata> get_arguments_metadata_list() const {
std::vector<GDExtensionClassMethodArgumentMetadata> vec;
LocalVector<GDExtensionClassMethodArgumentMetadata> get_arguments_metadata_list() const {
LocalVector<GDExtensionClassMethodArgumentMetadata> vec;
// First element is return value
vec.reserve(argument_count + 1);
for (int i = 0; i < argument_count + 1; i++) {
@@ -155,7 +154,7 @@ template <typename Derived, typename T, typename R, bool should_returns>
class MethodBindVarArgBase : public MethodBind {
protected:
R (T::*method)(const Variant **, GDExtensionInt, GDExtensionCallError &);
std::vector<PropertyInfo> arguments;
LocalVector<PropertyInfo> arguments;
public:
virtual PropertyInfo gen_argument_type_info(int p_arg) const {
@@ -191,7 +190,7 @@ public:
if (p_method_info.arguments.size()) {
arguments = p_method_info.arguments;
std::vector<StringName> names;
LocalVector<StringName> names;
names.reserve(p_method_info.arguments.size());
for (size_t i = 0; i < p_method_info.arguments.size(); i++) {
names.push_back(p_method_info.arguments[i].name);

View File

@@ -173,7 +173,7 @@ template <typename T>
struct PtrToArg<T *> {
static_assert(std::is_base_of<Object, T>::value, "Cannot encode non-Object value as an Object");
_FORCE_INLINE_ static T *convert(const void *p_ptr) {
return likely(p_ptr) ? reinterpret_cast<T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)))) : nullptr;
return likely(p_ptr) ? reinterpret_cast<T *>(::godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)))) : nullptr;
}
typedef Object *EncodeT;
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
@@ -185,7 +185,7 @@ template <typename T>
struct PtrToArg<const T *> {
static_assert(std::is_base_of<Object, T>::value, "Cannot encode non-Object value as an Object");
_FORCE_INLINE_ static const T *convert(const void *p_ptr) {
return likely(p_ptr) ? reinterpret_cast<const T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)))) : nullptr;
return likely(p_ptr) ? reinterpret_cast<const T *>(::godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)))) : nullptr;
}
typedef const Object *EncodeT;
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {

View File

@@ -38,14 +38,14 @@
#include <godot_cpp/variant/variant.hpp>
#include <godot_cpp/templates/local_vector.hpp>
#include <godot_cpp/classes/object.hpp>
#include <godot_cpp/godot.hpp>
#include <gdextension_interface.h>
#include <vector>
#define ADD_SIGNAL(m_signal) ::godot::ClassDB::add_signal(get_class_static(), m_signal)
#define ADD_GROUP(m_name, m_prefix) ::godot::ClassDB::add_property_group(get_class_static(), m_name, m_prefix)
#define ADD_SUBGROUP(m_name, m_prefix) ::godot::ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix)
@@ -65,10 +65,10 @@ struct MethodInfo {
PropertyInfo return_val;
uint32_t flags;
int id = 0;
std::vector<PropertyInfo> arguments;
std::vector<Variant> default_arguments;
LocalVector<PropertyInfo> arguments;
LocalVector<Variant> default_arguments;
GDExtensionClassMethodArgumentMetadata return_val_metadata;
std::vector<GDExtensionClassMethodArgumentMetadata> arguments_metadata;
LocalVector<GDExtensionClassMethodArgumentMetadata> arguments_metadata;
inline bool operator==(const MethodInfo &p_method) const { return id == p_method.id; }
inline bool operator<(const MethodInfo &p_method) const { return id == p_method.id ? (name < p_method.name) : (id < p_method.id); }
@@ -92,31 +92,27 @@ struct MethodInfo {
template <typename... Args>
MethodInfo::MethodInfo(StringName p_name, const Args &...args) :
name(p_name), flags(GDEXTENSION_METHOD_FLAG_NORMAL) {
arguments = { args... };
}
name(p_name), flags(GDEXTENSION_METHOD_FLAG_NORMAL), arguments({ args... }) {}
template <typename... Args>
MethodInfo::MethodInfo(Variant::Type ret, StringName p_name, const Args &...args) :
name(p_name), flags(GDEXTENSION_METHOD_FLAG_NORMAL) {
name(p_name), flags(GDEXTENSION_METHOD_FLAG_NORMAL), arguments({ args... }) {
return_val.type = ret;
arguments = { args... };
}
template <typename... Args>
MethodInfo::MethodInfo(const PropertyInfo &p_ret, StringName p_name, const Args &...args) :
name(p_name), return_val(p_ret), flags(GDEXTENSION_METHOD_FLAG_NORMAL) {
arguments = { args... };
name(p_name), return_val(p_ret), flags(GDEXTENSION_METHOD_FLAG_NORMAL), arguments({ args... }) {
}
class ObjectDB {
public:
static Object *get_instance(uint64_t p_object_id) {
GDExtensionObjectPtr obj = internal::gdextension_interface_object_get_instance_from_id(p_object_id);
GDExtensionObjectPtr obj = ::godot::gdextension_interface::object_get_instance_from_id(p_object_id);
if (obj == nullptr) {
return nullptr;
}
return internal::get_object_instance_binding(obj);
return ::godot::internal::get_object_instance_binding(obj);
}
};
@@ -126,11 +122,11 @@ T *Object::cast_to(Object *p_object) {
return nullptr;
}
StringName class_name = T::get_class_static();
GDExtensionObjectPtr casted = internal::gdextension_interface_object_cast_to(p_object->_owner, internal::gdextension_interface_classdb_get_class_tag(class_name._native_ptr()));
GDExtensionObjectPtr casted = ::godot::gdextension_interface::object_cast_to(p_object->_owner, ::godot::gdextension_interface::classdb_get_class_tag(class_name._native_ptr()));
if (casted == nullptr) {
return nullptr;
}
return dynamic_cast<T *>(internal::get_object_instance_binding(casted));
return dynamic_cast<T *>(::godot::internal::get_object_instance_binding(casted));
}
template <typename T>
@@ -139,11 +135,11 @@ const T *Object::cast_to(const Object *p_object) {
return nullptr;
}
StringName class_name = T::get_class_static();
GDExtensionObjectPtr casted = internal::gdextension_interface_object_cast_to(p_object->_owner, internal::gdextension_interface_classdb_get_class_tag(class_name._native_ptr()));
GDExtensionObjectPtr casted = ::godot::gdextension_interface::object_cast_to(p_object->_owner, ::godot::gdextension_interface::classdb_get_class_tag(class_name._native_ptr()));
if (casted == nullptr) {
return nullptr;
}
return dynamic_cast<const T *>(internal::get_object_instance_binding(casted));
return dynamic_cast<const T *>(::godot::internal::get_object_instance_binding(casted));
}
} // namespace godot

View File

@@ -30,180 +30,21 @@
#pragma once
#include <gdextension_interface.h>
#include <godot_cpp/core/gdextension_interface_loader.hpp>
namespace godot {
namespace internal {
namespace gdextension_interface {
extern "C" GDExtensionInterfaceGetProcAddress gdextension_interface_get_proc_address;
extern "C" GDExtensionInterfaceGetProcAddress get_proc_address;
extern "C" GDExtensionClassLibraryPtr library;
extern "C" void *token;
extern "C" GDExtensionGodotVersion2 godot_version;
// All of the GDExtension interface functions.
extern "C" GDExtensionInterfaceGetGodotVersion2 gdextension_interface_get_godot_version2;
extern "C" GDExtensionInterfaceMemAlloc gdextension_interface_mem_alloc;
extern "C" GDExtensionInterfaceMemRealloc gdextension_interface_mem_realloc;
extern "C" GDExtensionInterfaceMemFree gdextension_interface_mem_free;
extern "C" GDExtensionInterfacePrintError gdextension_interface_print_error;
extern "C" GDExtensionInterfacePrintErrorWithMessage gdextension_interface_print_error_with_message;
extern "C" GDExtensionInterfacePrintWarning gdextension_interface_print_warning;
extern "C" GDExtensionInterfacePrintWarningWithMessage gdextension_interface_print_warning_with_message;
extern "C" GDExtensionInterfacePrintScriptError gdextension_interface_print_script_error;
extern "C" GDExtensionInterfacePrintScriptErrorWithMessage gdextension_interface_print_script_error_with_message;
extern "C" GDExtensionInterfaceGetNativeStructSize gdextension_interface_get_native_struct_size;
extern "C" GDExtensionInterfaceVariantNewCopy gdextension_interface_variant_new_copy;
extern "C" GDExtensionInterfaceVariantNewNil gdextension_interface_variant_new_nil;
extern "C" GDExtensionInterfaceVariantDestroy gdextension_interface_variant_destroy;
extern "C" GDExtensionInterfaceVariantCall gdextension_interface_variant_call;
extern "C" GDExtensionInterfaceVariantCallStatic gdextension_interface_variant_call_static;
extern "C" GDExtensionInterfaceVariantEvaluate gdextension_interface_variant_evaluate;
extern "C" GDExtensionInterfaceVariantSet gdextension_interface_variant_set;
extern "C" GDExtensionInterfaceVariantSetNamed gdextension_interface_variant_set_named;
extern "C" GDExtensionInterfaceVariantSetKeyed gdextension_interface_variant_set_keyed;
extern "C" GDExtensionInterfaceVariantSetIndexed gdextension_interface_variant_set_indexed;
extern "C" GDExtensionInterfaceVariantGet gdextension_interface_variant_get;
extern "C" GDExtensionInterfaceVariantGetNamed gdextension_interface_variant_get_named;
extern "C" GDExtensionInterfaceVariantGetKeyed gdextension_interface_variant_get_keyed;
extern "C" GDExtensionInterfaceVariantGetIndexed gdextension_interface_variant_get_indexed;
extern "C" GDExtensionInterfaceVariantIterInit gdextension_interface_variant_iter_init;
extern "C" GDExtensionInterfaceVariantIterNext gdextension_interface_variant_iter_next;
extern "C" GDExtensionInterfaceVariantIterGet gdextension_interface_variant_iter_get;
extern "C" GDExtensionInterfaceVariantHash gdextension_interface_variant_hash;
extern "C" GDExtensionInterfaceVariantRecursiveHash gdextension_interface_variant_recursive_hash;
extern "C" GDExtensionInterfaceVariantHashCompare gdextension_interface_variant_hash_compare;
extern "C" GDExtensionInterfaceVariantBooleanize gdextension_interface_variant_booleanize;
extern "C" GDExtensionInterfaceVariantDuplicate gdextension_interface_variant_duplicate;
extern "C" GDExtensionInterfaceVariantStringify gdextension_interface_variant_stringify;
extern "C" GDExtensionInterfaceVariantGetType gdextension_interface_variant_get_type;
extern "C" GDExtensionInterfaceVariantHasMethod gdextension_interface_variant_has_method;
extern "C" GDExtensionInterfaceVariantHasMember gdextension_interface_variant_has_member;
extern "C" GDExtensionInterfaceVariantHasKey gdextension_interface_variant_has_key;
extern "C" GDExtensionInterfaceVariantGetObjectInstanceId gdextension_interface_variant_get_object_instance_id;
extern "C" GDExtensionInterfaceVariantGetTypeName gdextension_interface_variant_get_type_name;
extern "C" GDExtensionInterfaceVariantCanConvert gdextension_interface_variant_can_convert;
extern "C" GDExtensionInterfaceVariantCanConvertStrict gdextension_interface_variant_can_convert_strict;
extern "C" GDExtensionInterfaceGetVariantFromTypeConstructor gdextension_interface_get_variant_from_type_constructor;
extern "C" GDExtensionInterfaceGetVariantToTypeConstructor gdextension_interface_get_variant_to_type_constructor;
extern "C" GDExtensionInterfaceGetVariantGetInternalPtrFunc gdextension_interface_variant_get_ptr_internal_getter;
extern "C" GDExtensionInterfaceVariantGetPtrOperatorEvaluator gdextension_interface_variant_get_ptr_operator_evaluator;
extern "C" GDExtensionInterfaceVariantGetPtrBuiltinMethod gdextension_interface_variant_get_ptr_builtin_method;
extern "C" GDExtensionInterfaceVariantGetPtrConstructor gdextension_interface_variant_get_ptr_constructor;
extern "C" GDExtensionInterfaceVariantGetPtrDestructor gdextension_interface_variant_get_ptr_destructor;
extern "C" GDExtensionInterfaceVariantConstruct gdextension_interface_variant_construct;
extern "C" GDExtensionInterfaceVariantGetPtrSetter gdextension_interface_variant_get_ptr_setter;
extern "C" GDExtensionInterfaceVariantGetPtrGetter gdextension_interface_variant_get_ptr_getter;
extern "C" GDExtensionInterfaceVariantGetPtrIndexedSetter gdextension_interface_variant_get_ptr_indexed_setter;
extern "C" GDExtensionInterfaceVariantGetPtrIndexedGetter gdextension_interface_variant_get_ptr_indexed_getter;
extern "C" GDExtensionInterfaceVariantGetPtrKeyedSetter gdextension_interface_variant_get_ptr_keyed_setter;
extern "C" GDExtensionInterfaceVariantGetPtrKeyedGetter gdextension_interface_variant_get_ptr_keyed_getter;
extern "C" GDExtensionInterfaceVariantGetPtrKeyedChecker gdextension_interface_variant_get_ptr_keyed_checker;
extern "C" GDExtensionInterfaceVariantGetConstantValue gdextension_interface_variant_get_constant_value;
extern "C" GDExtensionInterfaceVariantGetPtrUtilityFunction gdextension_interface_variant_get_ptr_utility_function;
extern "C" GDExtensionInterfaceStringNewWithLatin1Chars gdextension_interface_string_new_with_latin1_chars;
extern "C" GDExtensionInterfaceStringNewWithUtf8Chars gdextension_interface_string_new_with_utf8_chars;
extern "C" GDExtensionInterfaceStringNewWithUtf16Chars gdextension_interface_string_new_with_utf16_chars;
extern "C" GDExtensionInterfaceStringNewWithUtf32Chars gdextension_interface_string_new_with_utf32_chars;
extern "C" GDExtensionInterfaceStringNewWithWideChars gdextension_interface_string_new_with_wide_chars;
extern "C" GDExtensionInterfaceStringNewWithLatin1CharsAndLen gdextension_interface_string_new_with_latin1_chars_and_len;
extern "C" GDExtensionInterfaceStringNewWithUtf8CharsAndLen gdextension_interface_string_new_with_utf8_chars_and_len;
extern "C" GDExtensionInterfaceStringNewWithUtf8CharsAndLen2 gdextension_interface_string_new_with_utf8_chars_and_len2;
extern "C" GDExtensionInterfaceStringNewWithUtf16CharsAndLen gdextension_interface_string_new_with_utf16_chars_and_len;
extern "C" GDExtensionInterfaceStringNewWithUtf16CharsAndLen2 gdextension_interface_string_new_with_utf16_chars_and_len2;
extern "C" GDExtensionInterfaceStringNewWithUtf32CharsAndLen gdextension_interface_string_new_with_utf32_chars_and_len;
extern "C" GDExtensionInterfaceStringNewWithWideCharsAndLen gdextension_interface_string_new_with_wide_chars_and_len;
extern "C" GDExtensionInterfaceStringToLatin1Chars gdextension_interface_string_to_latin1_chars;
extern "C" GDExtensionInterfaceStringToUtf8Chars gdextension_interface_string_to_utf8_chars;
extern "C" GDExtensionInterfaceStringToUtf16Chars gdextension_interface_string_to_utf16_chars;
extern "C" GDExtensionInterfaceStringToUtf32Chars gdextension_interface_string_to_utf32_chars;
extern "C" GDExtensionInterfaceStringToWideChars gdextension_interface_string_to_wide_chars;
extern "C" GDExtensionInterfaceStringOperatorIndex gdextension_interface_string_operator_index;
extern "C" GDExtensionInterfaceStringOperatorIndexConst gdextension_interface_string_operator_index_const;
extern "C" GDExtensionInterfaceStringOperatorPlusEqString gdextension_interface_string_operator_plus_eq_string;
extern "C" GDExtensionInterfaceStringOperatorPlusEqChar gdextension_interface_string_operator_plus_eq_char;
extern "C" GDExtensionInterfaceStringOperatorPlusEqCstr gdextension_interface_string_operator_plus_eq_cstr;
extern "C" GDExtensionInterfaceStringOperatorPlusEqWcstr gdextension_interface_string_operator_plus_eq_wcstr;
extern "C" GDExtensionInterfaceStringOperatorPlusEqC32str gdextension_interface_string_operator_plus_eq_c32str;
extern "C" GDExtensionInterfaceStringResize gdextension_interface_string_resize;
extern "C" GDExtensionInterfaceStringNameNewWithLatin1Chars gdextension_interface_string_name_new_with_latin1_chars;
extern "C" GDExtensionInterfaceXmlParserOpenBuffer gdextension_interface_xml_parser_open_buffer;
extern "C" GDExtensionInterfaceFileAccessStoreBuffer gdextension_interface_file_access_store_buffer;
extern "C" GDExtensionInterfaceFileAccessGetBuffer gdextension_interface_file_access_get_buffer;
extern "C" GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask gdextension_interface_worker_thread_pool_add_native_group_task;
extern "C" GDExtensionInterfaceWorkerThreadPoolAddNativeTask gdextension_interface_worker_thread_pool_add_native_task;
extern "C" GDExtensionInterfacePackedByteArrayOperatorIndex gdextension_interface_packed_byte_array_operator_index;
extern "C" GDExtensionInterfacePackedByteArrayOperatorIndexConst gdextension_interface_packed_byte_array_operator_index_const;
extern "C" GDExtensionInterfacePackedColorArrayOperatorIndex gdextension_interface_packed_color_array_operator_index;
extern "C" GDExtensionInterfacePackedColorArrayOperatorIndexConst gdextension_interface_packed_color_array_operator_index_const;
extern "C" GDExtensionInterfacePackedFloat32ArrayOperatorIndex gdextension_interface_packed_float32_array_operator_index;
extern "C" GDExtensionInterfacePackedFloat32ArrayOperatorIndexConst gdextension_interface_packed_float32_array_operator_index_const;
extern "C" GDExtensionInterfacePackedFloat64ArrayOperatorIndex gdextension_interface_packed_float64_array_operator_index;
extern "C" GDExtensionInterfacePackedFloat64ArrayOperatorIndexConst gdextension_interface_packed_float64_array_operator_index_const;
extern "C" GDExtensionInterfacePackedInt32ArrayOperatorIndex gdextension_interface_packed_int32_array_operator_index;
extern "C" GDExtensionInterfacePackedInt32ArrayOperatorIndexConst gdextension_interface_packed_int32_array_operator_index_const;
extern "C" GDExtensionInterfacePackedInt64ArrayOperatorIndex gdextension_interface_packed_int64_array_operator_index;
extern "C" GDExtensionInterfacePackedInt64ArrayOperatorIndexConst gdextension_interface_packed_int64_array_operator_index_const;
extern "C" GDExtensionInterfacePackedStringArrayOperatorIndex gdextension_interface_packed_string_array_operator_index;
extern "C" GDExtensionInterfacePackedStringArrayOperatorIndexConst gdextension_interface_packed_string_array_operator_index_const;
extern "C" GDExtensionInterfacePackedVector2ArrayOperatorIndex gdextension_interface_packed_vector2_array_operator_index;
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" GDExtensionInterfaceArraySetTyped gdextension_interface_array_set_typed;
extern "C" GDExtensionInterfaceDictionaryOperatorIndex gdextension_interface_dictionary_operator_index;
extern "C" GDExtensionInterfaceDictionaryOperatorIndexConst gdextension_interface_dictionary_operator_index_const;
extern "C" GDExtensionInterfaceDictionarySetTyped gdextension_interface_dictionary_set_typed;
extern "C" GDExtensionInterfaceObjectMethodBindCall gdextension_interface_object_method_bind_call;
extern "C" GDExtensionInterfaceObjectMethodBindPtrcall gdextension_interface_object_method_bind_ptrcall;
extern "C" GDExtensionInterfaceObjectDestroy gdextension_interface_object_destroy;
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;
extern "C" GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id;
extern "C" GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id;
extern "C" GDExtensionInterfaceObjectHasScriptMethod gdextension_interface_object_has_script_method;
extern "C" GDExtensionInterfaceObjectCallScriptMethod gdextension_interface_object_call_script_method;
extern "C" GDExtensionInterfaceCallableCustomCreate2 gdextension_interface_callable_custom_create2;
extern "C" GDExtensionInterfaceCallableCustomGetUserData gdextension_interface_callable_custom_get_userdata;
extern "C" GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object;
extern "C" GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object;
extern "C" GDExtensionInterfaceScriptInstanceCreate3 gdextension_interface_script_instance_create3;
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create;
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update;
extern "C" GDExtensionInterfaceObjectGetScriptInstance gdextension_interface_object_get_script_instance;
extern "C" GDExtensionInterfaceObjectSetScriptInstance gdextension_interface_object_set_script_instance;
extern "C" GDExtensionInterfaceClassdbConstructObject2 gdextension_interface_classdb_construct_object2;
extern "C" GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind;
extern "C" GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass5 gdextension_interface_classdb_register_extension_class5;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup gdextension_interface_classdb_register_extension_class_property_group;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup gdextension_interface_classdb_register_extension_class_property_subgroup;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassSignal gdextension_interface_classdb_register_extension_class_signal;
extern "C" GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_interface_classdb_unregister_extension_class;
extern "C" GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path;
extern "C" GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin;
extern "C" GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin;
extern "C" GDExtensionInterfaceEditorRegisterGetClassesUsedCallback gdextension_interface_editor_register_get_classes_used_callback;
extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars;
extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len;
extern "C" GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw;
extern "C" GDExtensionInterfaceImagePtr gdextension_interface_image_ptr;
extern "C" GDExtensionInterfaceRegisterMainLoopCallbacks gdextension_interface_register_main_loop_callbacks;
} // namespace gdextension_interface
namespace internal {
class DocDataRegistration {
public:

View File

@@ -0,0 +1,734 @@
/**************************************************************************/
/* a_hash_map.hpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#pragma once
#include <godot_cpp/templates/hash_map.hpp>
namespace godot {
struct HashMapData {
union {
uint64_t data;
struct
{
uint32_t hash;
uint32_t hash_to_key;
};
};
};
static_assert(sizeof(HashMapData) == 8);
/**
* An array-based implementation of a hash map. It is very efficient in terms of performance and
* memory usage. Works like a dynamic array, adding elements to the end of the array, and
* allows you to access array elements by their index by using `get_by_index` method.
* Example:
* ```
* AHashMap<int, Object *> map;
*
* int get_object_id_by_number(int p_number) {
* int id = map.get_index(p_number);
* return id;
* }
*
* Object *get_object_by_id(int p_id) {
* map.get_by_index(p_id).value;
* }
* ```
* Still, don`t erase the elements because ID can break.
*
* When an element erase, its place is taken by the element from the end.
*
* <-------------
* | |
* 6 8 X 9 32 -1 5 -10 7 X X X
* 6 8 7 9 32 -1 5 -10 X X X X
*
*
* Use RBMap if you need to iterate over sorted elements.
*
* Use HashMap if:
* - You need to keep an iterator or const pointer to Key and you intend to add/remove elements in the meantime.
* - You need to preserve the insertion order when using erase.
*
* It is recommended to use `HashMap` if `KeyValue` size is very large.
*/
template <typename TKey, typename TValue,
typename Hasher = HashMapHasherDefault,
typename Comparator = HashMapComparatorDefault<TKey>>
class AHashMap {
public:
// Must be a power of two.
static constexpr uint32_t INITIAL_CAPACITY = 16;
static constexpr uint32_t EMPTY_HASH = 0;
static_assert(EMPTY_HASH == 0, "EMPTY_HASH must always be 0 for the memcpy() optimization.");
private:
typedef KeyValue<TKey, TValue> MapKeyValue;
MapKeyValue *elements = nullptr;
HashMapData *map_data = nullptr;
// Due to optimization, this is `capacity - 1`. Use + 1 to get normal capacity.
uint32_t capacity = 0;
uint32_t num_elements = 0;
uint32_t _hash(const TKey &p_key) const {
uint32_t hash = Hasher::hash(p_key);
if (unlikely(hash == EMPTY_HASH)) {
hash = EMPTY_HASH + 1;
}
return hash;
}
static _FORCE_INLINE_ uint32_t _get_resize_count(uint32_t p_capacity) {
return p_capacity ^ (p_capacity + 1) >> 2; // = get_capacity() * 0.75 - 1; Works only if p_capacity = 2^n - 1.
}
static _FORCE_INLINE_ uint32_t _get_probe_length(uint32_t p_pos, uint32_t p_hash, uint32_t p_local_capacity) {
const uint32_t original_pos = p_hash & p_local_capacity;
return (p_pos - original_pos + p_local_capacity + 1) & p_local_capacity;
}
bool _lookup_pos(const TKey &p_key, uint32_t &r_pos, uint32_t &r_hash_pos) const {
if (unlikely(elements == nullptr)) {
return false; // Failed lookups, no elements.
}
return _lookup_pos_with_hash(p_key, r_pos, r_hash_pos, _hash(p_key));
}
bool _lookup_pos_with_hash(const TKey &p_key, uint32_t &r_pos, uint32_t &r_hash_pos, uint32_t p_hash) const {
if (unlikely(elements == nullptr)) {
return false; // Failed lookups, no elements.
}
uint32_t pos = p_hash & capacity;
HashMapData data = map_data[pos];
if (data.hash == p_hash && Comparator::compare(elements[data.hash_to_key].key, p_key)) {
r_pos = data.hash_to_key;
r_hash_pos = pos;
return true;
}
if (data.data == EMPTY_HASH) {
return false;
}
// A collision occurred.
pos = (pos + 1) & capacity;
uint32_t distance = 1;
while (true) {
data = map_data[pos];
if (data.hash == p_hash && Comparator::compare(elements[data.hash_to_key].key, p_key)) {
r_pos = data.hash_to_key;
r_hash_pos = pos;
return true;
}
if (data.data == EMPTY_HASH) {
return false;
}
if (distance > _get_probe_length(pos, data.hash, capacity)) {
return false;
}
pos = (pos + 1) & capacity;
distance++;
}
}
uint32_t _insert_with_hash(uint32_t p_hash, uint32_t p_index) {
uint32_t pos = p_hash & capacity;
if (map_data[pos].data == EMPTY_HASH) {
uint64_t data = ((uint64_t)p_index << 32) | p_hash;
map_data[pos].data = data;
return pos;
}
uint32_t distance = 1;
pos = (pos + 1) & capacity;
HashMapData c_data;
c_data.hash = p_hash;
c_data.hash_to_key = p_index;
while (true) {
if (map_data[pos].data == EMPTY_HASH) {
#ifdef DEV_ENABLED
if (unlikely(distance > 12)) {
WARN_PRINT("Excessive collision count (" +
itos(distance) + "), is the right hash function being used?");
}
#endif
map_data[pos] = c_data;
return pos;
}
// Not an empty slot, let's check the probing length of the existing one.
uint32_t existing_probe_len = _get_probe_length(pos, map_data[pos].hash, capacity);
if (existing_probe_len < distance) {
SWAP(c_data, map_data[pos]);
distance = existing_probe_len;
}
pos = (pos + 1) & capacity;
distance++;
}
}
void _resize_and_rehash(uint32_t p_new_capacity) {
uint32_t real_old_capacity = capacity + 1;
// Capacity can't be 0 and must be 2^n - 1.
capacity = MAX(4u, p_new_capacity);
uint32_t real_capacity = next_power_of_2(capacity);
capacity = real_capacity - 1;
HashMapData *old_map_data = map_data;
map_data = reinterpret_cast<HashMapData *>(Memory::alloc_static(sizeof(HashMapData) * real_capacity));
memset(map_data, 0, sizeof(HashMapData) * real_capacity);
elements = reinterpret_cast<MapKeyValue *>(Memory::realloc_static(elements, sizeof(MapKeyValue) * (_get_resize_count(capacity) + 1)));
if (num_elements != 0) {
for (uint32_t i = 0; i < real_old_capacity; i++) {
HashMapData data = old_map_data[i];
if (data.data != EMPTY_HASH) {
_insert_with_hash(data.hash, data.hash_to_key);
}
}
}
Memory::free_static(old_map_data);
}
int32_t _insert_element(const TKey &p_key, const TValue &p_value, uint32_t p_hash) {
if (unlikely(elements == nullptr)) {
// Allocate on demand to save memory.
uint32_t real_capacity = capacity + 1;
map_data = reinterpret_cast<HashMapData *>(Memory::alloc_static(sizeof(HashMapData) * real_capacity));
memset(map_data, 0, sizeof(HashMapData) * real_capacity);
elements = reinterpret_cast<MapKeyValue *>(Memory::alloc_static(sizeof(MapKeyValue) * (_get_resize_count(capacity) + 1)));
}
if (unlikely(num_elements > _get_resize_count(capacity))) {
_resize_and_rehash(capacity * 2);
}
memnew_placement(&elements[num_elements], MapKeyValue(p_key, p_value));
_insert_with_hash(p_hash, num_elements);
num_elements++;
return num_elements - 1;
}
void _init_from(const AHashMap &p_other) {
capacity = p_other.capacity;
uint32_t real_capacity = capacity + 1;
num_elements = p_other.num_elements;
if (p_other.num_elements == 0) {
return;
}
map_data = reinterpret_cast<HashMapData *>(Memory::alloc_static(sizeof(HashMapData) * real_capacity));
elements = reinterpret_cast<MapKeyValue *>(Memory::alloc_static(sizeof(MapKeyValue) * (_get_resize_count(capacity) + 1)));
if constexpr (std::is_trivially_copyable_v<TKey> && std::is_trivially_copyable_v<TValue>) {
void *destination = elements;
const void *source = p_other.elements;
memcpy(destination, source, sizeof(MapKeyValue) * num_elements);
} else {
for (uint32_t i = 0; i < num_elements; i++) {
memnew_placement(&elements[i], MapKeyValue(p_other.elements[i]));
}
}
memcpy(map_data, p_other.map_data, sizeof(HashMapData) * real_capacity);
}
public:
/* Standard Godot Container API */
_FORCE_INLINE_ uint32_t get_capacity() const { return capacity + 1; }
_FORCE_INLINE_ uint32_t size() const { return num_elements; }
_FORCE_INLINE_ bool is_empty() const {
return num_elements == 0;
}
void clear() {
if (elements == nullptr || num_elements == 0) {
return;
}
memset(map_data, EMPTY_HASH, (capacity + 1) * sizeof(HashMapData));
if constexpr (!(std::is_trivially_destructible_v<TKey> && std::is_trivially_destructible_v<TValue>)) {
for (uint32_t i = 0; i < num_elements; i++) {
elements[i].key.~TKey();
elements[i].value.~TValue();
}
}
num_elements = 0;
}
TValue &get(const TKey &p_key) {
uint32_t pos = 0;
uint32_t hash_pos = 0;
bool exists = _lookup_pos(p_key, pos, hash_pos);
CRASH_COND_MSG(!exists, "AHashMap key not found.");
return elements[pos].value;
}
const TValue &get(const TKey &p_key) const {
uint32_t pos = 0;
uint32_t hash_pos = 0;
bool exists = _lookup_pos(p_key, pos, hash_pos);
CRASH_COND_MSG(!exists, "AHashMap key not found.");
return elements[pos].value;
}
const TValue *getptr(const TKey &p_key) const {
uint32_t pos = 0;
uint32_t hash_pos = 0;
bool exists = _lookup_pos(p_key, pos, hash_pos);
if (exists) {
return &elements[pos].value;
}
return nullptr;
}
TValue *getptr(const TKey &p_key) {
uint32_t pos = 0;
uint32_t hash_pos = 0;
bool exists = _lookup_pos(p_key, pos, hash_pos);
if (exists) {
return &elements[pos].value;
}
return nullptr;
}
bool has(const TKey &p_key) const {
uint32_t _pos = 0;
uint32_t h_pos = 0;
return _lookup_pos(p_key, _pos, h_pos);
}
bool erase(const TKey &p_key) {
uint32_t pos = 0;
uint32_t element_pos = 0;
bool exists = _lookup_pos(p_key, element_pos, pos);
if (!exists) {
return false;
}
uint32_t next_pos = (pos + 1) & capacity;
while (map_data[next_pos].hash != EMPTY_HASH && _get_probe_length(next_pos, map_data[next_pos].hash, capacity) != 0) {
SWAP(map_data[next_pos], map_data[pos]);
pos = next_pos;
next_pos = (next_pos + 1) & capacity;
}
map_data[pos].data = EMPTY_HASH;
elements[element_pos].key.~TKey();
elements[element_pos].value.~TValue();
num_elements--;
if (element_pos < num_elements) {
void *destination = &elements[element_pos];
const void *source = &elements[num_elements];
memcpy(destination, source, sizeof(MapKeyValue));
uint32_t h_pos = 0;
_lookup_pos(elements[num_elements].key, pos, h_pos);
map_data[h_pos].hash_to_key = element_pos;
}
return true;
}
// Replace the key of an entry in-place, without invalidating iterators or changing the entries position during iteration.
// p_old_key must exist in the map and p_new_key must not, unless it is equal to p_old_key.
bool replace_key(const TKey &p_old_key, const TKey &p_new_key) {
if (p_old_key == p_new_key) {
return true;
}
uint32_t pos = 0;
uint32_t element_pos = 0;
ERR_FAIL_COND_V(_lookup_pos(p_new_key, element_pos, pos), false);
ERR_FAIL_COND_V(!_lookup_pos(p_old_key, element_pos, pos), false);
MapKeyValue &element = elements[element_pos];
const_cast<TKey &>(element.key) = p_new_key;
uint32_t next_pos = (pos + 1) & capacity;
while (map_data[next_pos].hash != EMPTY_HASH && _get_probe_length(next_pos, map_data[next_pos].hash, capacity) != 0) {
SWAP(map_data[next_pos], map_data[pos]);
pos = next_pos;
next_pos = (next_pos + 1) & capacity;
}
map_data[pos].data = EMPTY_HASH;
uint32_t hash = _hash(p_new_key);
_insert_with_hash(hash, element_pos);
return true;
}
// Reserves space for a number of elements, useful to avoid many resizes and rehashes.
// If adding a known (possibly large) number of elements at once, must be larger than old capacity.
void reserve(uint32_t p_new_capacity) {
ERR_FAIL_COND_MSG(p_new_capacity < size(), "reserve() called with a capacity smaller than the current size. This is likely a mistake.");
if (elements == nullptr) {
capacity = MAX(4u, p_new_capacity);
capacity = next_power_of_2(capacity) - 1;
return; // Unallocated yet.
}
if (p_new_capacity <= get_capacity()) {
return;
}
_resize_and_rehash(p_new_capacity);
}
/** Iterator API **/
struct ConstIterator {
_FORCE_INLINE_ const MapKeyValue &operator*() const {
return *pair;
}
_FORCE_INLINE_ const MapKeyValue *operator->() const {
return pair;
}
_FORCE_INLINE_ ConstIterator &operator++() {
pair++;
return *this;
}
_FORCE_INLINE_ ConstIterator &operator--() {
pair--;
if (pair < begin) {
pair = end;
}
return *this;
}
_FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return pair == b.pair; }
_FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return pair != b.pair; }
_FORCE_INLINE_ explicit operator bool() const {
return pair != end;
}
_FORCE_INLINE_ ConstIterator(MapKeyValue *p_key, MapKeyValue *p_begin, MapKeyValue *p_end) {
pair = p_key;
begin = p_begin;
end = p_end;
}
_FORCE_INLINE_ ConstIterator() {}
_FORCE_INLINE_ ConstIterator(const ConstIterator &p_it) {
pair = p_it.pair;
begin = p_it.begin;
end = p_it.end;
}
_FORCE_INLINE_ void operator=(const ConstIterator &p_it) {
pair = p_it.pair;
begin = p_it.begin;
end = p_it.end;
}
private:
MapKeyValue *pair = nullptr;
MapKeyValue *begin = nullptr;
MapKeyValue *end = nullptr;
};
struct Iterator {
_FORCE_INLINE_ MapKeyValue &operator*() const {
return *pair;
}
_FORCE_INLINE_ MapKeyValue *operator->() const {
return pair;
}
_FORCE_INLINE_ Iterator &operator++() {
pair++;
return *this;
}
_FORCE_INLINE_ Iterator &operator--() {
pair--;
if (pair < begin) {
pair = end;
}
return *this;
}
_FORCE_INLINE_ bool operator==(const Iterator &b) const { return pair == b.pair; }
_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return pair != b.pair; }
_FORCE_INLINE_ explicit operator bool() const {
return pair != end;
}
_FORCE_INLINE_ Iterator(MapKeyValue *p_key, MapKeyValue *p_begin, MapKeyValue *p_end) {
pair = p_key;
begin = p_begin;
end = p_end;
}
_FORCE_INLINE_ Iterator() {}
_FORCE_INLINE_ Iterator(const Iterator &p_it) {
pair = p_it.pair;
begin = p_it.begin;
end = p_it.end;
}
_FORCE_INLINE_ void operator=(const Iterator &p_it) {
pair = p_it.pair;
begin = p_it.begin;
end = p_it.end;
}
operator ConstIterator() const {
return ConstIterator(pair, begin, end);
}
private:
MapKeyValue *pair = nullptr;
MapKeyValue *begin = nullptr;
MapKeyValue *end = nullptr;
};
_FORCE_INLINE_ Iterator begin() {
return Iterator(elements, elements, elements + num_elements);
}
_FORCE_INLINE_ Iterator end() {
return Iterator(elements + num_elements, elements, elements + num_elements);
}
_FORCE_INLINE_ Iterator last() {
if (unlikely(num_elements == 0)) {
return Iterator(nullptr, nullptr, nullptr);
}
return Iterator(elements + num_elements - 1, elements, elements + num_elements);
}
Iterator find(const TKey &p_key) {
uint32_t pos = 0;
uint32_t h_pos = 0;
bool exists = _lookup_pos(p_key, pos, h_pos);
if (!exists) {
return end();
}
return Iterator(elements + pos, elements, elements + num_elements);
}
void remove(const Iterator &p_iter) {
if (p_iter) {
erase(p_iter->key);
}
}
_FORCE_INLINE_ ConstIterator begin() const {
return ConstIterator(elements, elements, elements + num_elements);
}
_FORCE_INLINE_ ConstIterator end() const {
return ConstIterator(elements + num_elements, elements, elements + num_elements);
}
_FORCE_INLINE_ ConstIterator last() const {
if (unlikely(num_elements == 0)) {
return ConstIterator(nullptr, nullptr, nullptr);
}
return ConstIterator(elements + num_elements - 1, elements, elements + num_elements);
}
ConstIterator find(const TKey &p_key) const {
uint32_t pos = 0;
uint32_t h_pos = 0;
bool exists = _lookup_pos(p_key, pos, h_pos);
if (!exists) {
return end();
}
return ConstIterator(elements + pos, elements, elements + num_elements);
}
/* Indexing */
const TValue &operator[](const TKey &p_key) const {
uint32_t pos = 0;
uint32_t h_pos = 0;
bool exists = _lookup_pos(p_key, pos, h_pos);
CRASH_COND(!exists);
return elements[pos].value;
}
TValue &operator[](const TKey &p_key) {
uint32_t pos = 0;
uint32_t h_pos = 0;
uint32_t hash = _hash(p_key);
bool exists = _lookup_pos_with_hash(p_key, pos, h_pos, hash);
if (exists) {
return elements[pos].value;
} else {
pos = _insert_element(p_key, TValue(), hash);
return elements[pos].value;
}
}
/* Insert */
Iterator insert(const TKey &p_key, const TValue &p_value) {
uint32_t pos = 0;
uint32_t h_pos = 0;
uint32_t hash = _hash(p_key);
bool exists = _lookup_pos_with_hash(p_key, pos, h_pos, hash);
if (!exists) {
pos = _insert_element(p_key, p_value, hash);
} else {
elements[pos].value = p_value;
}
return Iterator(elements + pos, elements, elements + num_elements);
}
// Inserts an element without checking if it already exists.
Iterator insert_new(const TKey &p_key, const TValue &p_value) {
DEV_ASSERT(!has(p_key));
uint32_t hash = _hash(p_key);
uint32_t pos = _insert_element(p_key, p_value, hash);
return Iterator(elements + pos, elements, elements + num_elements);
}
/* Array methods. */
// Unsafe. Changing keys and going outside the bounds of an array can lead to undefined behavior.
KeyValue<TKey, TValue> *get_elements_ptr() {
return elements;
}
// Returns the element index. If not found, returns -1.
int get_index(const TKey &p_key) {
uint32_t pos = 0;
uint32_t h_pos = 0;
bool exists = _lookup_pos(p_key, pos, h_pos);
if (!exists) {
return -1;
}
return pos;
}
KeyValue<TKey, TValue> &get_by_index(uint32_t p_index) {
CRASH_BAD_UNSIGNED_INDEX(p_index, num_elements);
return elements[p_index];
}
bool erase_by_index(uint32_t p_index) {
if (p_index >= size()) {
return false;
}
return erase(elements[p_index].key);
}
/* Constructors */
AHashMap(const AHashMap &p_other) {
_init_from(p_other);
}
AHashMap(const HashMap<TKey, TValue> &p_other) {
reserve(p_other.size());
for (const KeyValue<TKey, TValue> &E : p_other) {
uint32_t hash = _hash(E.key);
_insert_element(E.key, E.value, hash);
}
}
void operator=(const AHashMap &p_other) {
if (this == &p_other) {
return; // Ignore self assignment.
}
reset();
_init_from(p_other);
}
void operator=(const HashMap<TKey, TValue> &p_other) {
reset();
reserve(p_other.size());
for (const KeyValue<TKey, TValue> &E : p_other) {
uint32_t hash = _hash(E.key);
_insert_element(E.key, E.value, hash);
}
}
AHashMap(uint32_t p_initial_capacity) {
// Capacity can't be 0 and must be 2^n - 1.
capacity = MAX(4u, p_initial_capacity);
capacity = next_power_of_2(capacity) - 1;
}
AHashMap() :
capacity(INITIAL_CAPACITY - 1) {
}
AHashMap(std::initializer_list<KeyValue<TKey, TValue>> p_init) {
reserve(p_init.size());
for (const KeyValue<TKey, TValue> &E : p_init) {
insert(E.key, E.value);
}
}
void reset() {
if (elements != nullptr) {
if constexpr (!(std::is_trivially_destructible_v<TKey> && std::is_trivially_destructible_v<TValue>)) {
for (uint32_t i = 0; i < num_elements; i++) {
elements[i].key.~TKey();
elements[i].value.~TValue();
}
}
Memory::free_static(elements);
Memory::free_static(map_data);
elements = nullptr;
}
capacity = INITIAL_CAPACITY - 1;
num_elements = 0;
}
~AHashMap() {
reset();
}
};
} //namespace godot

View File

@@ -37,6 +37,7 @@
#include <godot_cpp/core/math.hpp>
#include <godot_cpp/core/object.hpp>
#include <godot_cpp/templates/pair.hpp>
#include <godot_cpp/variant/aabb.hpp>
#include <godot_cpp/variant/node_path.hpp>
#include <godot_cpp/variant/rect2.hpp>
@@ -319,6 +320,13 @@ struct HashMapHasherDefault {
template <typename T>
static _FORCE_INLINE_ uint32_t hash(const Ref<T> &p_ref) { return hash_one_uint64((uint64_t)p_ref.operator->()); }
template <typename F, typename S>
static _FORCE_INLINE_ uint32_t hash(const Pair<F, S> &p_pair) {
uint64_t h1 = hash(p_pair.first);
uint64_t h2 = hash(p_pair.second);
return hash_one_uint64((h1 << 32) | h2);
}
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return hash_fmix32(uint32_t(p_wchar)); }
@@ -329,6 +337,7 @@ struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); }
static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); }
static _FORCE_INLINE_ uint32_t hash(const ObjectID &p_id) { return hash_one_uint64(p_id); }
static _FORCE_INLINE_ uint32_t hash(const Callable &p_callable) { return p_callable.hash(); }
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { return hash_one_uint64(p_int); }
static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash_one_uint64(uint64_t(p_int)); }
@@ -376,6 +385,13 @@ struct HashMapHasherDefault {
h = hash_murmur3_one_real(p_vec.w, h);
return hash_fmix32(h);
}
static _FORCE_INLINE_ uint32_t hash(const Color &p_vec) {
uint32_t h = hash_murmur3_one_float(p_vec.r);
h = hash_murmur3_one_float(p_vec.g, h);
h = hash_murmur3_one_float(p_vec.b, h);
h = hash_murmur3_one_float(p_vec.a, h);
return hash_fmix32(h);
}
static _FORCE_INLINE_ uint32_t hash(const Rect2i &p_rect) {
uint32_t h = hash_murmur3_one_32(uint32_t(p_rect.position.x));
h = hash_murmur3_one_32(uint32_t(p_rect.position.y), h);

View File

@@ -30,86 +30,70 @@
#pragma once
#include <godot_cpp/templates/hashfuncs.hpp>
#include <godot_cpp/core/defs.hpp>
namespace godot {
template <typename F, typename S>
struct Pair {
F first;
S second;
F first{};
S second{};
Pair() :
first(),
second() {
}
constexpr Pair() = default;
constexpr Pair(const F &p_first, const S &p_second) :
first(p_first), second(p_second) {}
Pair(F p_first, const S &p_second) :
first(p_first),
second(p_second) {
}
constexpr bool operator==(const Pair &p_other) const { return first == p_other.first && second == p_other.second; }
constexpr bool operator!=(const Pair &p_other) const { return first != p_other.first || second != p_other.second; }
constexpr bool operator<(const Pair &p_other) const { return first == p_other.first ? (second < p_other.second) : (first < p_other.first); }
constexpr bool operator<=(const Pair &p_other) const { return first == p_other.first ? (second <= p_other.second) : (first < p_other.first); }
constexpr bool operator>(const Pair &p_other) const { return first == p_other.first ? (second > p_other.second) : (first > p_other.first); }
constexpr bool operator>=(const Pair &p_other) const { return first == p_other.first ? (second >= p_other.second) : (first > p_other.first); }
};
template <typename F, typename S>
bool operator==(const Pair<F, S> &pair, const Pair<F, S> &other) {
return (pair.first == other.first) && (pair.second == other.second);
}
template <typename F, typename S>
bool operator!=(const Pair<F, S> &pair, const Pair<F, S> &other) {
return (pair.first != other.first) || (pair.second != other.second);
}
template <typename F, typename S>
struct PairSort {
bool operator()(const Pair<F, S> &A, const Pair<F, S> &B) const {
if (A.first != B.first) {
return A.first < B.first;
}
return A.second < B.second;
constexpr bool operator()(const Pair<F, S> &p_lhs, const Pair<F, S> &p_rhs) const {
return p_lhs < p_rhs;
}
};
// Pair is zero-constructible if and only if both constrained types are zero-constructible.
template <typename F, typename S>
struct PairHash {
static uint32_t hash(const Pair<F, S> &P) {
uint64_t h1 = HashMapHasherDefault::hash(P.first);
uint64_t h2 = HashMapHasherDefault::hash(P.second);
return hash_one_uint64((h1 << 32) | h2);
}
};
struct is_zero_constructible<Pair<F, S>> : std::conjunction<is_zero_constructible<F>, is_zero_constructible<S>> {};
template <typename K, typename V>
struct KeyValue {
const K key;
V value;
const K key{};
V value{};
void operator=(const KeyValue &p_kv) = delete;
_FORCE_INLINE_ KeyValue(const KeyValue &p_kv) :
key(p_kv.key),
value(p_kv.value) {
}
_FORCE_INLINE_ KeyValue(const K &p_key, const V &p_value) :
key(p_key),
value(p_value) {
}
KeyValue &operator=(const KeyValue &p_kv) = delete;
KeyValue &operator=(KeyValue &&p_kv) = delete;
constexpr KeyValue(const KeyValue &p_kv) = default;
constexpr KeyValue(KeyValue &&p_kv) = default;
constexpr KeyValue(const K &p_key, const V &p_value) :
key(p_key), value(p_value) {}
constexpr KeyValue(const Pair<K, V> &p_pair) :
key(p_pair.first), value(p_pair.second) {}
constexpr bool operator==(const KeyValue &p_other) const { return key == p_other.key && value == p_other.value; }
constexpr bool operator!=(const KeyValue &p_other) const { return key != p_other.key || value != p_other.value; }
constexpr bool operator<(const KeyValue &p_other) const { return key == p_other.key ? (value < p_other.value) : (key < p_other.key); }
constexpr bool operator<=(const KeyValue &p_other) const { return key == p_other.key ? (value <= p_other.value) : (key < p_other.key); }
constexpr bool operator>(const KeyValue &p_other) const { return key == p_other.key ? (value > p_other.value) : (key > p_other.key); }
constexpr bool operator>=(const KeyValue &p_other) const { return key == p_other.key ? (value >= p_other.value) : (key > p_other.key); }
};
template <typename K, typename V>
bool operator==(const KeyValue<K, V> &pair, const KeyValue<K, V> &other) {
return (pair.key == other.key) && (pair.value == other.value);
}
template <typename K, typename V>
bool operator!=(const KeyValue<K, V> &pair, const KeyValue<K, V> &other) {
return (pair.key != other.key) || (pair.value != other.value);
}
template <typename K, typename V>
struct KeyValueSort {
bool operator()(const KeyValue<K, V> &A, const KeyValue<K, V> &B) const {
return A.key < B.key;
constexpr bool operator()(const KeyValue<K, V> &p_lhs, const KeyValue<K, V> &p_rhs) const {
return p_lhs.key < p_rhs.key;
}
};
// KeyValue is zero-constructible if and only if both constrained types are zero-constructible.
template <typename K, typename V>
struct is_zero_constructible<KeyValue<K, V>> : std::conjunction<is_zero_constructible<K>, is_zero_constructible<V>> {};
} // namespace godot

View File

@@ -124,14 +124,14 @@ public:
sorter.sort(data, len);
}
Size bsearch(const T &p_value, bool p_before) {
Size bsearch(const T &p_value, bool p_before) const {
return bsearch_custom<_DefaultComparator<T>>(p_value, p_before);
}
template <typename Comparator, typename Value, typename... Args>
Size bsearch_custom(const Value &p_value, bool p_before, Args &&...args) {
Size bsearch_custom(const Value &p_value, bool p_before, Args &&...args) const {
SearchArray<T, Comparator> search{ args... };
return search.bisect(ptrw(), size(), p_value, p_before);
return search.bisect(ptr(), size(), p_value, p_before);
}
Vector<T> duplicate() {

View File

@@ -205,12 +205,12 @@ class VariantInternal {
public:
template <typename T>
_FORCE_INLINE_ static T *get_internal_value(Variant *v) {
return static_cast<T *>(get_internal_func[internal::VariantInternalType<T>::type](v));
return static_cast<T *>(get_internal_func[::godot::internal::VariantInternalType<T>::type](v));
}
template <typename T>
_FORCE_INLINE_ static const T *get_internal_value(const Variant *v) {
return static_cast<const T *>(get_internal_func[internal::VariantInternalType<T>::type](const_cast<Variant *>(v)));
return static_cast<const T *>(get_internal_func[::godot::internal::VariantInternalType<T>::type](const_cast<Variant *>(v)));
}
// Atomic types.
@@ -473,8 +473,8 @@ public:
template <typename T>
struct VariantGetInternalPtr {
static internal::VariantInternalType<T> *get_ptr(Variant *v) { return VariantInternal::get_internal_value<T>(v); }
static const internal::VariantInternalType<T> *get_ptr(const Variant *v) { return VariantInternal::get_internal_value<T>(v); }
static ::godot::internal::VariantInternalType<T> *get_ptr(Variant *v) { return VariantInternal::get_internal_value<T>(v); }
static const ::godot::internal::VariantInternalType<T> *get_ptr(const Variant *v) { return VariantInternal::get_internal_value<T>(v); }
};
template <typename T>
@@ -493,7 +493,7 @@ struct VariantInternalAccessor {
// Enable set() only for those types where we can set (all but Object *).
template <typename U = T, typename = std::enable_if_t<can_set_variant_internal_value<U>::value>>
static _FORCE_INLINE_ void set(Variant *v, const internal::VariantInternalType<U> &p_value) {
static _FORCE_INLINE_ void set(Variant *v, const ::godot::internal::VariantInternalType<U> &p_value) {
*VariantInternal::get_internal_value<U>(v) = p_value;
}
};

364
make_interface_header.py Normal file
View File

@@ -0,0 +1,364 @@
import difflib
import json
from collections import OrderedDict
BASE_TYPES = [
"void",
"int",
"int8_t",
"uint8_t",
"int16_t",
"uint16_t",
"int32_t",
"uint32_t",
"int64_t",
"uint64_t",
"size_t",
"char",
"char16_t",
"char32_t",
"wchar_t",
"float",
"double",
]
def _get_buffer(path):
with open(path, "rb") as file:
return file.read()
def _generated_wrapper(path, header_lines):
f = open(path, "wt", encoding="utf-8")
for line in header_lines:
f.write(line + "\n")
f.write("#pragma once\n\n")
return f
def scons_run(target, source, env):
target_path = str(target[0])
source_path = str(source[0])
generate_gdextension_interface_header(target_path, source_path)
def generate_gdextension_interface_header(target, source, header_lines=[]):
buffer = _get_buffer(source)
data = json.loads(buffer, object_pairs_hook=OrderedDict)
check_formatting(buffer.decode("utf-8"), data, source)
check_allowed_keys(data, ["_copyright", "$schema", "format_version", "types", "interface"])
valid_data_types = {}
for type in BASE_TYPES:
valid_data_types[type] = True
with _generated_wrapper(target, header_lines) as file:
file.write("""\
#ifndef __cplusplus
#include <stddef.h>
#include <stdint.h>
typedef uint32_t char32_t;
typedef uint16_t char16_t;
#else
#include <cstddef>
#include <cstdint>
extern "C" {
#endif
""")
handles = []
type_replacements = []
for type in data["types"]:
kind = type["kind"]
check_type(kind, type, valid_data_types)
valid_data_types[type["name"]] = type
if "deprecated" in type:
check_allowed_keys(type["deprecated"], ["since"], ["message", "replace_with"])
if "replace_with" in type["deprecated"]:
type_replacements.append((type["name"], type["deprecated"]["replace_with"]))
if "description" in type:
write_doc(file, type["description"])
if kind == "handle":
check_allowed_keys(
type, ["name", "kind"], ["is_const", "is_uninitialized", "parent", "description", "deprecated"]
)
if "parent" in type and type["parent"] not in handles:
raise UnknownTypeError(type["parent"], type["name"])
# @todo In the future, let's write these as `struct *` so the compiler can help us with type checking.
type["type"] = "void*" if not type.get("is_const", False) else "const void*"
write_simple_type(file, type)
handles.append(type["name"])
elif kind == "alias":
check_allowed_keys(type, ["name", "kind", "type"], ["description", "deprecated"])
write_simple_type(file, type)
elif kind == "enum":
check_allowed_keys(type, ["name", "kind", "values"], ["is_bitfield", "description", "deprecated"])
write_enum_type(file, type)
elif kind == "function":
check_allowed_keys(type, ["name", "kind", "return_value", "arguments"], ["description", "deprecated"])
write_function_type(file, type)
elif kind == "struct":
check_allowed_keys(type, ["name", "kind", "members"], ["description", "deprecated"])
write_struct_type(file, type)
else:
raise Exception(f"Unknown kind of type: {kind}")
for type_name, replace_with in type_replacements:
if replace_with not in valid_data_types:
raise Exception(f"Unknown type '{replace_with}' used as replacement for '{type_name}'")
replacement = valid_data_types[replace_with]
if isinstance(replacement, dict) and "deprecated" in replacement:
raise Exception(
f"Cannot use '{replace_with}' as replacement for '{type_name}' because it's deprecated too"
)
interface_replacements = []
valid_interfaces = {}
for interface in data["interface"]:
check_type("function", interface, valid_data_types)
check_allowed_keys(
interface,
["name", "return_value", "arguments", "since", "description"],
["see", "legacy_type_name", "deprecated"],
)
valid_interfaces[interface["name"]] = interface
if "deprecated" in interface:
check_allowed_keys(interface["deprecated"], ["since"], ["message", "replace_with"])
if "replace_with" in interface["deprecated"]:
interface_replacements.append((interface["name"], interface["deprecated"]["replace_with"]))
write_interface(file, interface)
for function_name, replace_with in interface_replacements:
if replace_with not in valid_interfaces:
raise Exception(
f"Unknown interface function '{replace_with}' used as replacement for '{function_name}'"
)
replacement = valid_interfaces[replace_with]
if "deprecated" in replacement:
raise Exception(
f"Cannot use '{replace_with}' as replacement for '{function_name}' because it's deprecated too"
)
file.write("""\
#ifdef __cplusplus
}
#endif
""")
# Serialize back into JSON in order to see if the formatting remains the same.
def check_formatting(buffer, data, filename):
buffer2 = json.dumps(data, indent=4)
lines1 = buffer.splitlines()
lines2 = buffer2.splitlines()
diff = difflib.unified_diff(
lines1,
lines2,
fromfile="a/" + filename,
tofile="b/" + filename,
lineterm="",
)
diff = list(diff)
if len(diff) > 0:
print(" *** Apply this patch to fix: ***\n")
print("\n".join(diff))
raise Exception(f"Formatting issues in {filename}")
def check_allowed_keys(data, required, optional=[]):
keys = data.keys()
allowed = required + optional
for k in keys:
if k not in allowed:
raise Exception(f"Found unknown key '{k}'")
for r in required:
if r not in keys:
raise Exception(f"Missing required key '{r}'")
class UnknownTypeError(Exception):
def __init__(self, unknown, parent, item=None):
self.unknown = unknown
self.parent = parent
if item:
msg = f"Unknown type '{unknown}' for '{item}' used in '{parent}'"
else:
msg = f"Unknown type '{unknown}' used in '{parent}'"
super().__init__(msg)
def base_type_name(type_name):
if type_name.startswith("const "):
type_name = type_name[6:]
if type_name.endswith("*"):
type_name = type_name[:-1]
return type_name
def format_type_and_name(type, name=None):
ret = type
if ret[-1] == "*":
ret = ret[:-1] + " *"
if name:
if ret[-1] == "*":
ret = ret + name
else:
ret = ret + " " + name
return ret
def check_type(kind, type, valid_data_types):
if kind == "alias":
if base_type_name(type["type"]) not in valid_data_types:
raise UnknownTypeError(type["type"], type["name"])
elif kind == "struct":
for member in type["members"]:
if base_type_name(member["type"]) not in valid_data_types:
raise UnknownTypeError(member["type"], type["name"], member["name"])
elif kind == "function":
for arg in type["arguments"]:
if base_type_name(arg["type"]) not in valid_data_types:
raise UnknownTypeError(arg["type"], type["name"], arg.get("name"))
if "return_value" in type:
if base_type_name(type["return_value"]["type"]) not in valid_data_types:
raise UnknownTypeError(type["return_value"]["type"], type["name"])
def write_doc(file, doc, indent=""):
if len(doc) == 1:
file.write(f"{indent}/* {doc[0]} */\n")
return
first = True
for line in doc:
if first:
file.write(indent + "/*")
first = False
else:
file.write(indent + " *")
if line != "":
file.write(" " + line)
file.write("\n")
file.write(indent + " */\n")
def make_deprecated_message(data):
parts = [
f"Deprecated in Godot {data['since']}.",
data["message"] if "message" in data else "",
f"Use `{data['replace_with']}` instead." if "replace_with" in data else "",
]
return " ".join([x for x in parts if x.strip() != ""])
def make_deprecated_comment_for_type(type):
if "deprecated" not in type:
return ""
message = make_deprecated_message(type["deprecated"])
return f" /* {message} */"
def write_simple_type(file, type):
file.write(f"typedef {format_type_and_name(type['type'], type['name'])};{make_deprecated_comment_for_type(type)}\n")
def write_enum_type(file, enum):
file.write("typedef enum {\n")
for value in enum["values"]:
check_allowed_keys(value, ["name", "value"], ["description", "deprecated"])
if "description" in value:
write_doc(file, value["description"], "\t")
file.write(f"\t{value['name']} = {value['value']},\n")
file.write(f"}} {enum['name']};{make_deprecated_comment_for_type(enum)}\n\n")
def make_args_text(args):
combined = []
for arg in args:
check_allowed_keys(arg, ["type"], ["name", "description"])
combined.append(format_type_and_name(arg["type"], arg.get("name")))
return ", ".join(combined)
def write_function_type(file, fn):
args_text = make_args_text(fn["arguments"]) if ("arguments" in fn) else ""
name_and_args = f"(*{fn['name']})({args_text})"
file.write(
f"typedef {format_type_and_name(fn['return_value']['type'], name_and_args)};{make_deprecated_comment_for_type(fn)}\n"
)
def write_struct_type(file, struct):
file.write("typedef struct {\n")
for member in struct["members"]:
check_allowed_keys(member, ["name", "type"], ["description"])
if "description" in member:
write_doc(file, member["description"], "\t")
file.write(f"\t{format_type_and_name(member['type'], member['name'])};\n")
file.write(f"}} {struct['name']};{make_deprecated_comment_for_type(struct)}\n\n")
def write_interface(file, interface):
doc = [
f"@name {interface['name']}",
f"@since {interface['since']}",
]
if "deprecated" in interface:
doc.append(f"@deprecated {make_deprecated_message(interface['deprecated'])}")
doc += [
"",
interface["description"][0],
]
if len(interface["description"]) > 1:
doc.append("")
doc += interface["description"][1:]
if "arguments" in interface:
doc.append("")
for arg in interface["arguments"]:
if "description" not in arg:
raise Exception(f"Interface function {interface['name']} is missing docs for {arg['name']} argument")
arg_doc = " ".join(arg["description"])
doc.append(f"@param {arg['name']} {arg_doc}")
if "return_value" in interface and interface["return_value"]["type"] != "void":
if "description" not in interface["return_value"]:
raise Exception(f"Interface function {interface['name']} is missing docs for return value")
ret_doc = " ".join(interface["return_value"]["description"])
doc.append("")
doc.append(f"@return {ret_doc}")
if "see" in interface:
doc.append("")
for see in interface["see"]:
doc.append(f"@see {see}")
file.write("/**\n")
for d in doc:
if d != "":
file.write(f" * {d}\n")
else:
file.write(" *\n")
file.write(" */\n")
fn = interface.copy()
if "deprecated" in fn:
del fn["deprecated"]
fn["name"] = "GDExtensionInterface" + "".join(word.capitalize() for word in interface["name"].split("_"))
write_function_type(file, fn)
file.write("\n")

View File

@@ -10,6 +10,7 @@ from binding_generator import _generate_bindings, _get_file_list
from build_profile import generate_trimmed_api
api_filepath = "gdextension/extension_api.json"
interface_filepath = "gdextension/gdextension_interface.json"
bits = "64"
precision = "single"
output_dir = "self_test"
@@ -20,6 +21,7 @@ def test(profile_filepath=""):
_generate_bindings(
api,
api_filepath,
interface_filepath,
use_template_get_node=False,
bits=bits,
precision=precision,

View File

@@ -39,20 +39,20 @@ Vector<StringName> EditorPlugins::plugin_classes;
void EditorPlugins::add_plugin_class(const StringName &p_class_name) {
ERR_FAIL_COND_MSG(plugin_classes.find(p_class_name) != -1, vformat("Editor plugin already registered: %s", p_class_name));
plugin_classes.push_back(p_class_name);
internal::gdextension_interface_editor_add_plugin(p_class_name._native_ptr());
::godot::gdextension_interface::editor_add_plugin(p_class_name._native_ptr());
}
void EditorPlugins::remove_plugin_class(const StringName &p_class_name) {
int index = plugin_classes.find(p_class_name);
ERR_FAIL_COND_MSG(index == -1, vformat("Editor plugin is not registered: %s", p_class_name));
plugin_classes.remove_at(index);
internal::gdextension_interface_editor_remove_plugin(p_class_name._native_ptr());
::godot::gdextension_interface::editor_remove_plugin(p_class_name._native_ptr());
}
void EditorPlugins::deinitialize(GDExtensionInitializationLevel p_level) {
if (p_level == GDEXTENSION_INITIALIZATION_EDITOR) {
for (const StringName &class_name : plugin_classes) {
internal::gdextension_interface_editor_remove_plugin(class_name._native_ptr());
::godot::gdextension_interface::editor_remove_plugin(class_name._native_ptr());
}
plugin_classes.clear();
}

View File

@@ -37,31 +37,31 @@
namespace godot {
Error XMLParser::_open_buffer(const uint8_t *p_buffer, size_t p_size) {
return (Error)internal::gdextension_interface_xml_parser_open_buffer(_owner, p_buffer, p_size);
return (Error)::godot::gdextension_interface::xml_parser_open_buffer(_owner, p_buffer, p_size);
}
uint64_t FileAccess::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
return internal::gdextension_interface_file_access_get_buffer(_owner, p_dst, p_length);
return ::godot::gdextension_interface::file_access_get_buffer(_owner, p_dst, p_length);
}
void FileAccess::store_buffer(const uint8_t *p_src, uint64_t p_length) {
internal::gdextension_interface_file_access_store_buffer(_owner, p_src, p_length);
::godot::gdextension_interface::file_access_store_buffer(_owner, p_src, p_length);
}
WorkerThreadPool::TaskID WorkerThreadPool::add_native_task(void (*p_func)(void *), void *p_userdata, bool p_high_priority, const String &p_description) {
return (TaskID)internal::gdextension_interface_worker_thread_pool_add_native_task(_owner, p_func, p_userdata, p_high_priority, (GDExtensionConstStringPtr)&p_description);
return (TaskID)::godot::gdextension_interface::worker_thread_pool_add_native_task(_owner, p_func, p_userdata, p_high_priority, (GDExtensionConstStringPtr)&p_description);
}
WorkerThreadPool::GroupID WorkerThreadPool::add_native_group_task(void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) {
return (GroupID)internal::gdextension_interface_worker_thread_pool_add_native_group_task(_owner, p_func, p_userdata, p_elements, p_tasks, p_high_priority, (GDExtensionConstStringPtr)&p_description);
return (GroupID)::godot::gdextension_interface::worker_thread_pool_add_native_group_task(_owner, p_func, p_userdata, p_elements, p_tasks, p_high_priority, (GDExtensionConstStringPtr)&p_description);
}
uint8_t *Image::ptrw() {
return internal::gdextension_interface_image_ptrw(_owner);
return ::godot::gdextension_interface::image_ptrw(_owner);
}
const uint8_t *Image::ptr() {
return internal::gdextension_interface_image_ptr(_owner);
return ::godot::gdextension_interface::image_ptr(_owner);
}
} // namespace godot

View File

@@ -74,16 +74,16 @@ Wrapped::Wrapped(const StringName &p_godot_class) {
} else
#endif
{
_owner = godot::internal::gdextension_interface_classdb_construct_object2(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
_owner = ::godot::gdextension_interface::classdb_construct_object2(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
}
if (_constructing_extension_class_name) {
godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(_constructing_extension_class_name), this);
::godot::gdextension_interface::object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(_constructing_extension_class_name), this);
_constructing_extension_class_name = nullptr;
}
if (likely(_constructing_class_binding_callbacks)) {
godot::internal::gdextension_interface_object_set_instance_binding(_owner, godot::internal::token, this, _constructing_class_binding_callbacks);
::godot::gdextension_interface::object_set_instance_binding(_owner, ::godot::gdextension_interface::token, this, _constructing_class_binding_callbacks);
_constructing_class_binding_callbacks = nullptr;
} else {
CRASH_NOW_MSG("BUG: Godot Object created without binding callbacks. Did you forget to use memnew()?");

View File

@@ -36,14 +36,12 @@
#include <godot_cpp/core/memory.hpp>
#include <algorithm>
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;
HashMap<StringName, ClassDB::ClassInfo> ClassDB::classes;
AHashMap<StringName, const GDExtensionInstanceBindingCallbacks *> ClassDB::instance_binding_callbacks;
LocalVector<StringName> ClassDB::class_register_order;
AHashMap<StringName, Object *> ClassDB::engine_singletons;
std::mutex ClassDB::engine_singletons_mutex;
GDExtensionInitializationLevel ClassDB::current_level = GDEXTENSION_INITIALIZATION_CORE;
@@ -60,13 +58,13 @@ MethodDefinition D_METHOD(StringName p_name, StringName p_arg1) {
void ClassDB::add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix) {
ERR_FAIL_COND_MSG(classes.find(p_class) == classes.end(), String("Trying to add property '{0}{1}' to non-existing class '{2}'.").format(Array::make(p_prefix, p_name, p_class)));
internal::gdextension_interface_classdb_register_extension_class_property_group(internal::library, p_class._native_ptr(), p_name._native_ptr(), p_prefix._native_ptr());
::godot::gdextension_interface::classdb_register_extension_class_property_group(::godot::gdextension_interface::library, p_class._native_ptr(), p_name._native_ptr(), p_prefix._native_ptr());
}
void ClassDB::add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix) {
ERR_FAIL_COND_MSG(classes.find(p_class) == classes.end(), String("Trying to add property '{0}{1}' to non-existing class '{2}'.").format(Array::make(p_prefix, p_name, p_class)));
internal::gdextension_interface_classdb_register_extension_class_property_subgroup(internal::library, p_class._native_ptr(), p_name._native_ptr(), p_prefix._native_ptr());
::godot::gdextension_interface::classdb_register_extension_class_property_subgroup(::godot::gdextension_interface::library, p_class._native_ptr(), p_name._native_ptr(), p_prefix._native_ptr());
}
void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
@@ -108,7 +106,7 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf
p_pinfo.usage, // DEFAULT //uint32_t usage;
};
internal::gdextension_interface_classdb_register_extension_class_property_indexed(internal::library, info.name._native_ptr(), &prop_info, p_setter._native_ptr(), p_getter._native_ptr(), p_index);
::godot::gdextension_interface::classdb_register_extension_class_property_indexed(::godot::gdextension_interface::library, info.name._native_ptr(), &prop_info, p_setter._native_ptr(), p_getter._native_ptr(), p_index);
}
MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_method) {
@@ -116,9 +114,9 @@ MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_m
ClassInfo *type = &classes[p_class];
while (type) {
std::unordered_map<StringName, MethodBind *>::iterator method = type->method_map.find(p_method);
AHashMap<StringName, MethodBind *>::Iterator method = type->method_map.find(p_method);
if (method != type->method_map.end()) {
return method->second;
return method->value;
}
type = type->parent_ptr;
continue;
@@ -130,13 +128,13 @@ MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_m
MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const void **p_defs, int p_defcount) {
StringName instance_type = p_bind->get_instance_class();
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(instance_type);
HashMap<StringName, ClassInfo>::Iterator type_it = classes.find(instance_type);
if (type_it == classes.end()) {
memdelete(p_bind);
ERR_FAIL_V_MSG(nullptr, String("Class '{0}' doesn't exist.").format(Array::make(instance_type)));
}
ClassInfo &type = type_it->second;
ClassInfo &type = type_it->value;
if (type.method_map.find(method_name.name) != type.method_map.end()) {
memdelete(p_bind);
@@ -157,7 +155,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const M
p_bind->set_hint_flags(p_flags);
std::vector<StringName> args;
LocalVector<StringName> args;
args.resize(method_name.args.size());
size_t arg_index = 0;
for (StringName arg : method_name.args) {
@@ -166,7 +164,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const M
p_bind->set_argument_names(args);
std::vector<Variant> defvals;
LocalVector<Variant> defvals;
defvals.resize(p_defcount);
for (int i = 0; i < p_defcount; i++) {
@@ -186,34 +184,34 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const M
}
void ClassDB::bind_method_godot(const StringName &p_class_name, MethodBind *p_method) {
std::vector<GDExtensionVariantPtr> def_args;
const std::vector<Variant> &def_args_val = p_method->get_default_arguments();
LocalVector<GDExtensionVariantPtr> def_args;
const LocalVector<Variant> &def_args_val = p_method->get_default_arguments();
def_args.resize(def_args_val.size());
for (size_t i = 0; i < def_args_val.size(); i++) {
def_args[i] = (GDExtensionVariantPtr)&def_args_val[i];
}
std::vector<PropertyInfo> return_value_and_arguments_info = p_method->get_arguments_info_list();
std::vector<GDExtensionClassMethodArgumentMetadata> return_value_and_arguments_metadata = p_method->get_arguments_metadata_list();
LocalVector<PropertyInfo> return_value_and_arguments_info = p_method->get_arguments_info_list();
LocalVector<GDExtensionClassMethodArgumentMetadata> return_value_and_arguments_metadata = p_method->get_arguments_metadata_list();
std::vector<GDExtensionPropertyInfo> return_value_and_arguments_gdextension_info;
LocalVector<GDExtensionPropertyInfo> return_value_and_arguments_gdextension_info;
return_value_and_arguments_gdextension_info.reserve(return_value_and_arguments_info.size());
for (std::vector<PropertyInfo>::iterator it = return_value_and_arguments_info.begin(); it != return_value_and_arguments_info.end(); it++) {
for (const PropertyInfo &info : return_value_and_arguments_info) {
return_value_and_arguments_gdextension_info.push_back(
GDExtensionPropertyInfo{
static_cast<GDExtensionVariantType>(it->type), // GDExtensionVariantType type;
it->name._native_ptr(), // GDExtensionStringNamePtr name;
it->class_name._native_ptr(), // GDExtensionStringNamePtr class_name;
it->hint, // uint32_t hint;
it->hint_string._native_ptr(), // GDExtensionStringPtr hint_string;
it->usage, // uint32_t usage;
static_cast<GDExtensionVariantType>(info.type), // GDExtensionVariantType type;
info.name._native_ptr(), // GDExtensionStringNamePtr name;
info.class_name._native_ptr(), // GDExtensionStringNamePtr class_name;
info.hint, // uint32_t hint;
info.hint_string._native_ptr(), // GDExtensionStringPtr hint_string;
info.usage, // uint32_t usage;
});
}
GDExtensionPropertyInfo *return_value_info = return_value_and_arguments_gdextension_info.data();
GDExtensionClassMethodArgumentMetadata *return_value_metadata = return_value_and_arguments_metadata.data();
GDExtensionPropertyInfo *arguments_info = return_value_and_arguments_gdextension_info.data() + 1;
GDExtensionClassMethodArgumentMetadata *arguments_metadata = return_value_and_arguments_metadata.data() + 1;
GDExtensionPropertyInfo *return_value_info = return_value_and_arguments_gdextension_info.ptr();
GDExtensionClassMethodArgumentMetadata *return_value_metadata = return_value_and_arguments_metadata.ptr();
GDExtensionPropertyInfo *arguments_info = return_value_and_arguments_gdextension_info.ptr() + 1;
GDExtensionClassMethodArgumentMetadata *arguments_metadata = return_value_and_arguments_metadata.ptr() + 1;
StringName name = p_method->get_name();
GDExtensionClassMethodInfo method_info = {
@@ -229,17 +227,17 @@ void ClassDB::bind_method_godot(const StringName &p_class_name, MethodBind *p_me
arguments_info, // GDExtensionPropertyInfo *
arguments_metadata, // GDExtensionClassMethodArgumentMetadata *
(uint32_t)p_method->get_default_argument_count(), // uint32_t default_argument_count;
def_args.data(), // GDExtensionVariantPtr *default_arguments;
def_args.ptr(), // GDExtensionVariantPtr *default_arguments;
};
internal::gdextension_interface_classdb_register_extension_class_method(internal::library, p_class_name._native_ptr(), &method_info);
::godot::gdextension_interface::classdb_register_extension_class_method(::godot::gdextension_interface::library, p_class_name._native_ptr(), &method_info);
}
void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) {
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(p_class);
HashMap<StringName, ClassInfo>::Iterator type_it = classes.find(p_class);
ERR_FAIL_COND_MSG(type_it == classes.end(), String("Class '{0}' doesn't exist.").format(Array::make(p_class)));
ClassInfo &cl = type_it->second;
ClassInfo &cl = type_it->value;
// Check if this signal is already register
ClassInfo *check = &cl;
@@ -252,7 +250,7 @@ void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal)
cl.signal_names.insert(p_signal.name);
// register our signal in godot
std::vector<GDExtensionPropertyInfo> parameters;
LocalVector<GDExtensionPropertyInfo> parameters;
parameters.reserve(p_signal.arguments.size());
for (const PropertyInfo &par : p_signal.arguments) {
@@ -266,15 +264,15 @@ void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal)
});
}
internal::gdextension_interface_classdb_register_extension_class_signal(internal::library, cl.name._native_ptr(), p_signal.name._native_ptr(), parameters.data(), parameters.size());
::godot::gdextension_interface::classdb_register_extension_class_signal(::godot::gdextension_interface::library, cl.name._native_ptr(), p_signal.name._native_ptr(), parameters.ptr(), parameters.size());
}
void ClassDB::bind_integer_constant(const StringName &p_class_name, const StringName &p_enum_name, const StringName &p_constant_name, GDExtensionInt p_constant_value, bool p_is_bitfield) {
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(p_class_name);
HashMap<StringName, ClassInfo>::Iterator type_it = classes.find(p_class_name);
ERR_FAIL_COND_MSG(type_it == classes.end(), String("Class '{0}' doesn't exist.").format(Array::make(p_class_name)));
ClassInfo &type = type_it->second;
ClassInfo &type = type_it->value;
// check if it already exists
ERR_FAIL_COND_MSG(type.constant_names.find(p_constant_name) != type.constant_names.end(), String("Constant '{0}::{1}' already registered.").format(Array::make(p_class_name, p_constant_name)));
@@ -283,7 +281,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class_name, const String
type.constant_names.insert(p_constant_name);
// Register it with Godot
internal::gdextension_interface_classdb_register_extension_class_integer_constant(internal::library, p_class_name._native_ptr(), p_enum_name._native_ptr(), p_constant_name._native_ptr(), p_constant_value, p_is_bitfield);
::godot::gdextension_interface::classdb_register_extension_class_integer_constant(::godot::gdextension_interface::library, p_class_name._native_ptr(), p_enum_name._native_ptr(), p_constant_name._native_ptr(), p_constant_value, p_is_bitfield);
}
GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtensionConstStringNamePtr p_name, uint32_t p_hash) {
// This is called by Godot the first time it calls a virtual function, and it caches the result, per object instance.
@@ -292,17 +290,17 @@ GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtens
const StringName *class_name = reinterpret_cast<const StringName *>(p_userdata);
const StringName *name = reinterpret_cast<const StringName *>(p_name);
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(*class_name);
HashMap<StringName, ClassInfo>::Iterator type_it = classes.find(*class_name);
ERR_FAIL_COND_V_MSG(type_it == classes.end(), nullptr, String("Class '{0}' doesn't exist.").format(Array::make(*class_name)));
const ClassInfo *type = &type_it->second;
const ClassInfo *type = &type_it->value;
// Find method in current class, or any of its parent classes (Godot classes not included)
while (type != nullptr) {
std::unordered_map<StringName, ClassInfo::VirtualMethod>::const_iterator method_it = type->virtual_methods.find(*name);
AHashMap<StringName, ClassInfo::VirtualMethod>::ConstIterator method_it = type->virtual_methods.find(*name);
if (method_it != type->virtual_methods.end() && method_it->second.hash == p_hash) {
return method_it->second.func;
if (method_it != type->virtual_methods.end() && method_it->value.hash == p_hash) {
return method_it->value.func;
}
type = type->parent_ptr;
@@ -312,9 +310,9 @@ GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtens
}
const GDExtensionInstanceBindingCallbacks *ClassDB::get_instance_binding_callbacks(const StringName &p_class) {
std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *>::iterator callbacks_it = instance_binding_callbacks.find(p_class);
AHashMap<StringName, const GDExtensionInstanceBindingCallbacks *>::Iterator callbacks_it = instance_binding_callbacks.find(p_class);
if (likely(callbacks_it != instance_binding_callbacks.end())) {
return callbacks_it->second;
return callbacks_it->value;
}
// If we don't have an instance binding callback for the given class, find the closest parent where we do.
@@ -325,14 +323,14 @@ const GDExtensionInstanceBindingCallbacks *ClassDB::get_instance_binding_callbac
callbacks_it = instance_binding_callbacks.find(class_name);
} while (callbacks_it == instance_binding_callbacks.end());
return callbacks_it->second;
return callbacks_it->value;
}
void ClassDB::bind_virtual_method(const StringName &p_class, const StringName &p_method, GDExtensionClassCallVirtual p_call, uint32_t p_hash) {
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(p_class);
HashMap<StringName, ClassInfo>::Iterator type_it = classes.find(p_class);
ERR_FAIL_COND_MSG(type_it == classes.end(), String("Class '{0}' doesn't exist.").format(Array::make(p_class)));
ClassInfo &type = type_it->second;
ClassInfo &type = type_it->value;
ERR_FAIL_COND_MSG(type.method_map.find(p_method) != type.method_map.end(), String("Method '{0}::{1}()' already registered as non-virtual.").format(Array::make(p_class, p_method)));
ERR_FAIL_COND_MSG(type.virtual_methods.find(p_method) != type.virtual_methods.end(), String("Virtual '{0}::{1}()' method already registered.").format(Array::make(p_class, p_method)));
@@ -344,7 +342,7 @@ void ClassDB::bind_virtual_method(const StringName &p_class, const StringName &p
}
void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, const Vector<StringName> &p_arg_names) {
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(p_class);
HashMap<StringName, ClassInfo>::Iterator type_it = classes.find(p_class);
ERR_FAIL_COND_MSG(type_it == classes.end(), String("Class '{0}' doesn't exist.").format(Array::make(p_class)));
GDExtensionClassVirtualMethodInfo mi;
@@ -378,7 +376,7 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_
}
}
internal::gdextension_interface_classdb_register_extension_class_virtual_method(internal::library, &p_class, &mi);
::godot::gdextension_interface::classdb_register_extension_class_virtual_method(::godot::gdextension_interface::library, &p_class, &mi);
if (mi.arguments) {
memfree(mi.arguments);
@@ -392,8 +390,8 @@ void ClassDB::_editor_get_classes_used_callback(GDExtensionTypePtr p_packed_stri
PackedStringArray *arr = reinterpret_cast<PackedStringArray *>(p_packed_string_array);
arr->resize(instance_binding_callbacks.size());
int index = 0;
for (const std::pair<const StringName, const GDExtensionInstanceBindingCallbacks *> &pair : instance_binding_callbacks) {
(*arr)[index++] = pair.first;
for (const KeyValue<StringName, const GDExtensionInstanceBindingCallbacks *> &pair : instance_binding_callbacks) {
(*arr)[index++] = pair.key;
}
}
@@ -401,8 +399,8 @@ void ClassDB::initialize_class(const ClassInfo &p_cl) {
}
void ClassDB::initialize(GDExtensionInitializationLevel p_level) {
for (const std::pair<const StringName, ClassInfo> &pair : classes) {
const ClassInfo &cl = pair.second;
for (const KeyValue<StringName, ClassInfo> &pair : classes) {
const ClassInfo &cl = pair.value;
if (cl.level != p_level) {
continue;
}
@@ -413,18 +411,18 @@ void ClassDB::initialize(GDExtensionInitializationLevel p_level) {
void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
std::set<StringName> to_erase;
for (std::vector<StringName>::reverse_iterator i = class_register_order.rbegin(); i != class_register_order.rend(); ++i) {
const StringName &name = *i;
for (int i = class_register_order.size() - 1; i >= 0; --i) {
const StringName &name = class_register_order[i];
const ClassInfo &cl = classes[name];
if (cl.level != p_level) {
continue;
}
internal::gdextension_interface_classdb_unregister_extension_class(internal::library, name._native_ptr());
::godot::gdextension_interface::classdb_unregister_extension_class(::godot::gdextension_interface::library, name._native_ptr());
for (const std::pair<const StringName, MethodBind *> &method : cl.method_map) {
memdelete(method.second);
for (const KeyValue<StringName, MethodBind *> &method : cl.method_map) {
memdelete(method.value);
}
classes.erase(name);
@@ -432,26 +430,24 @@ void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
}
{
// The following is equivalent to c++20 `std::erase_if(class_register_order, [&](const StringName& name){ return to_erase.contains(name); });`
std::vector<StringName>::iterator it = std::remove_if(class_register_order.begin(), class_register_order.end(), [&](const StringName &p_name) {
return to_erase.count(p_name) > 0;
});
class_register_order.erase(it, class_register_order.end());
for (const StringName &x : to_erase) {
class_register_order.erase(x);
}
}
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;
LocalVector<Object *> singleton_objects;
{
std::lock_guard<std::mutex> lock(engine_singletons_mutex);
singleton_objects.reserve(engine_singletons.size());
for (const std::pair<const StringName, Object *> &pair : engine_singletons) {
singleton_objects.push_back(pair.second);
for (const KeyValue<StringName, Object *> &pair : engine_singletons) {
singleton_objects.push_back(pair.value);
}
}
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);
for (const Object *i : singleton_objects) {
::godot::gdextension_interface::object_free_instance_binding((*i)._owner, ::godot::gdextension_interface::token);
}
}
}

View File

@@ -39,9 +39,9 @@ namespace godot {
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify, bool p_is_warning) {
if (p_is_warning) {
internal::gdextension_interface_print_warning(p_error, p_function, p_file, p_line, p_editor_notify);
::godot::gdextension_interface::print_warning(p_error, p_function, p_file, p_line, p_editor_notify);
} else {
internal::gdextension_interface_print_error(p_error, p_function, p_file, p_line, p_editor_notify);
::godot::gdextension_interface::print_error(p_error, p_function, p_file, p_line, p_editor_notify);
}
}
@@ -51,9 +51,9 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify, bool p_is_warning) {
if (p_is_warning) {
internal::gdextension_interface_print_warning_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
::godot::gdextension_interface::print_warning_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
} else {
internal::gdextension_interface_print_error_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
::godot::gdextension_interface::print_error_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
}
}

View File

@@ -35,21 +35,19 @@
namespace godot {
void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
#ifdef DEBUG_ENABLED
bool prepad = false; // Already pre paded in the engine.
#if GODOT_VERSION_MINOR >= 6
return ::godot::gdextension_interface::mem_alloc2(p_bytes, p_pad_align);
#else
bool prepad = p_pad_align;
#endif
void *mem = internal::gdextension_interface_mem_alloc(p_bytes + (prepad ? DATA_OFFSET : 0));
void *mem = ::godot::gdextension_interface::mem_alloc(p_bytes + (p_pad_align ? DATA_OFFSET : 0));
ERR_FAIL_NULL_V(mem, nullptr);
if (prepad) {
if (p_pad_align) {
uint8_t *s8 = (uint8_t *)mem;
return s8 + DATA_OFFSET;
} else {
return mem;
}
#endif
}
void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
@@ -60,37 +58,31 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
return nullptr;
}
uint8_t *mem = (uint8_t *)p_memory;
#ifdef DEBUG_ENABLED
bool prepad = false; // Already pre paded in the engine.
#if GODOT_VERSION_MINOR >= 6
return ::godot::gdextension_interface::mem_realloc2(p_memory, p_bytes, p_pad_align);
#else
bool prepad = p_pad_align;
#endif
if (prepad) {
uint8_t *mem = (uint8_t *)p_memory;
if (p_pad_align) {
mem -= DATA_OFFSET;
mem = (uint8_t *)internal::gdextension_interface_mem_realloc(mem, p_bytes + DATA_OFFSET);
mem = (uint8_t *)::godot::gdextension_interface::mem_realloc(mem, p_bytes + DATA_OFFSET);
ERR_FAIL_NULL_V(mem, nullptr);
return mem + DATA_OFFSET;
} else {
return (uint8_t *)internal::gdextension_interface_mem_realloc(mem, p_bytes);
return (uint8_t *)::godot::gdextension_interface::mem_realloc(mem, p_bytes);
}
#endif
}
void Memory::free_static(void *p_ptr, bool p_pad_align) {
uint8_t *mem = (uint8_t *)p_ptr;
#ifdef DEBUG_ENABLED
bool prepad = false; // Already pre paded in the engine.
#if GODOT_VERSION_MINOR >= 6
::godot::gdextension_interface::mem_free2(p_ptr, p_pad_align);
#else
bool prepad = p_pad_align;
#endif
if (prepad) {
uint8_t *mem = (uint8_t *)p_ptr;
if (p_pad_align) {
mem -= DATA_OFFSET;
}
internal::gdextension_interface_mem_free(mem);
::godot::gdextension_interface::mem_free(mem);
#endif
}
_GlobalNil::_GlobalNil() {

View File

@@ -56,11 +56,11 @@ void MethodBind::set_name(const StringName &p_name) {
name = p_name;
}
void MethodBind::set_argument_names(const std::vector<StringName> &p_names) {
void MethodBind::set_argument_names(const LocalVector<StringName> &p_names) {
argument_names = p_names;
}
std::vector<StringName> MethodBind::get_argument_names() const {
LocalVector<StringName> MethodBind::get_argument_names() const {
return argument_names;
}
@@ -92,7 +92,7 @@ void MethodBind::bind_call(void *p_method_userdata, GDExtensionClassInstancePtr
Variant ret = bind->call(p_instance, p_args, p_argument_count, *r_error);
// This assumes the return value is an empty Variant, so it doesn't need to call the destructor first.
// Since only GDExtensionMethodBind calls this from the Godot side, it should always be the case.
internal::gdextension_interface_variant_new_copy(r_return, ret._native_ptr());
::godot::gdextension_interface::variant_new_copy(r_return, ret._native_ptr());
}
void MethodBind::bind_ptrcall(void *p_method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return) {

View File

@@ -42,7 +42,7 @@ Object *get_object_instance_binding(GodotObject *p_engine_object) {
}
// Get existing instance binding, if one already exists.
GDExtensionObjectPtr instance = gdextension_interface_object_get_instance_binding(p_engine_object, token, nullptr);
GDExtensionObjectPtr instance = ::godot::gdextension_interface::object_get_instance_binding(p_engine_object, ::godot::gdextension_interface::token, nullptr);
if (instance != nullptr) {
return reinterpret_cast<Object *>(instance);
}
@@ -50,17 +50,17 @@ Object *get_object_instance_binding(GodotObject *p_engine_object) {
// Otherwise, try to look up the correct binding callbacks.
const GDExtensionInstanceBindingCallbacks *binding_callbacks = nullptr;
StringName class_name;
if (gdextension_interface_object_get_class_name(p_engine_object, library, reinterpret_cast<GDExtensionStringNamePtr>(class_name._native_ptr()))) {
if (::godot::gdextension_interface::object_get_class_name(p_engine_object, ::godot::gdextension_interface::library, reinterpret_cast<GDExtensionStringNamePtr>(class_name._native_ptr()))) {
binding_callbacks = ClassDB::get_instance_binding_callbacks(class_name);
}
if (binding_callbacks == nullptr) {
binding_callbacks = &Object::_gde_binding_callbacks;
}
return reinterpret_cast<Object *>(gdextension_interface_object_get_instance_binding(p_engine_object, token, binding_callbacks));
return reinterpret_cast<Object *>(::godot::gdextension_interface::object_get_instance_binding(p_engine_object, ::godot::gdextension_interface::token, binding_callbacks));
}
TypedArray<Dictionary> convert_property_list(const std::vector<PropertyInfo> &p_list) {
TypedArray<Dictionary> convert_property_list(const LocalVector<PropertyInfo> &p_list) {
TypedArray<Dictionary> va;
for (const PropertyInfo &pi : p_list) {
va.push_back(Dictionary(pi));
@@ -73,7 +73,7 @@ TypedArray<Dictionary> convert_property_list(const std::vector<PropertyInfo> &p_
MethodInfo::operator Dictionary() const {
Dictionary dict;
dict["name"] = name;
dict["args"] = internal::convert_property_list(arguments);
dict["args"] = ::godot::internal::convert_property_list(arguments);
Array da;
for (size_t i = 0; i < default_arguments.size(); i++) {
da.push_back(default_arguments[i]);

View File

@@ -33,6 +33,7 @@
#include <godot_cpp/classes/editor_plugin_registration.hpp>
#include <godot_cpp/classes/wrapped.hpp>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/load_proc_address.inc>
#include <godot_cpp/core/memory.hpp>
#include <godot_cpp/core/version.hpp>
#include <godot_cpp/variant/variant.hpp>
@@ -43,176 +44,17 @@
namespace godot {
namespace internal {
namespace gdextension_interface {
GDExtensionInterfaceGetProcAddress gdextension_interface_get_proc_address = nullptr;
GDExtensionInterfaceGetProcAddress get_proc_address = nullptr;
GDExtensionClassLibraryPtr library = nullptr;
void *token = nullptr;
GDExtensionGodotVersion2 godot_version = {};
// All of the GDExtension interface functions.
GDExtensionInterfaceGetGodotVersion2 gdextension_interface_get_godot_version2 = nullptr;
GDExtensionInterfaceMemAlloc gdextension_interface_mem_alloc = nullptr;
GDExtensionInterfaceMemRealloc gdextension_interface_mem_realloc = nullptr;
GDExtensionInterfaceMemFree gdextension_interface_mem_free = nullptr;
GDExtensionInterfacePrintError gdextension_interface_print_error = nullptr;
GDExtensionInterfacePrintErrorWithMessage gdextension_interface_print_error_with_message = nullptr;
GDExtensionInterfacePrintWarning gdextension_interface_print_warning = nullptr;
GDExtensionInterfacePrintWarningWithMessage gdextension_interface_print_warning_with_message = nullptr;
GDExtensionInterfacePrintScriptError gdextension_interface_print_script_error = nullptr;
GDExtensionInterfacePrintScriptErrorWithMessage gdextension_interface_print_script_error_with_message = nullptr;
GDExtensionInterfaceGetNativeStructSize gdextension_interface_get_native_struct_size = nullptr;
GDExtensionInterfaceVariantNewCopy gdextension_interface_variant_new_copy = nullptr;
GDExtensionInterfaceVariantNewNil gdextension_interface_variant_new_nil = nullptr;
GDExtensionInterfaceVariantDestroy gdextension_interface_variant_destroy = nullptr;
GDExtensionInterfaceVariantCall gdextension_interface_variant_call = nullptr;
GDExtensionInterfaceVariantCallStatic gdextension_interface_variant_call_static = nullptr;
GDExtensionInterfaceVariantEvaluate gdextension_interface_variant_evaluate = nullptr;
GDExtensionInterfaceVariantSet gdextension_interface_variant_set = nullptr;
GDExtensionInterfaceVariantSetNamed gdextension_interface_variant_set_named = nullptr;
GDExtensionInterfaceVariantSetKeyed gdextension_interface_variant_set_keyed = nullptr;
GDExtensionInterfaceVariantSetIndexed gdextension_interface_variant_set_indexed = nullptr;
GDExtensionInterfaceVariantGet gdextension_interface_variant_get = nullptr;
GDExtensionInterfaceVariantGetNamed gdextension_interface_variant_get_named = nullptr;
GDExtensionInterfaceVariantGetKeyed gdextension_interface_variant_get_keyed = nullptr;
GDExtensionInterfaceVariantGetIndexed gdextension_interface_variant_get_indexed = nullptr;
GDExtensionInterfaceVariantIterInit gdextension_interface_variant_iter_init = nullptr;
GDExtensionInterfaceVariantIterNext gdextension_interface_variant_iter_next = nullptr;
GDExtensionInterfaceVariantIterGet gdextension_interface_variant_iter_get = nullptr;
GDExtensionInterfaceVariantHash gdextension_interface_variant_hash = nullptr;
GDExtensionInterfaceVariantRecursiveHash gdextension_interface_variant_recursive_hash = nullptr;
GDExtensionInterfaceVariantHashCompare gdextension_interface_variant_hash_compare = nullptr;
GDExtensionInterfaceVariantBooleanize gdextension_interface_variant_booleanize = nullptr;
GDExtensionInterfaceVariantDuplicate gdextension_interface_variant_duplicate = nullptr;
GDExtensionInterfaceVariantStringify gdextension_interface_variant_stringify = nullptr;
GDExtensionInterfaceVariantGetType gdextension_interface_variant_get_type = nullptr;
GDExtensionInterfaceVariantHasMethod gdextension_interface_variant_has_method = nullptr;
GDExtensionInterfaceVariantHasMember gdextension_interface_variant_has_member = nullptr;
GDExtensionInterfaceVariantHasKey gdextension_interface_variant_has_key = nullptr;
GDExtensionInterfaceVariantGetObjectInstanceId gdextension_interface_variant_get_object_instance_id = nullptr;
GDExtensionInterfaceVariantGetTypeName gdextension_interface_variant_get_type_name = nullptr;
GDExtensionInterfaceVariantCanConvert gdextension_interface_variant_can_convert = nullptr;
GDExtensionInterfaceVariantCanConvertStrict gdextension_interface_variant_can_convert_strict = nullptr;
GDExtensionInterfaceGetVariantFromTypeConstructor gdextension_interface_get_variant_from_type_constructor = nullptr;
GDExtensionInterfaceGetVariantToTypeConstructor gdextension_interface_get_variant_to_type_constructor = nullptr;
GDExtensionInterfaceGetVariantGetInternalPtrFunc gdextension_interface_variant_get_ptr_internal_getter = nullptr;
GDExtensionInterfaceVariantGetPtrOperatorEvaluator gdextension_interface_variant_get_ptr_operator_evaluator = nullptr;
GDExtensionInterfaceVariantGetPtrBuiltinMethod gdextension_interface_variant_get_ptr_builtin_method = nullptr;
GDExtensionInterfaceVariantGetPtrConstructor gdextension_interface_variant_get_ptr_constructor = nullptr;
GDExtensionInterfaceVariantGetPtrDestructor gdextension_interface_variant_get_ptr_destructor = nullptr;
GDExtensionInterfaceVariantConstruct gdextension_interface_variant_construct = nullptr;
GDExtensionInterfaceVariantGetPtrSetter gdextension_interface_variant_get_ptr_setter = nullptr;
GDExtensionInterfaceVariantGetPtrGetter gdextension_interface_variant_get_ptr_getter = nullptr;
GDExtensionInterfaceVariantGetPtrIndexedSetter gdextension_interface_variant_get_ptr_indexed_setter = nullptr;
GDExtensionInterfaceVariantGetPtrIndexedGetter gdextension_interface_variant_get_ptr_indexed_getter = nullptr;
GDExtensionInterfaceVariantGetPtrKeyedSetter gdextension_interface_variant_get_ptr_keyed_setter = nullptr;
GDExtensionInterfaceVariantGetPtrKeyedGetter gdextension_interface_variant_get_ptr_keyed_getter = nullptr;
GDExtensionInterfaceVariantGetPtrKeyedChecker gdextension_interface_variant_get_ptr_keyed_checker = nullptr;
GDExtensionInterfaceVariantGetConstantValue gdextension_interface_variant_get_constant_value = nullptr;
GDExtensionInterfaceVariantGetPtrUtilityFunction gdextension_interface_variant_get_ptr_utility_function = nullptr;
GDExtensionInterfaceStringNewWithLatin1Chars gdextension_interface_string_new_with_latin1_chars = nullptr;
GDExtensionInterfaceStringNewWithUtf8Chars gdextension_interface_string_new_with_utf8_chars = nullptr;
GDExtensionInterfaceStringNewWithUtf16Chars gdextension_interface_string_new_with_utf16_chars = nullptr;
GDExtensionInterfaceStringNewWithUtf32Chars gdextension_interface_string_new_with_utf32_chars = nullptr;
GDExtensionInterfaceStringNewWithWideChars gdextension_interface_string_new_with_wide_chars = nullptr;
GDExtensionInterfaceStringNewWithLatin1CharsAndLen gdextension_interface_string_new_with_latin1_chars_and_len = nullptr;
GDExtensionInterfaceStringNewWithUtf8CharsAndLen gdextension_interface_string_new_with_utf8_chars_and_len = nullptr;
GDExtensionInterfaceStringNewWithUtf8CharsAndLen2 gdextension_interface_string_new_with_utf8_chars_and_len2 = nullptr;
GDExtensionInterfaceStringNewWithUtf16CharsAndLen gdextension_interface_string_new_with_utf16_chars_and_len = nullptr;
GDExtensionInterfaceStringNewWithUtf16CharsAndLen2 gdextension_interface_string_new_with_utf16_chars_and_len2 = nullptr;
GDExtensionInterfaceStringNewWithUtf32CharsAndLen gdextension_interface_string_new_with_utf32_chars_and_len = nullptr;
GDExtensionInterfaceStringNewWithWideCharsAndLen gdextension_interface_string_new_with_wide_chars_and_len = nullptr;
GDExtensionInterfaceStringToLatin1Chars gdextension_interface_string_to_latin1_chars = nullptr;
GDExtensionInterfaceStringToUtf8Chars gdextension_interface_string_to_utf8_chars = nullptr;
GDExtensionInterfaceStringToUtf16Chars gdextension_interface_string_to_utf16_chars = nullptr;
GDExtensionInterfaceStringToUtf32Chars gdextension_interface_string_to_utf32_chars = nullptr;
GDExtensionInterfaceStringToWideChars gdextension_interface_string_to_wide_chars = nullptr;
GDExtensionInterfaceStringOperatorIndex gdextension_interface_string_operator_index = nullptr;
GDExtensionInterfaceStringOperatorIndexConst gdextension_interface_string_operator_index_const = nullptr;
GDExtensionInterfaceStringOperatorPlusEqString gdextension_interface_string_operator_plus_eq_string = nullptr;
GDExtensionInterfaceStringOperatorPlusEqChar gdextension_interface_string_operator_plus_eq_char = nullptr;
GDExtensionInterfaceStringOperatorPlusEqCstr gdextension_interface_string_operator_plus_eq_cstr = nullptr;
GDExtensionInterfaceStringOperatorPlusEqWcstr gdextension_interface_string_operator_plus_eq_wcstr = nullptr;
GDExtensionInterfaceStringOperatorPlusEqC32str gdextension_interface_string_operator_plus_eq_c32str = nullptr;
GDExtensionInterfaceStringResize gdextension_interface_string_resize = nullptr;
GDExtensionInterfaceStringNameNewWithLatin1Chars gdextension_interface_string_name_new_with_latin1_chars = nullptr;
GDExtensionInterfaceXmlParserOpenBuffer gdextension_interface_xml_parser_open_buffer = nullptr;
GDExtensionInterfaceFileAccessStoreBuffer gdextension_interface_file_access_store_buffer = nullptr;
GDExtensionInterfaceFileAccessGetBuffer gdextension_interface_file_access_get_buffer = nullptr;
GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask gdextension_interface_worker_thread_pool_add_native_group_task = nullptr;
GDExtensionInterfaceWorkerThreadPoolAddNativeTask gdextension_interface_worker_thread_pool_add_native_task = nullptr;
GDExtensionInterfacePackedByteArrayOperatorIndex gdextension_interface_packed_byte_array_operator_index = nullptr;
GDExtensionInterfacePackedByteArrayOperatorIndexConst gdextension_interface_packed_byte_array_operator_index_const = nullptr;
GDExtensionInterfacePackedColorArrayOperatorIndex gdextension_interface_packed_color_array_operator_index = nullptr;
GDExtensionInterfacePackedColorArrayOperatorIndexConst gdextension_interface_packed_color_array_operator_index_const = nullptr;
GDExtensionInterfacePackedFloat32ArrayOperatorIndex gdextension_interface_packed_float32_array_operator_index = nullptr;
GDExtensionInterfacePackedFloat32ArrayOperatorIndexConst gdextension_interface_packed_float32_array_operator_index_const = nullptr;
GDExtensionInterfacePackedFloat64ArrayOperatorIndex gdextension_interface_packed_float64_array_operator_index = nullptr;
GDExtensionInterfacePackedFloat64ArrayOperatorIndexConst gdextension_interface_packed_float64_array_operator_index_const = nullptr;
GDExtensionInterfacePackedInt32ArrayOperatorIndex gdextension_interface_packed_int32_array_operator_index = nullptr;
GDExtensionInterfacePackedInt32ArrayOperatorIndexConst gdextension_interface_packed_int32_array_operator_index_const = nullptr;
GDExtensionInterfacePackedInt64ArrayOperatorIndex gdextension_interface_packed_int64_array_operator_index = nullptr;
GDExtensionInterfacePackedInt64ArrayOperatorIndexConst gdextension_interface_packed_int64_array_operator_index_const = nullptr;
GDExtensionInterfacePackedStringArrayOperatorIndex gdextension_interface_packed_string_array_operator_index = nullptr;
GDExtensionInterfacePackedStringArrayOperatorIndexConst gdextension_interface_packed_string_array_operator_index_const = nullptr;
GDExtensionInterfacePackedVector2ArrayOperatorIndex gdextension_interface_packed_vector2_array_operator_index = nullptr;
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;
GDExtensionInterfaceArraySetTyped gdextension_interface_array_set_typed = nullptr;
GDExtensionInterfaceDictionaryOperatorIndex gdextension_interface_dictionary_operator_index = nullptr;
GDExtensionInterfaceDictionaryOperatorIndexConst gdextension_interface_dictionary_operator_index_const = nullptr;
GDExtensionInterfaceDictionarySetTyped gdextension_interface_dictionary_set_typed = nullptr;
GDExtensionInterfaceObjectMethodBindCall gdextension_interface_object_method_bind_call = nullptr;
GDExtensionInterfaceObjectMethodBindPtrcall gdextension_interface_object_method_bind_ptrcall = nullptr;
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;
GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id = nullptr;
GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id = nullptr;
GDExtensionInterfaceObjectHasScriptMethod gdextension_interface_object_has_script_method = nullptr;
GDExtensionInterfaceObjectCallScriptMethod gdextension_interface_object_call_script_method = nullptr;
GDExtensionInterfaceCallableCustomCreate2 gdextension_interface_callable_custom_create2 = nullptr;
GDExtensionInterfaceCallableCustomGetUserData gdextension_interface_callable_custom_get_userdata = nullptr;
GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object = nullptr;
GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object = nullptr;
GDExtensionInterfaceScriptInstanceCreate3 gdextension_interface_script_instance_create3 = nullptr;
GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create = nullptr;
GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update = nullptr;
GDExtensionInterfaceObjectGetScriptInstance gdextension_interface_object_get_script_instance = nullptr;
GDExtensionInterfaceObjectSetScriptInstance gdextension_interface_object_set_script_instance = nullptr;
GDExtensionInterfaceClassdbConstructObject2 gdextension_interface_classdb_construct_object2 = nullptr;
GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind = nullptr;
GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClass5 gdextension_interface_classdb_register_extension_class5 = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup gdextension_interface_classdb_register_extension_class_property_group = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup gdextension_interface_classdb_register_extension_class_property_subgroup = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassSignal gdextension_interface_classdb_register_extension_class_signal = nullptr;
GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_interface_classdb_unregister_extension_class = nullptr;
GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path = nullptr;
GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin = nullptr;
GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin = nullptr;
GDExtensionInterfaceEditorRegisterGetClassesUsedCallback gdextension_interface_editor_register_get_classes_used_callback = nullptr;
GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars = nullptr;
GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len = nullptr;
GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw = nullptr;
GDExtensionInterfaceImagePtr gdextension_interface_image_ptr = nullptr;
GDExtensionInterfaceRegisterMainLoopCallbacks gdextension_interface_register_main_loop_callbacks = nullptr;
} // namespace gdextension_interface
namespace internal {
struct DocData {
const char *hash = nullptr;
@@ -250,16 +92,6 @@ bool GDExtensionBinding::api_initialized = false;
int GDExtensionBinding::level_initialized[MODULE_INITIALIZATION_LEVEL_MAX] = { 0 };
GDExtensionBinding::InitDataList GDExtensionBinding::initdata;
#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 {
uint32_t version_major;
@@ -294,35 +126,35 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
if (uintptr_t(p_get_proc_address) % alignof(LegacyGDExtensionInterface) == 0 && 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 = (GDExtensionInterfacePrintError)legacy_interface->print_error;
::godot::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" 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) {
::godot::gdextension_interface::print_error = (GDExtensionInterfacePrintError)p_get_proc_address("print_error");
if (!::godot::gdextension_interface::print_error) {
printf("ERROR: Unable to load GDExtension interface function print_error().\n");
return false;
}
internal::gdextension_interface_get_proc_address = p_get_proc_address;
internal::library = p_library;
internal::token = p_library;
::godot::gdextension_interface::get_proc_address = p_get_proc_address;
::godot::gdextension_interface::library = p_library;
::godot::gdextension_interface::token = p_library;
LOAD_PROC_ADDRESS(get_godot_version2, GDExtensionInterfaceGetGodotVersion2);
internal::gdextension_interface_get_godot_version2(&internal::godot_version);
::godot::gdextension_interface::get_godot_version2(&::godot::gdextension_interface::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;
if (::godot::gdextension_interface::godot_version.major != GODOT_VERSION_MAJOR) {
compatible = ::godot::gdextension_interface::godot_version.major > GODOT_VERSION_MAJOR;
} else if (::godot::gdextension_interface::godot_version.minor != GODOT_VERSION_MINOR) {
compatible = ::godot::gdextension_interface::godot_version.minor > GODOT_VERSION_MINOR;
} else {
#if GODOT_VERSION_PATCH > 0
compatible = internal::godot_version.patch >= GODOT_VERSION_PATCH;
compatible = ::godot::gdextension_interface::godot_version.patch >= GODOT_VERSION_PATCH;
#else
// Prevent -Wtype-limits warning due to unsigned comparison.
compatible = true;
@@ -334,170 +166,14 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
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);
::godot::gdextension_interface::godot_version.major, ::godot::gdextension_interface::godot_version.minor, ::godot::gdextension_interface::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);
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);
LOAD_PROC_ADDRESS(print_script_error_with_message, GDExtensionInterfacePrintScriptErrorWithMessage);
LOAD_PROC_ADDRESS(get_native_struct_size, GDExtensionInterfaceGetNativeStructSize);
LOAD_PROC_ADDRESS(variant_new_copy, GDExtensionInterfaceVariantNewCopy);
LOAD_PROC_ADDRESS(variant_new_nil, GDExtensionInterfaceVariantNewNil);
LOAD_PROC_ADDRESS(variant_destroy, GDExtensionInterfaceVariantDestroy);
LOAD_PROC_ADDRESS(variant_call, GDExtensionInterfaceVariantCall);
LOAD_PROC_ADDRESS(variant_call_static, GDExtensionInterfaceVariantCallStatic);
LOAD_PROC_ADDRESS(variant_evaluate, GDExtensionInterfaceVariantEvaluate);
LOAD_PROC_ADDRESS(variant_set, GDExtensionInterfaceVariantSet);
LOAD_PROC_ADDRESS(variant_set_named, GDExtensionInterfaceVariantSetNamed);
LOAD_PROC_ADDRESS(variant_set_keyed, GDExtensionInterfaceVariantSetKeyed);
LOAD_PROC_ADDRESS(variant_set_indexed, GDExtensionInterfaceVariantSetIndexed);
LOAD_PROC_ADDRESS(variant_get, GDExtensionInterfaceVariantGet);
LOAD_PROC_ADDRESS(variant_get_named, GDExtensionInterfaceVariantGetNamed);
LOAD_PROC_ADDRESS(variant_get_keyed, GDExtensionInterfaceVariantGetKeyed);
LOAD_PROC_ADDRESS(variant_get_indexed, GDExtensionInterfaceVariantGetIndexed);
LOAD_PROC_ADDRESS(variant_iter_init, GDExtensionInterfaceVariantIterInit);
LOAD_PROC_ADDRESS(variant_iter_next, GDExtensionInterfaceVariantIterNext);
LOAD_PROC_ADDRESS(variant_iter_get, GDExtensionInterfaceVariantIterGet);
LOAD_PROC_ADDRESS(variant_hash, GDExtensionInterfaceVariantHash);
LOAD_PROC_ADDRESS(variant_recursive_hash, GDExtensionInterfaceVariantRecursiveHash);
LOAD_PROC_ADDRESS(variant_hash_compare, GDExtensionInterfaceVariantHashCompare);
LOAD_PROC_ADDRESS(variant_booleanize, GDExtensionInterfaceVariantBooleanize);
LOAD_PROC_ADDRESS(variant_duplicate, GDExtensionInterfaceVariantDuplicate);
LOAD_PROC_ADDRESS(variant_stringify, GDExtensionInterfaceVariantStringify);
LOAD_PROC_ADDRESS(variant_get_type, GDExtensionInterfaceVariantGetType);
LOAD_PROC_ADDRESS(variant_has_method, GDExtensionInterfaceVariantHasMethod);
LOAD_PROC_ADDRESS(variant_has_member, GDExtensionInterfaceVariantHasMember);
LOAD_PROC_ADDRESS(variant_has_key, GDExtensionInterfaceVariantHasKey);
LOAD_PROC_ADDRESS(variant_get_object_instance_id, GDExtensionInterfaceVariantGetObjectInstanceId);
LOAD_PROC_ADDRESS(variant_get_type_name, GDExtensionInterfaceVariantGetTypeName);
LOAD_PROC_ADDRESS(variant_can_convert, GDExtensionInterfaceVariantCanConvert);
LOAD_PROC_ADDRESS(variant_can_convert_strict, GDExtensionInterfaceVariantCanConvertStrict);
LOAD_PROC_ADDRESS(get_variant_from_type_constructor, GDExtensionInterfaceGetVariantFromTypeConstructor);
LOAD_PROC_ADDRESS(get_variant_to_type_constructor, GDExtensionInterfaceGetVariantToTypeConstructor);
LOAD_PROC_ADDRESS(variant_get_ptr_internal_getter, GDExtensionInterfaceGetVariantGetInternalPtrFunc);
LOAD_PROC_ADDRESS(variant_get_ptr_operator_evaluator, GDExtensionInterfaceVariantGetPtrOperatorEvaluator);
LOAD_PROC_ADDRESS(variant_get_ptr_builtin_method, GDExtensionInterfaceVariantGetPtrBuiltinMethod);
LOAD_PROC_ADDRESS(variant_get_ptr_constructor, GDExtensionInterfaceVariantGetPtrConstructor);
LOAD_PROC_ADDRESS(variant_get_ptr_destructor, GDExtensionInterfaceVariantGetPtrDestructor);
LOAD_PROC_ADDRESS(variant_construct, GDExtensionInterfaceVariantConstruct);
LOAD_PROC_ADDRESS(variant_get_ptr_setter, GDExtensionInterfaceVariantGetPtrSetter);
LOAD_PROC_ADDRESS(variant_get_ptr_getter, GDExtensionInterfaceVariantGetPtrGetter);
LOAD_PROC_ADDRESS(variant_get_ptr_indexed_setter, GDExtensionInterfaceVariantGetPtrIndexedSetter);
LOAD_PROC_ADDRESS(variant_get_ptr_indexed_getter, GDExtensionInterfaceVariantGetPtrIndexedGetter);
LOAD_PROC_ADDRESS(variant_get_ptr_keyed_setter, GDExtensionInterfaceVariantGetPtrKeyedSetter);
LOAD_PROC_ADDRESS(variant_get_ptr_keyed_getter, GDExtensionInterfaceVariantGetPtrKeyedGetter);
LOAD_PROC_ADDRESS(variant_get_ptr_keyed_checker, GDExtensionInterfaceVariantGetPtrKeyedChecker);
LOAD_PROC_ADDRESS(variant_get_constant_value, GDExtensionInterfaceVariantGetConstantValue);
LOAD_PROC_ADDRESS(variant_get_ptr_utility_function, GDExtensionInterfaceVariantGetPtrUtilityFunction);
LOAD_PROC_ADDRESS(string_new_with_latin1_chars, GDExtensionInterfaceStringNewWithLatin1Chars);
LOAD_PROC_ADDRESS(string_new_with_utf8_chars, GDExtensionInterfaceStringNewWithUtf8Chars);
LOAD_PROC_ADDRESS(string_new_with_utf16_chars, GDExtensionInterfaceStringNewWithUtf16Chars);
LOAD_PROC_ADDRESS(string_new_with_utf32_chars, GDExtensionInterfaceStringNewWithUtf32Chars);
LOAD_PROC_ADDRESS(string_new_with_wide_chars, GDExtensionInterfaceStringNewWithWideChars);
LOAD_PROC_ADDRESS(string_new_with_latin1_chars_and_len, GDExtensionInterfaceStringNewWithLatin1CharsAndLen);
LOAD_PROC_ADDRESS(string_new_with_utf8_chars_and_len, GDExtensionInterfaceStringNewWithUtf8CharsAndLen);
LOAD_PROC_ADDRESS(string_new_with_utf8_chars_and_len2, GDExtensionInterfaceStringNewWithUtf8CharsAndLen2);
LOAD_PROC_ADDRESS(string_new_with_utf16_chars_and_len, GDExtensionInterfaceStringNewWithUtf16CharsAndLen);
LOAD_PROC_ADDRESS(string_new_with_utf16_chars_and_len2, GDExtensionInterfaceStringNewWithUtf16CharsAndLen2);
LOAD_PROC_ADDRESS(string_new_with_utf32_chars_and_len, GDExtensionInterfaceStringNewWithUtf32CharsAndLen);
LOAD_PROC_ADDRESS(string_new_with_wide_chars_and_len, GDExtensionInterfaceStringNewWithWideCharsAndLen);
LOAD_PROC_ADDRESS(string_to_latin1_chars, GDExtensionInterfaceStringToLatin1Chars);
LOAD_PROC_ADDRESS(string_to_utf8_chars, GDExtensionInterfaceStringToUtf8Chars);
LOAD_PROC_ADDRESS(string_to_utf16_chars, GDExtensionInterfaceStringToUtf16Chars);
LOAD_PROC_ADDRESS(string_to_utf32_chars, GDExtensionInterfaceStringToUtf32Chars);
LOAD_PROC_ADDRESS(string_to_wide_chars, GDExtensionInterfaceStringToWideChars);
LOAD_PROC_ADDRESS(string_operator_index, GDExtensionInterfaceStringOperatorIndex);
LOAD_PROC_ADDRESS(string_operator_index_const, GDExtensionInterfaceStringOperatorIndexConst);
LOAD_PROC_ADDRESS(string_operator_plus_eq_string, GDExtensionInterfaceStringOperatorPlusEqString);
LOAD_PROC_ADDRESS(string_operator_plus_eq_char, GDExtensionInterfaceStringOperatorPlusEqChar);
LOAD_PROC_ADDRESS(string_operator_plus_eq_cstr, GDExtensionInterfaceStringOperatorPlusEqCstr);
LOAD_PROC_ADDRESS(string_operator_plus_eq_wcstr, GDExtensionInterfaceStringOperatorPlusEqWcstr);
LOAD_PROC_ADDRESS(string_operator_plus_eq_c32str, GDExtensionInterfaceStringOperatorPlusEqC32str);
LOAD_PROC_ADDRESS(string_resize, GDExtensionInterfaceStringResize);
LOAD_PROC_ADDRESS(string_name_new_with_latin1_chars, GDExtensionInterfaceStringNameNewWithLatin1Chars);
LOAD_PROC_ADDRESS(xml_parser_open_buffer, GDExtensionInterfaceXmlParserOpenBuffer);
LOAD_PROC_ADDRESS(file_access_store_buffer, GDExtensionInterfaceFileAccessStoreBuffer);
LOAD_PROC_ADDRESS(file_access_get_buffer, GDExtensionInterfaceFileAccessGetBuffer);
LOAD_PROC_ADDRESS(worker_thread_pool_add_native_group_task, GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask);
LOAD_PROC_ADDRESS(worker_thread_pool_add_native_task, GDExtensionInterfaceWorkerThreadPoolAddNativeTask);
LOAD_PROC_ADDRESS(packed_byte_array_operator_index, GDExtensionInterfacePackedByteArrayOperatorIndex);
LOAD_PROC_ADDRESS(packed_byte_array_operator_index_const, GDExtensionInterfacePackedByteArrayOperatorIndexConst);
LOAD_PROC_ADDRESS(packed_color_array_operator_index, GDExtensionInterfacePackedColorArrayOperatorIndex);
LOAD_PROC_ADDRESS(packed_color_array_operator_index_const, GDExtensionInterfacePackedColorArrayOperatorIndexConst);
LOAD_PROC_ADDRESS(packed_float32_array_operator_index, GDExtensionInterfacePackedFloat32ArrayOperatorIndex);
LOAD_PROC_ADDRESS(packed_float32_array_operator_index_const, GDExtensionInterfacePackedFloat32ArrayOperatorIndexConst);
LOAD_PROC_ADDRESS(packed_float64_array_operator_index, GDExtensionInterfacePackedFloat64ArrayOperatorIndex);
LOAD_PROC_ADDRESS(packed_float64_array_operator_index_const, GDExtensionInterfacePackedFloat64ArrayOperatorIndexConst);
LOAD_PROC_ADDRESS(packed_int32_array_operator_index, GDExtensionInterfacePackedInt32ArrayOperatorIndex);
LOAD_PROC_ADDRESS(packed_int32_array_operator_index_const, GDExtensionInterfacePackedInt32ArrayOperatorIndexConst);
LOAD_PROC_ADDRESS(packed_int64_array_operator_index, GDExtensionInterfacePackedInt64ArrayOperatorIndex);
LOAD_PROC_ADDRESS(packed_int64_array_operator_index_const, GDExtensionInterfacePackedInt64ArrayOperatorIndexConst);
LOAD_PROC_ADDRESS(packed_string_array_operator_index, GDExtensionInterfacePackedStringArrayOperatorIndex);
LOAD_PROC_ADDRESS(packed_string_array_operator_index_const, GDExtensionInterfacePackedStringArrayOperatorIndexConst);
LOAD_PROC_ADDRESS(packed_vector2_array_operator_index, GDExtensionInterfacePackedVector2ArrayOperatorIndex);
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_set_typed, GDExtensionInterfaceArraySetTyped);
LOAD_PROC_ADDRESS(dictionary_operator_index, GDExtensionInterfaceDictionaryOperatorIndex);
LOAD_PROC_ADDRESS(dictionary_operator_index_const, GDExtensionInterfaceDictionaryOperatorIndexConst);
LOAD_PROC_ADDRESS(dictionary_set_typed, GDExtensionInterfaceDictionarySetTyped);
LOAD_PROC_ADDRESS(object_method_bind_call, GDExtensionInterfaceObjectMethodBindCall);
LOAD_PROC_ADDRESS(object_method_bind_ptrcall, GDExtensionInterfaceObjectMethodBindPtrcall);
LOAD_PROC_ADDRESS(object_destroy, GDExtensionInterfaceObjectDestroy);
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);
LOAD_PROC_ADDRESS(object_get_instance_from_id, GDExtensionInterfaceObjectGetInstanceFromId);
LOAD_PROC_ADDRESS(object_get_instance_id, GDExtensionInterfaceObjectGetInstanceId);
LOAD_PROC_ADDRESS(object_has_script_method, GDExtensionInterfaceObjectHasScriptMethod);
LOAD_PROC_ADDRESS(object_call_script_method, GDExtensionInterfaceObjectCallScriptMethod);
LOAD_PROC_ADDRESS(callable_custom_create2, GDExtensionInterfaceCallableCustomCreate2);
LOAD_PROC_ADDRESS(callable_custom_get_userdata, GDExtensionInterfaceCallableCustomGetUserData);
LOAD_PROC_ADDRESS(ref_get_object, GDExtensionInterfaceRefGetObject);
LOAD_PROC_ADDRESS(ref_set_object, GDExtensionInterfaceRefSetObject);
LOAD_PROC_ADDRESS(script_instance_create3, GDExtensionInterfaceScriptInstanceCreate3);
LOAD_PROC_ADDRESS(placeholder_script_instance_create, GDExtensionInterfacePlaceHolderScriptInstanceCreate);
LOAD_PROC_ADDRESS(placeholder_script_instance_update, GDExtensionInterfacePlaceHolderScriptInstanceUpdate);
LOAD_PROC_ADDRESS(object_get_script_instance, GDExtensionInterfaceObjectGetScriptInstance);
LOAD_PROC_ADDRESS(object_set_script_instance, GDExtensionInterfaceObjectSetScriptInstance);
LOAD_PROC_ADDRESS(classdb_construct_object2, GDExtensionInterfaceClassdbConstructObject2);
LOAD_PROC_ADDRESS(classdb_get_method_bind, GDExtensionInterfaceClassdbGetMethodBind);
LOAD_PROC_ADDRESS(classdb_get_class_tag, GDExtensionInterfaceClassdbGetClassTag);
LOAD_PROC_ADDRESS(classdb_register_extension_class5, GDExtensionInterfaceClassdbRegisterExtensionClass5);
LOAD_PROC_ADDRESS(classdb_register_extension_class_method, GDExtensionInterfaceClassdbRegisterExtensionClassMethod);
LOAD_PROC_ADDRESS(classdb_register_extension_class_virtual_method, GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod);
LOAD_PROC_ADDRESS(classdb_register_extension_class_integer_constant, GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant);
LOAD_PROC_ADDRESS(classdb_register_extension_class_property, GDExtensionInterfaceClassdbRegisterExtensionClassProperty);
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_indexed, GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed);
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_group, GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup);
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_subgroup, GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup);
LOAD_PROC_ADDRESS(classdb_register_extension_class_signal, GDExtensionInterfaceClassdbRegisterExtensionClassSignal);
LOAD_PROC_ADDRESS(classdb_unregister_extension_class, GDExtensionInterfaceClassdbUnregisterExtensionClass);
LOAD_PROC_ADDRESS(get_library_path, GDExtensionInterfaceGetLibraryPath);
LOAD_PROC_ADDRESS(editor_add_plugin, GDExtensionInterfaceEditorAddPlugin);
LOAD_PROC_ADDRESS(editor_remove_plugin, GDExtensionInterfaceEditorRemovePlugin);
LOAD_PROC_ADDRESS(editor_register_get_classes_used_callback, GDExtensionInterfaceEditorRegisterGetClassesUsedCallback);
LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars);
LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars_and_len, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen);
LOAD_PROC_ADDRESS(image_ptrw, GDExtensionInterfaceImagePtrw);
LOAD_PROC_ADDRESS(image_ptr, GDExtensionInterfaceImagePtr);
LOAD_PROC_ADDRESS(register_main_loop_callbacks, GDExtensionInterfaceRegisterMainLoopCallbacks);
if (!::godot::internal::load_gdextension_interface(p_get_proc_address)) {
return false;
}
r_initialization->initialize = initialize_level;
r_initialization->deinitialize = deinitialize_level;
@@ -505,7 +181,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
r_initialization->minimum_initialization_level = p_init_data->minimum_initialization_level;
Variant::init_bindings();
godot::internal::register_engine_classes();
::godot::internal::register_engine_classes();
api_initialized = true;
return true;
@@ -529,13 +205,13 @@ void GDExtensionBinding::initialize_level(void *p_userdata, GDExtensionInitializ
level_initialized[p_level]++;
if ((ModuleInitializationLevel)p_level == MODULE_INITIALIZATION_LEVEL_CORE && init_data && init_data->has_main_loop_callbacks()) {
internal::gdextension_interface_register_main_loop_callbacks(internal::library, &init_data->main_loop_callbacks);
::godot::gdextension_interface::register_main_loop_callbacks(::godot::gdextension_interface::library, &init_data->main_loop_callbacks);
}
if ((ModuleInitializationLevel)p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
internal::gdextension_interface_editor_register_get_classes_used_callback(internal::library, &ClassDB::_editor_get_classes_used_callback);
::godot::gdextension_interface::editor_register_get_classes_used_callback(::godot::gdextension_interface::library, &ClassDB::_editor_get_classes_used_callback);
const internal::DocData &doc_data = internal::get_doc_data();
const ::godot::internal::DocData &doc_data = ::godot::internal::get_doc_data();
if (doc_data.is_valid()) {
doc_data.load_data();
}
@@ -618,7 +294,7 @@ GDExtensionBool GDExtensionBinding::InitObject::init() const {
return GDExtensionBinding::init(get_proc_address, library, init_data, initialization);
}
void internal::DocData::load_data() const {
void ::godot::internal::DocData::load_data() const {
PackedByteArray compressed;
compressed.resize(compressed_size);
memcpy(compressed.ptrw(), data, compressed_size);
@@ -626,7 +302,7 @@ void internal::DocData::load_data() const {
// 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);
::godot::gdextension_interface::editor_help_load_xml_from_utf8_chars_and_len(reinterpret_cast<const char *>(decompressed.ptr()), uncompressed_size);
}
} // namespace godot

View File

@@ -105,7 +105,7 @@ bool CallableCustom::is_valid() const {
Callable::Callable(CallableCustom *p_callable_custom) {
GDExtensionCallableCustomInfo2 info = {};
info.callable_userdata = p_callable_custom;
info.token = internal::token;
info.token = ::godot::gdextension_interface::token;
info.object_id = p_callable_custom->get_object();
info.call_func = &callable_custom_call;
info.is_valid_func = &callable_custom_is_valid;
@@ -116,11 +116,11 @@ Callable::Callable(CallableCustom *p_callable_custom) {
info.to_string_func = &callable_custom_to_string;
info.get_argument_count_func = &custom_callable_get_argument_count_func;
::godot::internal::gdextension_interface_callable_custom_create2(_native_ptr(), &info);
::godot::gdextension_interface::callable_custom_create2(_native_ptr(), &info);
}
CallableCustom *Callable::get_custom() const {
CallableCustomBase *callable_custom = (CallableCustomBase *)::godot::internal::gdextension_interface_callable_custom_get_userdata(_native_ptr(), internal::token);
CallableCustomBase *callable_custom = (CallableCustomBase *)::godot::gdextension_interface::callable_custom_get_userdata(_native_ptr(), ::godot::gdextension_interface::token);
return dynamic_cast<CallableCustom *>(callable_custom);
}

View File

@@ -103,7 +103,7 @@ namespace internal {
Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_method_pointer) {
GDExtensionCallableCustomInfo2 info = {};
info.callable_userdata = p_callable_method_pointer;
info.token = internal::token;
info.token = ::godot::gdextension_interface::token;
info.object_id = p_callable_method_pointer->get_object();
info.call_func = &custom_callable_mp_call;
info.is_valid_func = &custom_callable_mp_is_valid;
@@ -114,7 +114,7 @@ Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_m
info.get_argument_count_func = &custom_callable_mp_get_argument_count_func;
Callable callable;
::godot::internal::gdextension_interface_callable_custom_create2(callable._native_ptr(), &info);
::godot::gdextension_interface::callable_custom_create2(callable._native_ptr(), &info);
return callable;
}

View File

@@ -157,19 +157,19 @@ template class CharStringT<wchar_t>;
// It's easier to have them written in C++ directly than in a Python script that generates them.
String::String(const char *from) {
internal::gdextension_interface_string_new_with_latin1_chars(_native_ptr(), from);
::godot::gdextension_interface::string_new_with_latin1_chars(_native_ptr(), from);
}
String::String(const wchar_t *from) {
internal::gdextension_interface_string_new_with_wide_chars(_native_ptr(), from);
::godot::gdextension_interface::string_new_with_wide_chars(_native_ptr(), from);
}
String::String(const char16_t *from) {
internal::gdextension_interface_string_new_with_utf16_chars(_native_ptr(), from);
::godot::gdextension_interface::string_new_with_utf16_chars(_native_ptr(), from);
}
String::String(const char32_t *from) {
internal::gdextension_interface_string_new_with_utf32_chars(_native_ptr(), from);
::godot::gdextension_interface::string_new_with_utf32_chars(_native_ptr(), from);
}
String String::utf8(const char *from, int64_t len) {
@@ -179,7 +179,7 @@ String String::utf8(const char *from, int64_t len) {
}
Error String::parse_utf8(const char *from, int64_t len) {
return (Error)internal::gdextension_interface_string_new_with_utf8_chars_and_len2(_native_ptr(), from, len);
return (Error)::godot::gdextension_interface::string_new_with_utf8_chars_and_len2(_native_ptr(), from, len);
}
String String::utf16(const char16_t *from, int64_t len) {
@@ -189,7 +189,7 @@ String String::utf16(const char16_t *from, int64_t len) {
}
Error String::parse_utf16(const char16_t *from, int64_t len, bool default_little_endian) {
return (Error)internal::gdextension_interface_string_new_with_utf16_chars_and_len2(_native_ptr(), from, len, default_little_endian);
return (Error)::godot::gdextension_interface::string_new_with_utf16_chars_and_len2(_native_ptr(), from, len, default_little_endian);
}
String String::num_real(double p_num, bool p_trailing) {
@@ -230,11 +230,11 @@ String rtoss(double p_val) {
}
CharString String::utf8() const {
int64_t length = internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), nullptr, 0);
int64_t length = ::godot::gdextension_interface::string_to_utf8_chars(_native_ptr(), nullptr, 0);
int64_t size = length + 1;
CharString str;
str.resize(size);
internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), str.ptrw(), length);
::godot::gdextension_interface::string_to_utf8_chars(_native_ptr(), str.ptrw(), length);
str[length] = '\0';
@@ -242,11 +242,11 @@ CharString String::utf8() const {
}
CharString String::ascii() const {
int64_t length = internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), nullptr, 0);
int64_t length = ::godot::gdextension_interface::string_to_latin1_chars(_native_ptr(), nullptr, 0);
int64_t size = length + 1;
CharString str;
str.resize(size);
internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), str.ptrw(), length);
::godot::gdextension_interface::string_to_latin1_chars(_native_ptr(), str.ptrw(), length);
str[length] = '\0';
@@ -254,11 +254,11 @@ CharString String::ascii() const {
}
Char16String String::utf16() const {
int64_t length = internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), nullptr, 0);
int64_t length = ::godot::gdextension_interface::string_to_utf16_chars(_native_ptr(), nullptr, 0);
int64_t size = length + 1;
Char16String str;
str.resize(size);
internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), str.ptrw(), length);
::godot::gdextension_interface::string_to_utf16_chars(_native_ptr(), str.ptrw(), length);
str[length] = '\0';
@@ -266,11 +266,11 @@ Char16String String::utf16() const {
}
Char32String String::utf32() const {
int64_t length = internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), nullptr, 0);
int64_t length = ::godot::gdextension_interface::string_to_utf32_chars(_native_ptr(), nullptr, 0);
int64_t size = length + 1;
Char32String str;
str.resize(size);
internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), str.ptrw(), length);
::godot::gdextension_interface::string_to_utf32_chars(_native_ptr(), str.ptrw(), length);
str[length] = '\0';
@@ -278,11 +278,11 @@ Char32String String::utf32() const {
}
CharWideString String::wide_string() const {
int64_t length = internal::gdextension_interface_string_to_wide_chars(_native_ptr(), nullptr, 0);
int64_t length = ::godot::gdextension_interface::string_to_wide_chars(_native_ptr(), nullptr, 0);
int64_t size = length + 1;
CharWideString str;
str.resize(size);
internal::gdextension_interface_string_to_wide_chars(_native_ptr(), str.ptrw(), length);
::godot::gdextension_interface::string_to_wide_chars(_native_ptr(), str.ptrw(), length);
str[length] = '\0';
@@ -290,7 +290,7 @@ CharWideString String::wide_string() const {
}
Error String::resize(int64_t p_size) {
return (Error)internal::gdextension_interface_string_resize(_native_ptr(), p_size);
return (Error)::godot::gdextension_interface::string_resize(_native_ptr(), p_size);
}
String &String::operator=(const char *p_str) {
@@ -366,44 +366,44 @@ String String::operator+(const char32_t p_char) {
}
String &String::operator+=(const String &p_str) {
internal::gdextension_interface_string_operator_plus_eq_string((GDExtensionStringPtr)this, (GDExtensionConstStringPtr)&p_str);
::godot::gdextension_interface::string_operator_plus_eq_string((GDExtensionStringPtr)this, (GDExtensionConstStringPtr)&p_str);
return *this;
}
String &String::operator+=(char32_t p_char) {
internal::gdextension_interface_string_operator_plus_eq_char((GDExtensionStringPtr)this, p_char);
::godot::gdextension_interface::string_operator_plus_eq_char((GDExtensionStringPtr)this, p_char);
return *this;
}
String &String::operator+=(const char *p_str) {
internal::gdextension_interface_string_operator_plus_eq_cstr((GDExtensionStringPtr)this, p_str);
::godot::gdextension_interface::string_operator_plus_eq_cstr((GDExtensionStringPtr)this, p_str);
return *this;
}
String &String::operator+=(const wchar_t *p_str) {
internal::gdextension_interface_string_operator_plus_eq_wcstr((GDExtensionStringPtr)this, p_str);
::godot::gdextension_interface::string_operator_plus_eq_wcstr((GDExtensionStringPtr)this, p_str);
return *this;
}
String &String::operator+=(const char32_t *p_str) {
internal::gdextension_interface_string_operator_plus_eq_c32str((GDExtensionStringPtr)this, p_str);
::godot::gdextension_interface::string_operator_plus_eq_c32str((GDExtensionStringPtr)this, p_str);
return *this;
}
const char32_t &String::operator[](int64_t p_index) const {
return *internal::gdextension_interface_string_operator_index_const((GDExtensionStringPtr)this, p_index);
return *::godot::gdextension_interface::string_operator_index_const((GDExtensionStringPtr)this, p_index);
}
char32_t &String::operator[](int64_t p_index) {
return *internal::gdextension_interface_string_operator_index((GDExtensionStringPtr)this, p_index);
return *::godot::gdextension_interface::string_operator_index((GDExtensionStringPtr)this, p_index);
}
const char32_t *String::ptr() const {
return internal::gdextension_interface_string_operator_index_const((GDExtensionStringPtr)this, 0);
return ::godot::gdextension_interface::string_operator_index_const((GDExtensionStringPtr)this, 0);
}
char32_t *String::ptrw() {
return internal::gdextension_interface_string_operator_index((GDExtensionStringPtr)this, 0);
return ::godot::gdextension_interface::string_operator_index((GDExtensionStringPtr)this, 0);
}
bool operator==(const char *p_chr, const String &p_str) {
@@ -459,7 +459,7 @@ String operator+(char32_t p_char, const String &p_str) {
}
StringName::StringName(const char *from, bool p_static) {
internal::gdextension_interface_string_name_new_with_latin1_chars(&opaque, from, p_static);
::godot::gdextension_interface::string_name_new_with_latin1_chars(&opaque, from, p_static);
}
StringName::StringName(const wchar_t *from) :

View File

@@ -48,211 +48,211 @@
namespace godot {
const uint8_t &PackedByteArray::operator[](int64_t p_index) const {
return *internal::gdextension_interface_packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *::godot::gdextension_interface::packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
}
uint8_t &PackedByteArray::operator[](int64_t p_index) {
return *internal::gdextension_interface_packed_byte_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *::godot::gdextension_interface::packed_byte_array_operator_index((GDExtensionTypePtr *)this, p_index);
}
const uint8_t *PackedByteArray::ptr() const {
return internal::gdextension_interface_packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return ::godot::gdextension_interface::packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
uint8_t *PackedByteArray::ptrw() {
return internal::gdextension_interface_packed_byte_array_operator_index((GDExtensionTypePtr *)this, 0);
return ::godot::gdextension_interface::packed_byte_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const Color &PackedColorArray::operator[](int64_t p_index) const {
const Color *color = (const Color *)internal::gdextension_interface_packed_color_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
const Color *color = (const Color *)::godot::gdextension_interface::packed_color_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *color;
}
Color &PackedColorArray::operator[](int64_t p_index) {
Color *color = (Color *)internal::gdextension_interface_packed_color_array_operator_index((GDExtensionTypePtr *)this, p_index);
Color *color = (Color *)::godot::gdextension_interface::packed_color_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *color;
}
const Color *PackedColorArray::ptr() const {
return (const Color *)internal::gdextension_interface_packed_color_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return (const Color *)::godot::gdextension_interface::packed_color_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
Color *PackedColorArray::ptrw() {
return (Color *)internal::gdextension_interface_packed_color_array_operator_index((GDExtensionTypePtr *)this, 0);
return (Color *)::godot::gdextension_interface::packed_color_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const float &PackedFloat32Array::operator[](int64_t p_index) const {
return *internal::gdextension_interface_packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *::godot::gdextension_interface::packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
}
float &PackedFloat32Array::operator[](int64_t p_index) {
return *internal::gdextension_interface_packed_float32_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *::godot::gdextension_interface::packed_float32_array_operator_index((GDExtensionTypePtr *)this, p_index);
}
const float *PackedFloat32Array::ptr() const {
return internal::gdextension_interface_packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return ::godot::gdextension_interface::packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
float *PackedFloat32Array::ptrw() {
return internal::gdextension_interface_packed_float32_array_operator_index((GDExtensionTypePtr *)this, 0);
return ::godot::gdextension_interface::packed_float32_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const double &PackedFloat64Array::operator[](int64_t p_index) const {
return *internal::gdextension_interface_packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *::godot::gdextension_interface::packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
}
double &PackedFloat64Array::operator[](int64_t p_index) {
return *internal::gdextension_interface_packed_float64_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *::godot::gdextension_interface::packed_float64_array_operator_index((GDExtensionTypePtr *)this, p_index);
}
const double *PackedFloat64Array::ptr() const {
return internal::gdextension_interface_packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return ::godot::gdextension_interface::packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
double *PackedFloat64Array::ptrw() {
return internal::gdextension_interface_packed_float64_array_operator_index((GDExtensionTypePtr *)this, 0);
return ::godot::gdextension_interface::packed_float64_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const int32_t &PackedInt32Array::operator[](int64_t p_index) const {
return *internal::gdextension_interface_packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *::godot::gdextension_interface::packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
}
int32_t &PackedInt32Array::operator[](int64_t p_index) {
return *internal::gdextension_interface_packed_int32_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *::godot::gdextension_interface::packed_int32_array_operator_index((GDExtensionTypePtr *)this, p_index);
}
const int32_t *PackedInt32Array::ptr() const {
return internal::gdextension_interface_packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return ::godot::gdextension_interface::packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
int32_t *PackedInt32Array::ptrw() {
return internal::gdextension_interface_packed_int32_array_operator_index((GDExtensionTypePtr *)this, 0);
return ::godot::gdextension_interface::packed_int32_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const int64_t &PackedInt64Array::operator[](int64_t p_index) const {
return *internal::gdextension_interface_packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *::godot::gdextension_interface::packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
}
int64_t &PackedInt64Array::operator[](int64_t p_index) {
return *internal::gdextension_interface_packed_int64_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *::godot::gdextension_interface::packed_int64_array_operator_index((GDExtensionTypePtr *)this, p_index);
}
const int64_t *PackedInt64Array::ptr() const {
return internal::gdextension_interface_packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return ::godot::gdextension_interface::packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
int64_t *PackedInt64Array::ptrw() {
return internal::gdextension_interface_packed_int64_array_operator_index((GDExtensionTypePtr *)this, 0);
return ::godot::gdextension_interface::packed_int64_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const String &PackedStringArray::operator[](int64_t p_index) const {
const String *string = (const String *)internal::gdextension_interface_packed_string_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
const String *string = (const String *)::godot::gdextension_interface::packed_string_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *string;
}
String &PackedStringArray::operator[](int64_t p_index) {
String *string = (String *)internal::gdextension_interface_packed_string_array_operator_index((GDExtensionTypePtr *)this, p_index);
String *string = (String *)::godot::gdextension_interface::packed_string_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *string;
}
const String *PackedStringArray::ptr() const {
return (const String *)internal::gdextension_interface_packed_string_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return (const String *)::godot::gdextension_interface::packed_string_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
String *PackedStringArray::ptrw() {
return (String *)internal::gdextension_interface_packed_string_array_operator_index((GDExtensionTypePtr *)this, 0);
return (String *)::godot::gdextension_interface::packed_string_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const Vector2 &PackedVector2Array::operator[](int64_t p_index) const {
const Vector2 *vec = (const Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
const Vector2 *vec = (const Vector2 *)::godot::gdextension_interface::packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *vec;
}
Vector2 &PackedVector2Array::operator[](int64_t p_index) {
Vector2 *vec = (Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index((GDExtensionTypePtr *)this, p_index);
Vector2 *vec = (Vector2 *)::godot::gdextension_interface::packed_vector2_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *vec;
}
const Vector2 *PackedVector2Array::ptr() const {
return (const Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return (const Vector2 *)::godot::gdextension_interface::packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
Vector2 *PackedVector2Array::ptrw() {
return (Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index((GDExtensionTypePtr *)this, 0);
return (Vector2 *)::godot::gdextension_interface::packed_vector2_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const Vector3 &PackedVector3Array::operator[](int64_t p_index) const {
const Vector3 *vec = (const Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
const Vector3 *vec = (const Vector3 *)::godot::gdextension_interface::packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *vec;
}
Vector3 &PackedVector3Array::operator[](int64_t p_index) {
Vector3 *vec = (Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index((GDExtensionTypePtr *)this, p_index);
Vector3 *vec = (Vector3 *)::godot::gdextension_interface::packed_vector3_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *vec;
}
const Vector3 *PackedVector3Array::ptr() const {
return (const Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return (const Vector3 *)::godot::gdextension_interface::packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
Vector3 *PackedVector3Array::ptrw() {
return (Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index((GDExtensionTypePtr *)this, 0);
return (Vector3 *)::godot::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);
const Vector4 *vec = (const Vector4 *)::godot::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);
Vector4 *vec = (Vector4 *)::godot::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);
return (const Vector4 *)::godot::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);
return (Vector4 *)::godot::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);
const Variant *var = (const Variant *)::godot::gdextension_interface::array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *var;
}
Variant &Array::operator[](int64_t p_index) {
Variant *var = (Variant *)internal::gdextension_interface_array_operator_index((GDExtensionTypePtr *)this, p_index);
Variant *var = (Variant *)::godot::gdextension_interface::array_operator_index((GDExtensionTypePtr *)this, p_index);
return *var;
}
void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script) {
// p_type is not Variant::Type so that header doesn't depend on <variant.hpp>.
internal::gdextension_interface_array_set_typed((GDExtensionTypePtr *)this, (GDExtensionVariantType)p_type, (GDExtensionConstStringNamePtr)&p_class_name, (GDExtensionConstVariantPtr)&p_script);
::godot::gdextension_interface::array_set_typed((GDExtensionTypePtr *)this, (GDExtensionVariantType)p_type, (GDExtensionConstStringNamePtr)&p_class_name, (GDExtensionConstVariantPtr)&p_script);
}
const Variant *Array::ptr() const {
return (const Variant *)internal::gdextension_interface_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return (const Variant *)::godot::gdextension_interface::array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
Variant *Array::ptrw() {
return (Variant *)internal::gdextension_interface_array_operator_index((GDExtensionTypePtr *)this, 0);
return (Variant *)::godot::gdextension_interface::array_operator_index((GDExtensionTypePtr *)this, 0);
}
const Variant &Dictionary::operator[](const Variant &p_key) const {
const Variant *var = (const Variant *)internal::gdextension_interface_dictionary_operator_index_const((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
const Variant *var = (const Variant *)::godot::gdextension_interface::dictionary_operator_index_const((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
return *var;
}
Variant &Dictionary::operator[](const Variant &p_key) {
Variant *var = (Variant *)internal::gdextension_interface_dictionary_operator_index((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
Variant *var = (Variant *)::godot::gdextension_interface::dictionary_operator_index((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
return *var;
}
void Dictionary::set_typed(uint32_t p_key_type, const StringName &p_key_class_name, const Variant &p_key_script, uint32_t p_value_type, const StringName &p_value_class_name, const Variant &p_value_script) {
// p_key_type/p_value_type are not Variant::Type so that header doesn't depend on <variant.hpp>.
internal::gdextension_interface_dictionary_set_typed((GDExtensionTypePtr *)this, (GDExtensionVariantType)p_key_type, (GDExtensionConstStringNamePtr)&p_key_class_name, (GDExtensionConstVariantPtr)&p_key_script,
::godot::gdextension_interface::dictionary_set_typed((GDExtensionTypePtr *)this, (GDExtensionVariantType)p_key_type, (GDExtensionConstStringNamePtr)&p_key_class_name, (GDExtensionConstVariantPtr)&p_key_script,
(GDExtensionVariantType)p_value_type, (GDExtensionConstStringNamePtr)&p_value_class_name, (GDExtensionConstVariantPtr)&p_value_script);
}

View File

@@ -47,8 +47,8 @@ GDExtensionTypeFromVariantConstructorFunc Variant::to_type_constructor[Variant::
void Variant::init_bindings() {
// Start from 1 to skip NIL.
for (int i = 1; i < VARIANT_MAX; i++) {
from_type_constructor[i] = internal::gdextension_interface_get_variant_from_type_constructor((GDExtensionVariantType)i);
to_type_constructor[i] = internal::gdextension_interface_get_variant_to_type_constructor((GDExtensionVariantType)i);
from_type_constructor[i] = ::godot::gdextension_interface::get_variant_from_type_constructor((GDExtensionVariantType)i);
to_type_constructor[i] = ::godot::gdextension_interface::get_variant_to_type_constructor((GDExtensionVariantType)i);
}
VariantInternal::init_bindings();
@@ -73,15 +73,15 @@ void Variant::init_bindings() {
}
Variant::Variant() {
internal::gdextension_interface_variant_new_nil(_native_ptr());
::godot::gdextension_interface::variant_new_nil(_native_ptr());
}
Variant::Variant(GDExtensionConstVariantPtr native_ptr) {
internal::gdextension_interface_variant_new_copy(_native_ptr(), native_ptr);
::godot::gdextension_interface::variant_new_copy(_native_ptr(), native_ptr);
}
Variant::Variant(const Variant &other) {
internal::gdextension_interface_variant_new_copy(_native_ptr(), other._native_ptr());
::godot::gdextension_interface::variant_new_copy(_native_ptr(), other._native_ptr());
}
Variant::Variant(Variant &&other) {
@@ -256,7 +256,7 @@ Variant::Variant(const PackedVector4Array &v) {
}
Variant::~Variant() {
internal::gdextension_interface_variant_destroy(_native_ptr());
::godot::gdextension_interface::variant_destroy(_native_ptr());
}
Variant::operator bool() const {
@@ -443,14 +443,14 @@ Variant::operator Object *() const {
if (obj == nullptr) {
return nullptr;
}
return internal::get_object_instance_binding(obj);
return ::godot::internal::get_object_instance_binding(obj);
}
Variant::operator ObjectID() const {
if (get_type() == Type::INT) {
return ObjectID(operator uint64_t());
} else if (get_type() == Type::OBJECT) {
return ObjectID(internal::gdextension_interface_variant_get_object_instance_id(_native_ptr()));
return ObjectID(::godot::gdextension_interface::variant_get_object_instance_id(_native_ptr()));
} else {
return ObjectID();
}
@@ -518,7 +518,7 @@ Object *Variant::get_validated_object() const {
Variant &Variant::operator=(const Variant &other) {
clear();
internal::gdextension_interface_variant_new_copy(_native_ptr(), other._native_ptr());
::godot::gdextension_interface::variant_new_copy(_native_ptr(), other._native_ptr());
return *this;
}
@@ -558,22 +558,22 @@ bool Variant::operator<(const Variant &other) const {
}
void Variant::callp(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
internal::gdextension_interface_variant_call(_native_ptr(), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
::godot::gdextension_interface::variant_call(_native_ptr(), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
}
void Variant::callp_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
internal::gdextension_interface_variant_call_static(static_cast<GDExtensionVariantType>(type), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
::godot::gdextension_interface::variant_call_static(static_cast<GDExtensionVariantType>(type), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
}
void Variant::evaluate(const Operator &op, const Variant &a, const Variant &b, Variant &r_ret, bool &r_valid) {
GDExtensionBool valid;
internal::gdextension_interface_variant_evaluate(static_cast<GDExtensionVariantOperator>(op), a._native_ptr(), b._native_ptr(), r_ret._native_ptr(), &valid);
::godot::gdextension_interface::variant_evaluate(static_cast<GDExtensionVariantOperator>(op), a._native_ptr(), b._native_ptr(), r_ret._native_ptr(), &valid);
r_valid = PtrToArg<bool>::convert(&valid);
}
void Variant::set(const Variant &key, const Variant &value, bool *r_valid) {
GDExtensionBool valid;
internal::gdextension_interface_variant_set(_native_ptr(), key._native_ptr(), value._native_ptr(), &valid);
::godot::gdextension_interface::variant_set(_native_ptr(), key._native_ptr(), value._native_ptr(), &valid);
if (r_valid) {
*r_valid = PtrToArg<bool>::convert(&valid);
}
@@ -581,27 +581,27 @@ void Variant::set(const Variant &key, const Variant &value, bool *r_valid) {
void Variant::set_named(const StringName &name, const Variant &value, bool &r_valid) {
GDExtensionBool valid;
internal::gdextension_interface_variant_set_named(_native_ptr(), name._native_ptr(), value._native_ptr(), &valid);
::godot::gdextension_interface::variant_set_named(_native_ptr(), name._native_ptr(), value._native_ptr(), &valid);
r_valid = PtrToArg<bool>::convert(&valid);
}
void Variant::set_indexed(int64_t index, const Variant &value, bool &r_valid, bool &r_oob) {
GDExtensionBool valid, oob;
internal::gdextension_interface_variant_set_indexed(_native_ptr(), index, value._native_ptr(), &valid, &oob);
::godot::gdextension_interface::variant_set_indexed(_native_ptr(), index, value._native_ptr(), &valid, &oob);
r_valid = PtrToArg<bool>::convert(&valid);
r_oob = PtrToArg<bool>::convert(&oob);
}
void Variant::set_keyed(const Variant &key, const Variant &value, bool &r_valid) {
GDExtensionBool valid;
internal::gdextension_interface_variant_set_keyed(_native_ptr(), key._native_ptr(), value._native_ptr(), &valid);
::godot::gdextension_interface::variant_set_keyed(_native_ptr(), key._native_ptr(), value._native_ptr(), &valid);
r_valid = PtrToArg<bool>::convert(&valid);
}
Variant Variant::get(const Variant &key, bool *r_valid) const {
Variant result;
GDExtensionBool valid;
internal::gdextension_interface_variant_get(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
::godot::gdextension_interface::variant_get(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
if (r_valid) {
*r_valid = PtrToArg<bool>::convert(&valid);
}
@@ -611,7 +611,7 @@ Variant Variant::get(const Variant &key, bool *r_valid) const {
Variant Variant::get_named(const StringName &name, bool &r_valid) const {
Variant result;
GDExtensionBool valid;
internal::gdextension_interface_variant_get_named(_native_ptr(), name._native_ptr(), result._native_ptr(), &valid);
::godot::gdextension_interface::variant_get_named(_native_ptr(), name._native_ptr(), result._native_ptr(), &valid);
r_valid = PtrToArg<bool>::convert(&valid);
return result;
}
@@ -620,7 +620,7 @@ Variant Variant::get_indexed(int64_t index, bool &r_valid, bool &r_oob) const {
Variant result;
GDExtensionBool valid;
GDExtensionBool oob;
internal::gdextension_interface_variant_get_indexed(_native_ptr(), index, result._native_ptr(), &valid, &oob);
::godot::gdextension_interface::variant_get_indexed(_native_ptr(), index, result._native_ptr(), &valid, &oob);
r_valid = PtrToArg<bool>::convert(&valid);
r_oob = PtrToArg<bool>::convert(&oob);
return result;
@@ -629,7 +629,7 @@ Variant Variant::get_indexed(int64_t index, bool &r_valid, bool &r_oob) const {
Variant Variant::get_keyed(const Variant &key, bool &r_valid) const {
Variant result;
GDExtensionBool valid;
internal::gdextension_interface_variant_get_keyed(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
::godot::gdextension_interface::variant_get_keyed(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
r_valid = PtrToArg<bool>::convert(&valid);
return result;
}
@@ -646,14 +646,14 @@ bool Variant::in(const Variant &index, bool *r_valid) const {
bool Variant::iter_init(Variant &r_iter, bool &r_valid) const {
GDExtensionBool valid;
GDExtensionBool result = internal::gdextension_interface_variant_iter_init(_native_ptr(), r_iter._native_ptr(), &valid);
GDExtensionBool result = ::godot::gdextension_interface::variant_iter_init(_native_ptr(), r_iter._native_ptr(), &valid);
r_valid = PtrToArg<bool>::convert(&valid);
return PtrToArg<bool>::convert(&result);
}
bool Variant::iter_next(Variant &r_iter, bool &r_valid) const {
GDExtensionBool valid;
GDExtensionBool result = internal::gdextension_interface_variant_iter_next(_native_ptr(), r_iter._native_ptr(), &valid);
GDExtensionBool result = ::godot::gdextension_interface::variant_iter_next(_native_ptr(), r_iter._native_ptr(), &valid);
r_valid = PtrToArg<bool>::convert(&valid);
return PtrToArg<bool>::convert(&result);
}
@@ -661,23 +661,23 @@ bool Variant::iter_next(Variant &r_iter, bool &r_valid) const {
Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
Variant result;
GDExtensionBool valid;
internal::gdextension_interface_variant_iter_get(_native_ptr(), r_iter._native_ptr(), result._native_ptr(), &valid);
::godot::gdextension_interface::variant_iter_get(_native_ptr(), r_iter._native_ptr(), result._native_ptr(), &valid);
r_valid = PtrToArg<bool>::convert(&valid);
return result;
}
Variant::Type Variant::get_type() const {
return static_cast<Variant::Type>(internal::gdextension_interface_variant_get_type(_native_ptr()));
return static_cast<Variant::Type>(::godot::gdextension_interface::variant_get_type(_native_ptr()));
}
bool Variant::has_method(const StringName &method) const {
GDExtensionBool has = internal::gdextension_interface_variant_has_method(_native_ptr(), method._native_ptr());
GDExtensionBool has = ::godot::gdextension_interface::variant_has_method(_native_ptr(), method._native_ptr());
return PtrToArg<bool>::convert(&has);
}
bool Variant::has_key(const Variant &key, bool *r_valid) const {
GDExtensionBool valid;
GDExtensionBool has = internal::gdextension_interface_variant_has_key(_native_ptr(), key._native_ptr(), &valid);
GDExtensionBool has = ::godot::gdextension_interface::variant_has_key(_native_ptr(), key._native_ptr(), &valid);
if (r_valid) {
*r_valid = PtrToArg<bool>::convert(&valid);
}
@@ -685,33 +685,33 @@ bool Variant::has_key(const Variant &key, bool *r_valid) const {
}
bool Variant::has_member(Variant::Type type, const StringName &member) {
GDExtensionBool has = internal::gdextension_interface_variant_has_member(static_cast<GDExtensionVariantType>(type), member._native_ptr());
GDExtensionBool has = ::godot::gdextension_interface::variant_has_member(static_cast<GDExtensionVariantType>(type), member._native_ptr());
return PtrToArg<bool>::convert(&has);
}
uint32_t Variant::hash() const {
GDExtensionInt hash = internal::gdextension_interface_variant_hash(_native_ptr());
GDExtensionInt hash = ::godot::gdextension_interface::variant_hash(_native_ptr());
return PtrToArg<uint32_t>::convert(&hash);
}
uint32_t Variant::recursive_hash(int recursion_count) const {
GDExtensionInt hash = internal::gdextension_interface_variant_recursive_hash(_native_ptr(), recursion_count);
GDExtensionInt hash = ::godot::gdextension_interface::variant_recursive_hash(_native_ptr(), recursion_count);
return PtrToArg<uint32_t>::convert(&hash);
}
bool Variant::hash_compare(const Variant &variant) const {
GDExtensionBool compare = internal::gdextension_interface_variant_hash_compare(_native_ptr(), variant._native_ptr());
GDExtensionBool compare = ::godot::gdextension_interface::variant_hash_compare(_native_ptr(), variant._native_ptr());
return PtrToArg<bool>::convert(&compare);
}
bool Variant::booleanize() const {
GDExtensionBool booleanized = internal::gdextension_interface_variant_booleanize(_native_ptr());
GDExtensionBool booleanized = ::godot::gdextension_interface::variant_booleanize(_native_ptr());
return PtrToArg<bool>::convert(&booleanized);
}
String Variant::stringify() const {
String result;
internal::gdextension_interface_variant_stringify(_native_ptr(), result._native_ptr());
::godot::gdextension_interface::variant_stringify(_native_ptr(), result._native_ptr());
return result;
}
@@ -719,23 +719,23 @@ Variant Variant::duplicate(bool deep) const {
Variant result;
GDExtensionBool _deep;
PtrToArg<bool>::encode(deep, &_deep);
internal::gdextension_interface_variant_duplicate(_native_ptr(), result._native_ptr(), _deep);
::godot::gdextension_interface::variant_duplicate(_native_ptr(), result._native_ptr(), _deep);
return result;
}
String Variant::get_type_name(Variant::Type type) {
String result;
internal::gdextension_interface_variant_get_type_name(static_cast<GDExtensionVariantType>(type), result._native_ptr());
::godot::gdextension_interface::variant_get_type_name(static_cast<GDExtensionVariantType>(type), result._native_ptr());
return result;
}
bool Variant::can_convert(Variant::Type from, Variant::Type to) {
GDExtensionBool can = internal::gdextension_interface_variant_can_convert(static_cast<GDExtensionVariantType>(from), static_cast<GDExtensionVariantType>(to));
GDExtensionBool can = ::godot::gdextension_interface::variant_can_convert(static_cast<GDExtensionVariantType>(from), static_cast<GDExtensionVariantType>(to));
return PtrToArg<bool>::convert(&can);
}
bool Variant::can_convert_strict(Variant::Type from, Variant::Type to) {
GDExtensionBool can = internal::gdextension_interface_variant_can_convert_strict(static_cast<GDExtensionVariantType>(from), static_cast<GDExtensionVariantType>(to));
GDExtensionBool can = ::godot::gdextension_interface::variant_can_convert_strict(static_cast<GDExtensionVariantType>(from), static_cast<GDExtensionVariantType>(to));
return PtrToArg<bool>::convert(&can);
}
@@ -786,9 +786,9 @@ void Variant::clear() {
};
if (unlikely(needs_deinit[get_type()])) { // Make it fast for types that don't need deinit.
internal::gdextension_interface_variant_destroy(_native_ptr());
::godot::gdextension_interface::variant_destroy(_native_ptr());
}
internal::gdextension_interface_variant_new_nil(_native_ptr());
::godot::gdextension_interface::variant_new_nil(_native_ptr());
}
} // namespace godot

View File

@@ -36,7 +36,7 @@ GDExtensionVariantGetInternalPtrFunc VariantInternal::get_internal_func[Variant:
void VariantInternal::init_bindings() {
for (int i = 1; i < Variant::VARIANT_MAX; i++) {
get_internal_func[i] = internal::gdextension_interface_variant_get_ptr_internal_getter((GDExtensionVariantType)i);
get_internal_func[i] = ::godot::gdextension_interface::variant_get_ptr_internal_getter((GDExtensionVariantType)i);
}
}

View File

@@ -8,6 +8,7 @@
"OS",
"TileMap",
"TileSet",
"Tween",
"Viewport"
]
}

View File

@@ -225,6 +225,9 @@ func _ready():
assert_equal(new_tilemap.tile_set, new_tileset)
new_tilemap.queue_free()
# Creates a Tween and checks that it's valid. Improper refcount handling will crash now or at shutdown.
assert_equal(example.test_tween_smoke_test(), true)
# Test variant call.
var test_obj = TestClass.new()
assert_equal(example.test_variant_call(test_obj), "hello world")

View File

@@ -222,6 +222,7 @@ void Example::_bind_methods() {
ClassDB::bind_method(D_METHOD("test_add_child", "node"), &Example::test_add_child);
ClassDB::bind_method(D_METHOD("test_set_tileset", "tilemap", "tileset"), &Example::test_set_tileset);
ClassDB::bind_method(D_METHOD("test_tween_smoke_test"), &Example::test_tween_smoke_test);
ClassDB::bind_method(D_METHOD("test_variant_call", "variant"), &Example::test_variant_call);
@@ -305,7 +306,7 @@ void Example::_bind_methods() {
}
bool Example::has_object_instance_binding() const {
return internal::gdextension_interface_object_get_instance_binding(_owner, internal::token, nullptr);
return ::godot::gdextension_interface::object_get_instance_binding(_owner, ::godot::gdextension_interface::token, nullptr);
}
Example::Example() :
@@ -616,6 +617,11 @@ void Example::test_set_tileset(TileMap *p_tilemap, const Ref<TileSet> &p_tileset
p_tilemap->set_tileset(p_tileset);
}
bool Example::test_tween_smoke_test() {
Ref<Tween> tween = create_tween();
return tween.is_valid() && tween->is_class("Tween") && tween->get_reference_count() > 1;
}
Variant Example::test_variant_call(Variant p_variant) {
return p_variant.call("test", "hello");
}
@@ -742,7 +748,7 @@ String Example::test_use_engine_singleton() const {
String Example::test_library_path() {
String library_path;
internal::gdextension_interface_get_library_path(internal::library, library_path._native_ptr());
::godot::gdextension_interface::get_library_path(::godot::gdextension_interface::library, library_path._native_ptr());
return library_path;
}

View File

@@ -19,6 +19,7 @@
#include <godot_cpp/classes/input_event_key.hpp>
#include <godot_cpp/classes/tile_map.hpp>
#include <godot_cpp/classes/tile_set.hpp>
#include <godot_cpp/classes/tween.hpp>
#include <godot_cpp/classes/viewport.hpp>
#include <godot_cpp/variant/typed_dictionary.hpp>
#include <godot_cpp/variant/variant.hpp>
@@ -154,6 +155,7 @@ public:
void test_add_child(Node *p_node);
void test_set_tileset(TileMap *p_tilemap, const Ref<TileSet> &p_tileset) const;
bool test_tween_smoke_test();
Variant test_variant_call(Variant p_variant);

View File

@@ -2,6 +2,7 @@ import os
import platform
import sys
import header_builders
from SCons import __version__ as scons_raw_version
from SCons.Action import Action
from SCons.Builder import Builder
@@ -148,6 +149,11 @@ def scons_emit_files(target, source, env):
env.Depends(file, profile_filepath)
files.append(file)
env["godot_cpp_gen_dir"] = target[0].abspath
# gdextension_interface.h shouldn't depend on extension_api.json or the build_profile.json.
gdextension_interface_header = os.path.join(str(target[0]), "gen", "include", "gdextension_interface.h")
env.Ignore(gdextension_interface_header, [source[0], profile_filepath])
return files, source
@@ -161,6 +167,7 @@ def scons_generate_bindings(target, source, env):
_generate_bindings(
api,
str(source[0]),
str(source[1]),
env["generate_template_get_node"],
"32" if "32" in env["arch"] else "64",
env["precision"],
@@ -375,6 +382,7 @@ def options(opts, env):
)
)
opts.Add(BoolVariable("debug_symbols", "Build with debugging symbols", True))
opts.Add(BoolVariable("deprecated", "Enable compatibility code for deprecated and removed features", True))
opts.Add(BoolVariable("dev_build", "Developer build with dev-only debugging code (DEV_ENABLED)", False))
opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
@@ -445,17 +453,6 @@ def generate(env):
else: # Release
opt_level = "speed"
# Allow marking includes as external/system to avoid raising warnings.
if env.scons_version < (4, 2):
env["_CPPEXTINCFLAGS"] = "${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}"
else:
env["_CPPEXTINCFLAGS"] = (
"${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)}"
)
env["CPPEXTPATH"] = []
env["EXTINCPREFIX"] = "-isystem "
env["EXTINCSUFFIX"] = ""
env["optimize"] = ARGUMENTS.get("optimize", opt_level)
env["debug_symbols"] = get_cmdline_bool("debug_symbols", env.dev_build)
@@ -498,6 +495,9 @@ def generate(env):
if env["precision"] == "double":
env.Append(CPPDEFINES=["REAL_T_IS_DOUBLE"])
if not env["deprecated"]:
env.Append(CPPDEFINES=["DISABLE_DEPRECATED"])
# Allow detecting when building as a GDExtension.
env.Append(CPPDEFINES=["GDEXTENSION"])
@@ -529,6 +529,10 @@ def generate(env):
BUILDERS={
"GodotCPPBindings": Builder(action=Action(scons_generate_bindings, "$GENCOMSTR"), emitter=scons_emit_files),
"GodotCPPDocData": Builder(action=scons_generate_doc_source),
"GLSL_HEADER": Builder(
action=header_builders.build_raw_headers_action,
suffix="glsl.gen.h",
),
}
)
env.AddMethod(_godot_cpp, "GodotCPP")
@@ -544,8 +548,9 @@ def _godot_cpp(env):
env.Dir("."),
[
api_file,
os.path.join(extension_dir, "gdextension_interface.h"),
os.path.join(extension_dir, "gdextension_interface.json"),
"binding_generator.py",
"make_interface_header.py",
],
)
# Forces bindings regeneration.
@@ -565,7 +570,6 @@ def _godot_cpp(env):
# Includes
env.AppendUnique(
CPPPATH=[
env.Dir(extension_dir),
env.Dir("include").srcnode(),
env.Dir("gen/include"),
]

69
tools/header_builders.py Normal file
View File

@@ -0,0 +1,69 @@
import os.path
## See https://github.com/godotengine/godot/blob/master/glsl_builders.py
def build_raw_header(source_filename: str, constant_name: str) -> None:
# Read the source file content.
with open(source_filename, "r") as source_file:
source_content = source_file.read()
constant_name = constant_name.replace(".", "_")
# Build header content using a C raw string literal.
header_content = (
"/* THIS FILE IS GENERATED. EDITS WILL BE LOST. */\n\n"
"#pragma once\n\n"
f"inline constexpr const char *{constant_name}"
" = "
f'R"<!>({source_content})<!>"'
";\n"
)
# Write the header to the provided file name with a ".gen.h" suffix.
header_filename = f"{source_filename}.gen.h"
with open(header_filename, "w") as header_file:
header_file.write(header_content)
def build_raw_headers_action(target, source, env):
env.NoCache(target)
for src in source:
source_filename = str(src)
# To match Godot, replace ".glsl" with "_shader_glsl". Does nothing for non-GLSL files.
constant_name = os.path.basename(source_filename).replace(".glsl", "_shader_glsl")
build_raw_header(source_filename, constant_name)
def escape_svg(filename: str) -> str:
with open(filename, encoding="utf-8", newline="\n") as svg_file:
svg_content = svg_file.read()
return f'R"<!>({svg_content})<!>"'
## See https://github.com/godotengine/godot/blob/master/editor/icons/editor_icons_builders.py
## See https://github.com/godotengine/godot/blob/master/scene/theme/icons/default_theme_icons_builders.py
def make_svg_icons_action(target, source, env):
destination = str(target[0])
constant_prefix = os.path.basename(destination).replace(".gen.h", "")
svg_icons = [str(x) for x in source]
# Convert the SVG icons to escaped strings and convert their names to C strings.
icon_names = [f'"{os.path.basename(fname)[:-4]}"' for fname in svg_icons]
icon_sources = [escape_svg(fname) for fname in svg_icons]
# Join them as indented comma-separated items for use in an array initializer.
icon_names_str = ",\n\t".join(icon_names)
icon_sources_str = ",\n\t".join(icon_sources)
# Write the file to disk.
with open(destination, "w", encoding="utf-8", newline="\n") as destination_file:
destination_file.write(
f"""\
/* THIS FILE IS GENERATED. EDITS WILL BE LOST. */
#pragma once
inline constexpr int {constant_prefix}_count = {len(icon_names)};
inline constexpr const char *{constant_prefix}_sources[] = {{
{icon_sources_str}
}};
inline constexpr const char *{constant_prefix}_names[] = {{
{icon_names_str}
}};
"""
)

View File

@@ -5,7 +5,7 @@ from SCons.Variables import BoolVariable
def options(opts):
opts.Add(BoolVariable("use_llvm", "Use the LLVM compiler - only effective when targeting Linux", False))
opts.Add(BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True))
opts.Add(BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", False))
def exists(env):

View File

@@ -130,11 +130,6 @@ def generate(env):
if env["silence_msvc"] and not env.GetOption("clean"):
silence_msvc(env)
if not env["use_llvm"]:
env.AppendUnique(CCFLAGS=["/experimental:external", "/external:anglebrackets"])
env.AppendUnique(CCFLAGS=["/external:W0"])
env["EXTINCPREFIX"] = "/external:I"
elif (sys.platform == "win32" or sys.platform == "msys") and not env["mingw_prefix"]:
env["use_mingw"] = True
mingw.generate(env)