mirror of
https://github.com/godotengine/godot-cpp.git
synced 2026-01-01 05:48:37 +03:00
Compare commits
40 Commits
godot-4.5-
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b724219737 | ||
|
|
fe68c22c3e | ||
|
|
4ae2669dcd | ||
|
|
ee2a174746 | ||
|
|
8d1a1c847b | ||
|
|
8daf1ea657 | ||
|
|
7f75888cda | ||
|
|
2d7941d0dc | ||
|
|
f47a4d5400 | ||
|
|
788edc6bfe | ||
|
|
7d114d8d28 | ||
|
|
44a7d6befe | ||
|
|
d033e8abea | ||
|
|
fde93df450 | ||
|
|
618ee44a23 | ||
|
|
6c05f1f0b1 | ||
|
|
b14df6e18f | ||
|
|
647c7d811f | ||
|
|
fd0a8a5d0e | ||
|
|
bde278b2c7 | ||
|
|
42b03da2b1 | ||
|
|
a9773579cb | ||
|
|
8c5e038744 | ||
|
|
76d1ce6848 | ||
|
|
fc70347ef7 | ||
|
|
5910c0e8a2 | ||
|
|
c7873e1355 | ||
|
|
2fd41b7e16 | ||
|
|
28e8b1a04b | ||
|
|
4218f9370d | ||
|
|
3eb3069e09 | ||
|
|
48d02db27c | ||
|
|
12db0684b2 | ||
|
|
ef63d2e657 | ||
|
|
0974e9724b | ||
|
|
0b8e76817b | ||
|
|
17d13e3edb | ||
|
|
c58dfa4d99 | ||
|
|
51008e1556 | ||
|
|
479d206c50 |
2
.github/actions/setup-godot-cpp/action.yml
vendored
2
.github/actions/setup-godot-cpp/action.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/ci-cmake.yml
vendored
2
.github/workflows/ci-cmake.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/ci-scons.yml
vendored
2
.github/workflows/ci-scons.yml
vendored
@@ -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
|
||||
|
||||
@@ -4,7 +4,7 @@ default_language_version:
|
||||
exclude: |
|
||||
(?x)^(
|
||||
gdextension/extension_api\.json|
|
||||
gdextension/gdextension_interface\.h
|
||||
gdextension/gdextension_interface\.json
|
||||
)$
|
||||
|
||||
repos:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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::"):
|
||||
|
||||
@@ -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}',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ]===========================]
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
353
doc/cmake.rst
353
doc/cmake.rst
@@ -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
|
||||
@@ -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
9451
gdextension/gdextension_interface.json
Normal file
9451
gdextension/gdextension_interface.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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))));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
41
include/godot_cpp/core/load_proc_address.inc
Normal file
41
include/godot_cpp/core/load_proc_address.inc
Normal 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; \
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
734
include/godot_cpp/templates/a_hash_map.hpp
Normal file
734
include/godot_cpp/templates/a_hash_map.hpp
Normal 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
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
364
make_interface_header.py
Normal 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")
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()?");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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]);
|
||||
|
||||
380
src/godot.cpp
380
src/godot.cpp
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) :
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"OS",
|
||||
"TileMap",
|
||||
"TileSet",
|
||||
"Tween",
|
||||
"Viewport"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
69
tools/header_builders.py
Normal 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}
|
||||
}};
|
||||
"""
|
||||
)
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user