Compare commits

...

32 Commits

Author SHA1 Message Date
ae0d1aa153 Added compilation_db tool for improved code navigation using clangd. 2023-06-12 12:03:53 +02:00
Rémi Verschelde
d12cf071bb
Merge pull request #1128 from Mathis-Z/master
Fixing #1127 by making return types of auto-generated functions dynamic
2023-06-08 22:31:51 +02:00
Mathis-Z
ac98dd2752 Fixing #1127 by making return types of auto-generated functions dynamic 2023-06-08 20:35:29 +02:00
David Snopek
ee5cf3a11d
Merge pull request #1137 from dsnopek/no-more-legacy-mode
Clarify error message because there isn't a legacy Godot 4.0 mode anymore
2023-06-08 10:11:29 -05:00
David Snopek
3074d22815 Clarify error message because there isn't a legacy Godot 4.0 mode anymore 2023-06-08 09:42:03 -05:00
Rémi Verschelde
92a139d31e
Merge pull request #1129 from dsnopek/interface-print-error
Correctly load gdextension_interface_print_error
2023-06-08 16:01:40 +02:00
Rémi Verschelde
b5a3aeb8ee
Merge pull request #1123 from dsnopek/revert-pr-1044-1045
Revert the changes from PR #1044 and #1045 and standardize on `Object **` encoding in ptrcall
2023-06-07 17:30:44 +02:00
David Snopek
ad726015e7 Revert the changes from PR #1044 and #1045 and standardize on Object ** encoding in ptrcall 2023-06-07 08:30:33 -05:00
Rémi Verschelde
c669f0b78a
gdextension: Sync with upstream commit 828ec2c5d005b6499c7c4c88beaf81767d05614b (4.1-beta1) 2023-06-07 13:23:12 +02:00
David Snopek
59bffc94a8 Correctly load gdextension_interface_print_error 2023-05-31 01:32:44 -05:00
David Snopek
aef9ea7387
Merge pull request #1113 from Calinou/add-issue-template
Add issue template based on the main Godot repository
2023-05-26 17:00:25 -05:00
David Snopek
0c466ddb67
Merge pull request #1117 from dsnopek/sync-gdextension-interface
Synchronize gdextension_interface.h with Godot
2023-05-26 17:00:13 -05:00
David Snopek
6347ce2550 Synchronize gdextension_interface.h with Godot 2023-05-26 15:43:50 -05:00
Rémi Verschelde
2078c00bab
Merge pull request #1114 from dsnopek/editor-plugins
Add support for adding/removing editor plugins
2023-05-26 11:04:35 +02:00
Hugo Locurcio
e7c57a39db
Add issue template based on the main Godot repository 2023-05-25 15:59:33 +02:00
David Snopek
2e45bd8373
Merge pull request #1101 from dsnopek/better-tests
Add automated tests that run a GDExtension (rather than just building it)
2023-05-24 21:18:12 -05:00
David Snopek
0d0d5a670b
Merge pull request #1116 from saki7/Ref-allow-non-const-access
Change Ref<T> to allow non const access to ptr
2023-05-24 21:17:25 -05:00
David Snopek
8052f818b4
Merge pull request #1050 from dsnopek/object-correct-class
Ensure GDExtension class is the correct type for the Godot engine class
2023-05-24 21:17:12 -05:00
David Snopek
08bc2ef680
Merge pull request #1115 from dgcole/master
Update Getting Started section of README.md
2023-05-24 21:16:28 -05:00
dgcole
6f0649a86d Update getting started section of README.md 2023-05-24 21:49:55 -04:00
David Snopek
1fd3f82d3a Add automated tests that run a GDExtension (rather than just building it) 2023-05-17 14:08:12 -05:00
Nana Sakisaka
48635729b9 Change Ref<T> to allow non const access to ptr 2023-05-17 19:24:09 +09:00
David Snopek
e75ebffb70 Add support for adding/removing editor plugins 2023-05-16 22:02:35 -05:00
David Snopek
431e30bc32 Ensure GDExtension class is the correct type for the Godot engine class 2023-05-16 15:18:48 -05:00
Rémi Verschelde
1c18413de0
Merge pull request #1095 from dsnopek/gdextension-interface
Update to load function pointers for GDExtension interface
2023-05-16 17:26:31 +02:00
Hugo Locurcio
813827c26a
Merge pull request #1108 from sasichkamega/master 2023-05-12 19:58:34 +02:00
David Snopek
a5c6ca5920 Update to load function pointers for GDExtension interface 2023-05-09 21:45:48 -05:00
Alex
7f94f90b01 Update CMakeLists.txt 2023-05-06 09:55:41 +03:00
Rémi Verschelde
feaba551b5
Merge pull request #1045 from zhehangd/fix_ref_crash
Fix crash using Ref<T> as parameter
2023-04-04 11:30:08 +02:00
Rémi Verschelde
e9942db502
Merge pull request #1044 from zhehangd/fix_obj_ptr_crash
Fix crash using Object* as parameter
2023-04-01 11:36:17 +02:00
Zhehang Ding
093f0673f5 Fix PtrToArg<Object*> crash 2023-03-30 19:38:12 -07:00
Zhehang Ding
517db6686a Fix PtrToArg<Ref<T>> crash 2023-02-15 22:36:29 -08:00
45 changed files with 9707 additions and 1183 deletions

71
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,71 @@
name: Bug report
description: Report a bug in the godot-cpp GDExtension/GDNative integration
body:
- type: markdown
attributes:
value: |
- When reporting bugs, you'll make our life simpler (and the fix will come sooner) if you follow the guidelines in this template.
- Write a descriptive issue title above.
- The golden rule is to **always open *one* issue for *one* bug**. If you notice several bugs and want to report them, make sure to create one new issue for each of them.
- Search [open](https://github.com/godotengine/godot-cpp/issues) and [closed](https://github.com/godotengine/godot-cpp/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported. If you don't find a relevant match or if you're unsure, don't hesitate to **open a new issue**. The bugsquad will handle it from there if it's a duplicate.
- Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/stable/about/release_policy.html).
- type: input
attributes:
label: Godot version
description: >
Specify the Git commit hash if using a development or non-official build.
If you use a custom build, please test if your issue is reproducible in official builds too.
placeholder: 3.3.stable, 4.0.dev (3041becc6)
validations:
required: true
- type: input
attributes:
label: godot-cpp version
description: >
Specify the Git commit hash if using a development build.
placeholder: 3.3.stable, 4.0.dev (3041becc6)
validations:
required: true
- type: input
attributes:
label: System information
description: |
- Specify the OS version, and when relevant hardware information.
- For issues that are likely OS-specific and/or graphics-related, please specify the CPU model and architecture.
- **Bug reports not including the required information may be closed at the maintainers' discretion.** If in doubt, always include all the requested information; it's better to include too much information than not enough information.
placeholder: Windows 10, Intel Core i5-7200U
validations:
required: true
- type: textarea
attributes:
label: Issue description
description: |
Describe your issue briefly. What doesn't work, and how do you expect it to work instead?
You can include images or videos with drag and drop, and format code blocks or logs with <code>```</code> tags.
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: |
List of steps or sample code that reproduces the issue. Having reproducible issues is a prerequisite for contributors to be able to solve them.
If you include a minimal reproduction project below, you can detail how to use it here.
validations:
required: true
- type: textarea
attributes:
label: Minimal reproduction project
description: |
- A small Godot project which reproduces the issue, with no unnecessary files included. Be sure to not include the `.godot` folder in the archive (but keep `project.godot`).
- Required, unless the reproduction steps are trivial and don't require any project files to be followed. In this case, write "N/A" in the field.
- Drag and drop a ZIP archive to upload it. **Do not select another field until the project is done uploading.**
- **If you've been asked by a maintainer to upload a minimal reproduction project, you *must* do so within 7 days.** Otherwise, your bug report will be closed as it'll be considered too difficult to diagnose.
validations:
required: true

14
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,14 @@
blank_issues_enabled: false
contact_links:
- name: Godot proposals
url: https://github.com/godotengine/godot-proposals
about: Please submit feature proposals on the Godot proposals repository, not here.
- name: Godot documentation repository
url: https://github.com/godotengine/godot-docs
about: Please report issues with documentation on the Godot documentation repository, not here.
- name: Godot community channels
url: https://godotengine.org/community
about: Please ask for technical support on one of the other community channels, not here.

View File

@ -22,6 +22,7 @@ jobs:
platform: linux
artifact-name: godot-cpp-linux-glibc2.27-x86_64-release
artifact-path: bin/libgodot-cpp.linux.template_release.x86_64.a
run-tests: true
cache-name: linux-x86_64
- name: 🐧 Linux (GCC, Double Precision)
@ -30,6 +31,7 @@ jobs:
artifact-name: godot-cpp-linux-glibc2.27-x86_64-double-release
artifact-path: bin/libgodot-cpp.linux.template_release.double.x86_64.a
flags: precision=double
run-tests: false
cache-name: linux-x86_64-f64
- name: 🏁 Windows (x86_64, MSVC)
@ -37,6 +39,7 @@ jobs:
platform: windows
artifact-name: godot-cpp-windows-msvc2019-x86_64-release
artifact-path: bin/libgodot-cpp.windows.template_release.x86_64.lib
run-tests: false
cache-name: windows-x86_64-msvc
- name: 🏁 Windows (x86_64, MinGW)
@ -45,6 +48,7 @@ jobs:
artifact-name: godot-cpp-linux-mingw-x86_64-release
artifact-path: bin/libgodot-cpp.windows.template_release.x86_64.a
flags: use_mingw=yes
run-tests: false
cache-name: windows-x86_64-mingw
- name: 🍎 macOS (universal)
@ -53,6 +57,7 @@ jobs:
artifact-name: godot-cpp-macos-universal-release
artifact-path: bin/libgodot-cpp.macos.template_release.universal.a
flags: arch=universal
run-tests: false
cache-name: macos-universal
- name: 🤖 Android (arm64)
@ -61,6 +66,7 @@ jobs:
artifact-name: godot-cpp-android-arm64-release
artifact-path: bin/libgodot-cpp.android.template_release.arm64.a
flags: ANDROID_NDK_ROOT=$ANDROID_NDK_LATEST_HOME arch=arm64
run-tests: false
cache-name: android-arm64
- name: 🍏 iOS (arm64)
@ -69,6 +75,7 @@ jobs:
artifact-name: godot-cpp-ios-arm64-release
artifact-path: bin/libgodot-cpp.ios.template_release.arm64.a
flags: arch=arm64
run-tests: false
cache-name: ios-arm64
env:
@ -124,6 +131,31 @@ jobs:
cd test
scons platform=${{ matrix.platform }} target=template_release ${{ matrix.flags }}
- name: Download latest Godot artifacts
uses: dsnopek/action-download-artifact@1322f74e2dac9feed2ee76a32d9ae1ca3b4cf4e9
if: ${{ matrix.run-tests }}
with:
repo: godotengine/godot
branch: master
event: push
workflow: linux_builds.yml
workflow_conclusion: success
name: linux-editor-mono
search_artifacts: true
check_artifacts: true
ensure_latest: true
path: godot-artifacts
- name: Run tests
if: ${{ matrix.run-tests }}
run: |
chmod +x ./godot-artifacts/godot.linuxbsd.editor.x86_64.mono
./godot-artifacts/godot.linuxbsd.editor.x86_64.mono --headless --version
cd test
# Need to run the editor so .godot is generated... but it crashes! Ignore that :-)
(cd project && (../../godot-artifacts/godot.linuxbsd.editor.x86_64.mono --editor --headless --quit >/dev/null 2>&1 || true))
GODOT=../godot-artifacts/godot.linuxbsd.editor.x86_64.mono ./run-tests.sh
- name: Upload artifact
uses: actions/upload-artifact@v3
with:

View File

@ -37,8 +37,8 @@
# Todo
# Test build for Windows, Mac and mingw.
project(godot-cpp LANGUAGES CXX)
cmake_minimum_required(VERSION 3.12)
project(godot-cpp LANGUAGES CXX)
option(GENERATE_TEMPLATE_GET_NODE "Generate a template version of the Node class's get_node." ON)
option(GODOT_CPP_SYSTEM_HEADERS "Expose headers as SYSTEM." ON)

View File

@ -2,8 +2,11 @@
> **Warning**
>
> This repository's `master` branch is only usable with Godot's ([GDExtension](https://godotengine.org/article/introducing-gd-extensions))
> API (Godot 4.0 and later).
> This repository's `master` branch is only usable with the latest version of
> Godot's ([GDExtension](https://godotengine.org/article/introducing-gd-extensions))
> API (Godot 4.1 and later).
>
> For users of Godot 4.0.x, switch to the [`4.0`](https://github.com/godotengine/godot-cpp/tree/4.0) branch.
>
> For GDNative users (Godot 3.x), switch to the [`3.x`](https://github.com/godotengine/godot-cpp/tree/3.x)
> or the [`3.5`](https://github.com/godotengine/godot-cpp/tree/3.5) branch.
@ -79,6 +82,7 @@ Follow [the example](test/demo/example.gdextension):
[configuration]
entry_symbol = "example_library_init"
compatibility_minimum = 4.1
[libraries]
@ -99,8 +103,8 @@ extern "C" {
// Initialization.
GDExtensionBool GDE_EXPORT example_library_init(const GDExtensionInterface *p_interface, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
godot::GDExtensionBinding::InitObject init_obj(p_interface, p_library, r_initialization);
GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
init_obj.register_initializer(initialize_example_module);
init_obj.register_terminator(uninitialize_example_module);

View File

@ -53,7 +53,7 @@ else:
# Default tools with no platform defaults to gnu toolchain.
# We apply platform specific toolchains via our custom tools.
env = Environment(tools=["default"], PLATFORM="")
env = Environment(tools=["default", "compilation_db"], PLATFORM="") # <MEWIN> Added compilation_db tool for improved code navigation using clangd.
# Default num_jobs to local cpu count if not user specified.
# SCons has a peculiarity where user-specified options won't be overridden

View File

@ -128,6 +128,8 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
if sources:
utility_functions_source_path = source_gen_folder / "variant" / "utility_functions.cpp"
files.append(str(utility_functions_source_path.as_posix()))
register_engine_classes_source_path = source_gen_folder / "register_engine_classes.cpp"
files.append(str(register_engine_classes_source_path.as_posix()))
return files
@ -772,12 +774,12 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
if "constructors" in builtin_api:
for constructor in builtin_api["constructors"]:
result.append(
f'\t_method_bindings.constructor_{constructor["index"]} = internal::gde_interface->variant_get_ptr_constructor({enum_type_name}, {constructor["index"]});'
f'\t_method_bindings.constructor_{constructor["index"]} = internal::gdextension_interface_variant_get_ptr_constructor({enum_type_name}, {constructor["index"]});'
)
if builtin_api["has_destructor"]:
result.append(
f"\t_method_bindings.destructor = internal::gde_interface->variant_get_ptr_destructor({enum_type_name});"
f"\t_method_bindings.destructor = internal::gdextension_interface_variant_get_ptr_destructor({enum_type_name});"
)
result.append("}")
@ -796,36 +798,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__name = StringName("{method["name"]}");')
result.append(
f'\t_method_bindings.method_{method["name"]} = internal::gde_interface->variant_get_ptr_builtin_method({enum_type_name}, __name._native_ptr(), {method["hash"]});'
f'\t_method_bindings.method_{method["name"]} = internal::gdextension_interface_variant_get_ptr_builtin_method({enum_type_name}, __name._native_ptr(), {method["hash"]});'
)
if "members" in builtin_api:
for member in builtin_api["members"]:
result.append(f'\t__name = StringName("{member["name"]}");')
result.append(
f'\t_method_bindings.member_{member["name"]}_setter = internal::gde_interface->variant_get_ptr_setter({enum_type_name}, __name._native_ptr());'
f'\t_method_bindings.member_{member["name"]}_setter = internal::gdextension_interface_variant_get_ptr_setter({enum_type_name}, __name._native_ptr());'
)
result.append(
f'\t_method_bindings.member_{member["name"]}_getter = internal::gde_interface->variant_get_ptr_getter({enum_type_name}, __name._native_ptr());'
f'\t_method_bindings.member_{member["name"]}_getter = internal::gdextension_interface_variant_get_ptr_getter({enum_type_name}, __name._native_ptr());'
)
if "indexing_return_type" in builtin_api:
result.append(
f"\t_method_bindings.indexed_setter = internal::gde_interface->variant_get_ptr_indexed_setter({enum_type_name});"
f"\t_method_bindings.indexed_setter = internal::gdextension_interface_variant_get_ptr_indexed_setter({enum_type_name});"
)
result.append(
f"\t_method_bindings.indexed_getter = internal::gde_interface->variant_get_ptr_indexed_getter({enum_type_name});"
f"\t_method_bindings.indexed_getter = internal::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::gde_interface->variant_get_ptr_keyed_setter({enum_type_name});"
f"\t_method_bindings.keyed_setter = internal::gdextension_interface_variant_get_ptr_keyed_setter({enum_type_name});"
)
result.append(
f"\t_method_bindings.keyed_getter = internal::gde_interface->variant_get_ptr_keyed_getter({enum_type_name});"
f"\t_method_bindings.keyed_getter = internal::gdextension_interface_variant_get_ptr_keyed_getter({enum_type_name});"
)
result.append(
f"\t_method_bindings.keyed_checker = internal::gde_interface->variant_get_ptr_keyed_checker({enum_type_name});"
f"\t_method_bindings.keyed_checker = internal::gdextension_interface_variant_get_ptr_keyed_checker({enum_type_name});"
)
if "operators" in builtin_api:
@ -838,11 +840,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::gde_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"]} = 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});'
)
else:
result.append(
f'\t_method_bindings.operator_{get_operator_id_name(operator["name"])} = internal::gde_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"])} = 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);'
)
result.append("}")
@ -1157,6 +1159,10 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
generate_engine_class_source(class_api, used_classes, fully_used_classes, use_template_get_node)
)
register_engine_classes_filename = Path(output_dir) / "src" / "register_engine_classes.cpp"
with register_engine_classes_filename.open("w+") as source_file:
source_file.write(generate_register_engine_classes_source(api))
for native_struct in api["native_structures"]:
struct_name = native_struct["name"]
snake_struct_name = camel_to_snake(struct_name)
@ -1376,6 +1382,24 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
result.append("};")
result.append("")
if class_name == "EditorPlugin":
result.append("class EditorPlugins {")
result.append("public:")
result.append("")
result.append("\ttemplate <class T>")
result.append("\tstatic void add_by_type() {")
result.append("\t\tinternal::gdextension_interface_editor_add_plugin(T::get_class_static()._native_ptr());")
result.append("\t}")
result.append("\ttemplate <class T>")
result.append("\tstatic void remove_by_type() {")
result.append("\t\tinternal::gdextension_interface_editor_remove_plugin(T::get_class_static()._native_ptr());")
result.append("\t}")
result.append("};")
result.append("")
result.append("} // namespace godot")
result.append("")
@ -1421,13 +1445,13 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result.append(f"{class_name} *{class_name}::get_singleton() {{")
result.append(f"\tconst StringName __class_name = {class_name}::get_class_static();")
result.append(
"\tstatic GDExtensionObjectPtr singleton_obj = internal::gde_interface->global_get_singleton(__class_name._native_ptr());"
"\tstatic GDExtensionObjectPtr singleton_obj = internal::gdextension_interface_global_get_singleton(__class_name._native_ptr());"
)
result.append("#ifdef DEBUG_ENABLED")
result.append("\tERR_FAIL_COND_V(singleton_obj == nullptr, nullptr);")
result.append("#endif // DEBUG_ENABLED")
result.append(
f"\tstatic {class_name} *singleton = reinterpret_cast<{class_name} *>(internal::gde_interface->object_get_instance_binding(singleton_obj, internal::token, &{class_name}::___binding_callbacks));"
f"\tstatic {class_name} *singleton = reinterpret_cast<{class_name} *>(internal::gdextension_interface_object_get_instance_binding(singleton_obj, internal::token, &{class_name}::___binding_callbacks));"
)
result.append("\treturn singleton;")
result.append("}")
@ -1449,7 +1473,7 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result.append(f"\tconst StringName __class_name = {class_name}::get_class_static();")
result.append(f'\tconst StringName __method_name = "{method["name"]}";')
result.append(
f'\tstatic GDExtensionMethodBindPtr ___method_bind = internal::gde_interface->classdb_get_method_bind(__class_name._native_ptr(), __method_name._native_ptr(), {method["hash"]});'
f'\tstatic GDExtensionMethodBindPtr ___method_bind = internal::gdextension_interface_classdb_get_method_bind(__class_name._native_ptr(), __method_name._native_ptr(), {method["hash"]});'
)
method_call = "\t"
has_return = "return_value" in method and method["return_value"]["type"] != "void"
@ -1512,7 +1536,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::gde_interface->object_method_bind_call(___method_bind, _owner, reinterpret_cast<GDExtensionConstVariantPtr *>(args), arg_count, &ret, &error"
method_call += "internal::gdextension_interface_object_method_bind_call(___method_bind, _owner, reinterpret_cast<GDExtensionConstVariantPtr *>(args), arg_count, &ret, &error"
if is_ref:
method_call += ")" # Close Ref<> constructor.
@ -1551,6 +1575,38 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
return "\n".join(result)
def generate_register_engine_classes_source(api):
includes = []
registrations = []
for class_api in api["classes"]:
if class_api["name"] == "ClassDB":
continue
class_name = class_api["name"]
snake_class_name = camel_to_snake(class_name)
includes.append(f"#include <godot_cpp/classes/{snake_class_name}.hpp>")
registrations.append(f"\tClassDB::register_engine_class<{class_name}>();")
result = []
add_header(f"register_engine_classes.cpp", result)
result.append("#include <godot_cpp/godot.hpp>")
result.append("")
result = result + includes
result.append("")
result.append("namespace godot {")
result.append("")
result.append("void GDExtensionBinding::register_engine_classes() {")
result = result + registrations
result.append("}")
result.append("")
result.append("} // namespace godot ")
return "\n".join(result)
def generate_global_constants(api, output_dir):
include_gen_folder = Path(output_dir) / "include" / "godot_cpp" / "classes"
source_gen_folder = Path(output_dir) / "src" / "classes"
@ -1709,7 +1765,7 @@ def generate_utility_functions(api, output_dir):
source.append(f'\tconst StringName __function_name = "{function["name"]}";')
source.append(
f'\tstatic GDExtensionPtrUtilityFunction ___function = internal::gde_interface->variant_get_ptr_utility_function(__function_name._native_ptr(), {function["hash"]});'
f'\tstatic GDExtensionPtrUtilityFunction ___function = internal::gdextension_interface_variant_get_ptr_utility_function(__function_name._native_ptr(), {function["hash"]});'
)
has_return = "return_type" in function and function["return_type"] != "void"
if has_return:
@ -1742,6 +1798,9 @@ def generate_utility_functions(api, output_dir):
source += encode
arguments.append(arg_name)
function_call += ", ".join(arguments)
else:
if has_return:
source.append(f'\t{get_gdextension_type(correct_type(function["return_type"]))} ret;')
else:
source.append("\tVariant ret;")
function_call += "___function(&ret, reinterpret_cast<GDExtensionConstVariantPtr *>(args), arg_count"
@ -1831,7 +1890,7 @@ def get_encoded_arg(arg_name, type_name, type_meta):
elif is_engine_class(type_name):
# `{name}` is a C++ wrapper, it contains a field which is the object's pointer Godot expects.
# We have to check `nullptr` because when the caller sends `nullptr`, the wrapper itself will be null.
name = f"({name} != nullptr ? {name}->_owner : nullptr)"
name = f"({name} != nullptr ? &{name}->_owner : nullptr)"
else:
name = f"&{name}"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -88,26 +88,15 @@ public:
return reference != p_r.reference;
}
_FORCE_INLINE_ T *operator->() {
_FORCE_INLINE_ T *operator*() const {
return reference;
}
_FORCE_INLINE_ T *operator*() {
_FORCE_INLINE_ T *operator->() const {
return reference;
}
_FORCE_INLINE_ const T *operator->() const {
return reference;
}
_FORCE_INLINE_ const T *ptr() const {
return reference;
}
_FORCE_INLINE_ T *ptr() {
return reference;
}
_FORCE_INLINE_ const T *operator*() const {
_FORCE_INLINE_ T *ptr() const {
return reference;
}
@ -241,10 +230,8 @@ template <class T>
struct PtrToArg<Ref<T>> {
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
GDExtensionRefPtr ref = (GDExtensionRefPtr)p_ptr;
ERR_FAIL_NULL_V(ref, Ref<T>());
T *obj = reinterpret_cast<T *>(godot::internal::gde_interface->object_get_instance_binding(godot::internal::gde_interface->ref_get_object(ref), godot::internal::token, &T::___binding_callbacks));
return Ref<T>(obj);
ERR_FAIL_NULL_V(p_ptr, Ref<T>());
return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref))));
}
typedef Ref<T> EncodeT;
@ -256,7 +243,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::gde_interface->ref_set_object(ref, p_val->_owner);
godot::internal::gdextension_interface_ref_set_object(ref, p_val->_owner);
}
}
};
@ -266,7 +253,9 @@ struct PtrToArg<const Ref<T> &> {
typedef Ref<T> EncodeT;
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
return Ref<T>(reinterpret_cast<T *>(godot::internal::gde_interface->object_get_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)), godot::internal::token, &T::___binding_callbacks)));
GDExtensionRefPtr ref = const_cast<GDExtensionRefPtr>(p_ptr);
ERR_FAIL_NULL_V(p_ptr, Ref<T>());
return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref))));
}
};

View File

@ -148,7 +148,7 @@ template <class 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::gde_interface->variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
if (!internal::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 +163,7 @@ template <class 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::gde_interface->variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
if (!internal::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 +178,7 @@ template <class 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::gde_interface->variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
if (!internal::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;

View File

@ -104,6 +104,7 @@ 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 MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const void **p_defs, int p_defcount);
static void initialize_class(const ClassInfo &cl);
@ -117,6 +118,8 @@ public:
static void register_class(bool p_virtual = false);
template <class T>
static void register_abstract_class();
template <class T>
static void register_engine_class();
template <class N, class M, typename... VarArgs>
static MethodBind *bind_method(N p_method_name, M p_method, VarArgs... p_args);
@ -137,6 +140,7 @@ public:
static MethodBind *get_method(const StringName &p_class, const StringName &p_method);
static GDExtensionClassCallVirtual get_virtual_func(void *p_userdata, GDExtensionConstStringNamePtr p_name);
static const GDExtensionInstanceBindingCallbacks *get_instance_binding_callbacks(const StringName &p_class);
static void initialize(GDExtensionInitializationLevel p_level);
static void deinitialize(GDExtensionInitializationLevel p_level);
@ -161,6 +165,8 @@ public:
template <class T, bool is_abstract>
void ClassDB::_register_class(bool p_virtual) {
instance_binding_callbacks[T::get_class_static()] = &T::___binding_callbacks;
// Register this class within our plugin
ClassInfo cl;
cl.name = T::get_class_static();
@ -194,7 +200,7 @@ void ClassDB::_register_class(bool p_virtual) {
(void *)&T::get_class_static(), // void *class_userdata;
};
internal::gde_interface->classdb_register_extension_class(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
internal::gdextension_interface_classdb_register_extension_class(internal::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();
@ -213,6 +219,11 @@ void ClassDB::register_abstract_class() {
ClassDB::_register_class<T, true>();
}
template <class T>
void ClassDB::register_engine_class() {
instance_binding_callbacks[T::get_class_static()] = &T::___binding_callbacks;
}
template <class N, class M, typename... VarArgs>
MethodBind *ClassDB::bind_method(N p_method_name, M p_method, VarArgs... p_args) {
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.

View File

@ -47,25 +47,25 @@ template <class O, class... 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::gde_interface->object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
internal::gdextension_interface_object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
if (ret == nullptr) {
return nullptr;
}
return reinterpret_cast<O *>(internal::gde_interface->object_get_instance_binding(ret, internal::token, &O::___binding_callbacks));
return reinterpret_cast<O *>(internal::get_object_instance_binding(ret));
}
template <class R, class... Args>
R _call_native_mb_ret(const GDExtensionMethodBindPtr mb, void *instance, const Args &...args) {
R ret;
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
internal::gde_interface->object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
internal::gdextension_interface_object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
return ret;
}
template <class... 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::gde_interface->object_method_bind_ptrcall(mb, instance, mb_args.data(), nullptr);
internal::gdextension_interface_object_method_bind_ptrcall(mb, instance, mb_args.data(), nullptr);
}
template <class R, class... Args>
@ -81,7 +81,7 @@ Object *_call_utility_ret_obj(const GDExtensionPtrUtilityFunction func, void *in
GodotObject *ret = nullptr;
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
func(&ret, mb_args.data(), mb_args.size());
return (Object *)internal::gde_interface->object_get_instance_binding(ret, internal::token, &Object::___binding_callbacks);
return (Object *)internal::get_object_instance_binding(ret);
}
template <class... Args>

View File

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

View File

@ -33,6 +33,7 @@
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/core/object.hpp>
#include <godot_cpp/godot.hpp>
#include <godot_cpp/variant/variant.hpp>
@ -168,7 +169,7 @@ MAKE_PTRARG_BY_REFERENCE(Variant);
template <class T>
struct PtrToArg<T *> {
_FORCE_INLINE_ static T *convert(const void *p_ptr) {
return reinterpret_cast<T *>(godot::internal::gde_interface->object_get_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)), godot::internal::token, &T::___binding_callbacks));
return reinterpret_cast<T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr))));
}
typedef Object *EncodeT;
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
@ -179,7 +180,7 @@ struct PtrToArg<T *> {
template <class T>
struct PtrToArg<const T *> {
_FORCE_INLINE_ static const T *convert(const void *p_ptr) {
return reinterpret_cast<const T *>(godot::internal::gde_interface->object_get_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)), godot::internal::token, &T::___binding_callbacks));
return reinterpret_cast<const T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr))));
}
typedef const Object *EncodeT;
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {

View File

@ -52,6 +52,12 @@
namespace godot {
namespace internal {
Object *get_object_instance_binding(GodotObject *);
} // namespace internal
struct MethodInfo {
StringName name;
PropertyInfo return_val;
@ -124,11 +130,11 @@ public:
class ObjectDB {
public:
static Object *get_instance(uint64_t p_object_id) {
GDExtensionObjectPtr obj = internal::gde_interface->object_get_instance_from_id(p_object_id);
GDExtensionObjectPtr obj = internal::gdextension_interface_object_get_instance_from_id(p_object_id);
if (obj == nullptr) {
return nullptr;
}
return reinterpret_cast<Object *>(internal::gde_interface->object_get_instance_binding(obj, internal::token, &Object::___binding_callbacks));
return internal::get_object_instance_binding(obj);
}
};
@ -138,11 +144,11 @@ T *Object::cast_to(Object *p_object) {
return nullptr;
}
StringName class_name = T::get_class_static();
GDExtensionObjectPtr casted = internal::gde_interface->object_cast_to(p_object->_owner, internal::gde_interface->classdb_get_class_tag(class_name._native_ptr()));
GDExtensionObjectPtr casted = internal::gdextension_interface_object_cast_to(p_object->_owner, internal::gdextension_interface_classdb_get_class_tag(class_name._native_ptr()));
if (casted == nullptr) {
return nullptr;
}
return reinterpret_cast<T *>(internal::gde_interface->object_get_instance_binding(casted, internal::token, &T::___binding_callbacks));
return dynamic_cast<T *>(internal::get_object_instance_binding(casted));
}
template <class T>
@ -151,11 +157,11 @@ const T *Object::cast_to(const Object *p_object) {
return nullptr;
}
StringName class_name = T::get_class_static();
GDExtensionObjectPtr casted = internal::gde_interface->object_cast_to(p_object->_owner, internal::gde_interface->classdb_get_class_tag(class_name._native_ptr()));
GDExtensionObjectPtr casted = internal::gdextension_interface_object_cast_to(p_object->_owner, internal::gdextension_interface_classdb_get_class_tag(class_name._native_ptr()));
if (casted == nullptr) {
return nullptr;
}
return reinterpret_cast<const T *>(internal::gde_interface->object_get_instance_binding(casted, internal::token, &T::___binding_callbacks));
return dynamic_cast<const T *>(internal::get_object_instance_binding(casted));
}
} // namespace godot

View File

@ -37,10 +37,150 @@ namespace godot {
namespace internal {
extern "C" const GDExtensionInterface *gde_interface;
extern "C" GDExtensionInterfaceGetProcAddress gdextension_interface_get_proc_address;
extern "C" GDExtensionClassLibraryPtr library;
extern "C" void *token;
extern "C" GDExtensionGodotVersion godot_version;
// All of the GDExtension interface functions.
extern "C" GDExtensionInterfaceGetGodotVersion gdextension_interface_get_godot_version;
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" 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" 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" GDExtensionInterfaceStringNewWithUtf16CharsAndLen gdextension_interface_string_new_with_utf16_chars_and_len;
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" 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" GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index;
extern "C" GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const;
extern "C" GDExtensionInterfaceArrayRef gdextension_interface_array_ref;
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" 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" 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" GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object;
extern "C" GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object;
extern "C" GDExtensionInterfaceScriptInstanceCreate gdextension_interface_script_instance_create;
extern "C" GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_construct_object;
extern "C" GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind;
extern "C" GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass gdextension_interface_classdb_register_extension_class;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant;
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property;
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;
} // namespace internal
enum ModuleInitializationLevel {
@ -51,28 +191,28 @@ enum ModuleInitializationLevel {
};
class GDExtensionBinding {
private:
static void register_engine_classes();
public:
using Callback = void (*)(ModuleInitializationLevel p_level);
static Callback init_callback;
static Callback terminate_callback;
static GDExtensionInitializationLevel minimum_initialization_level;
static GDExtensionBool init(const GDExtensionInterface *p_interface, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization);
static GDExtensionBool init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization);
public:
static void initialize_level(void *userdata, GDExtensionInitializationLevel p_level);
static void deinitialize_level(void *userdata, GDExtensionInitializationLevel p_level);
class InitObject {
const GDExtensionInterface *gde_interface;
GDExtensionInterfaceGetProcAddress get_proc_address;
GDExtensionClassLibraryPtr library;
GDExtensionInitialization *initialization;
public:
InitObject(const GDExtensionInterface *p_interface, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) :
gde_interface(p_interface),
library(p_library),
initialization(r_initialization) {}
InitObject(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization);
void register_initializer(Callback p_init) const;
void register_terminator(Callback p_init) const;

View File

@ -36,23 +36,23 @@
namespace godot {
Error XMLParser::_open_buffer(const uint8_t *p_buffer, size_t p_size) {
return (Error)internal::gde_interface->xml_parser_open_buffer(_owner, p_buffer, p_size);
return (Error)internal::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::gde_interface->file_access_get_buffer(_owner, p_dst, p_length);
return internal::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::gde_interface->file_access_store_buffer(_owner, p_src, p_length);
internal::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::gde_interface->worker_thread_pool_add_native_task(_owner, p_func, p_userdata, p_high_priority, (GDExtensionConstStringPtr)&p_description);
return (TaskID)internal::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::gde_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)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);
}
} // namespace godot

View File

@ -43,13 +43,13 @@ const StringName *Wrapped::_get_extension_class_name() const {
void Wrapped::_postinitialize() {
const StringName *extension_class = _get_extension_class_name();
if (extension_class) {
godot::internal::gde_interface->object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(extension_class), this);
godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(extension_class), this);
}
godot::internal::gde_interface->object_set_instance_binding(_owner, godot::internal::token, this, _get_bindings_callbacks());
godot::internal::gdextension_interface_object_set_instance_binding(_owner, godot::internal::token, this, _get_bindings_callbacks());
}
Wrapped::Wrapped(const StringName p_godot_class) {
_owner = godot::internal::gde_interface->classdb_construct_object(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
_owner = godot::internal::gdextension_interface_classdb_construct_object(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
}
Wrapped::Wrapped(GodotObject *p_godot_object) {

View File

@ -40,6 +40,7 @@
namespace godot {
std::unordered_map<StringName, ClassDB::ClassInfo> ClassDB::classes;
std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *> ClassDB::instance_binding_callbacks;
GDExtensionInitializationLevel ClassDB::current_level = GDEXTENSION_INITIALIZATION_CORE;
MethodDefinition D_METHOD(StringName p_name) {
@ -55,13 +56,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::gde_interface->classdb_register_extension_class_property_group(internal::library, p_class._native_ptr(), p_name._native_ptr(), p_prefix._native_ptr());
internal::gdextension_interface_classdb_register_extension_class_property_group(internal::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::gde_interface->classdb_register_extension_class_property_subgroup(internal::library, p_class._native_ptr(), p_name._native_ptr(), p_prefix._native_ptr());
internal::gdextension_interface_classdb_register_extension_class_property_subgroup(internal::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) {
@ -111,7 +112,7 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf
setget.index = p_index;
setget.type = p_pinfo.type;
internal::gde_interface->classdb_register_extension_class_property(internal::library, info.name._native_ptr(), &prop_info, setget.setter._native_ptr(), setget.getter._native_ptr());
internal::gdextension_interface_classdb_register_extension_class_property(internal::library, info.name._native_ptr(), &prop_info, setget.setter._native_ptr(), setget.getter._native_ptr());
}
MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_method) {
@ -234,7 +235,7 @@ void ClassDB::bind_method_godot(const StringName &p_class_name, MethodBind *p_me
(uint32_t)p_method->get_default_argument_count(), // uint32_t default_argument_count;
def_args.data(), // GDExtensionVariantPtr *default_arguments;
};
internal::gde_interface->classdb_register_extension_class_method(internal::library, p_class_name._native_ptr(), &method_info);
internal::gdextension_interface_classdb_register_extension_class_method(internal::library, p_class_name._native_ptr(), &method_info);
}
void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) {
@ -269,7 +270,7 @@ void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal)
});
}
internal::gde_interface->classdb_register_extension_class_signal(internal::library, cl.name._native_ptr(), p_signal.name._native_ptr(), parameters.data(), parameters.size());
internal::gdextension_interface_classdb_register_extension_class_signal(internal::library, cl.name._native_ptr(), p_signal.name._native_ptr(), parameters.data(), 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) {
@ -286,7 +287,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::gde_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);
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);
}
GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtensionConstStringNamePtr p_name) {
// This is called by Godot the first time it calls a virtual function, and it caches the result, per object instance.
@ -314,6 +315,12 @@ GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtens
return nullptr;
}
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);
ERR_FAIL_COND_V_MSG(callbacks_it == instance_binding_callbacks.end(), nullptr, String("Cannot find instance binding callbacks for class '{0}'.").format(Array::make(p_class)));
return callbacks_it->second;
}
void ClassDB::bind_virtual_method(const StringName &p_class, const StringName &p_method, GDExtensionClassCallVirtual p_call) {
std::unordered_map<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)));
@ -347,7 +354,7 @@ void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
continue;
}
internal::gde_interface->classdb_unregister_extension_class(internal::library, cl.name._native_ptr());
internal::gdextension_interface_classdb_unregister_extension_class(internal::library, cl.name._native_ptr());
for (auto method : cl.method_map) {
memdelete(method.second);

View File

@ -39,9 +39,9 @@ namespace godot {
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify, bool p_is_warning) {
if (p_is_warning) {
internal::gde_interface->print_warning(p_error, p_function, p_file, p_line, p_editor_notify);
internal::gdextension_interface_print_warning(p_error, p_function, p_file, p_line, p_editor_notify);
} else {
internal::gde_interface->print_error(p_error, p_function, p_file, p_line, p_editor_notify);
internal::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::gde_interface->print_warning_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
internal::gdextension_interface_print_warning_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
} else {
internal::gde_interface->print_error_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
internal::gdextension_interface_print_error_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
}
}

View File

@ -41,7 +41,7 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
bool prepad = p_pad_align;
#endif
void *mem = internal::gde_interface->mem_alloc(p_bytes + (prepad ? PAD_ALIGN : 0));
void *mem = internal::gdextension_interface_mem_alloc(p_bytes + (prepad ? PAD_ALIGN : 0));
ERR_FAIL_COND_V(!mem, nullptr);
if (prepad) {
@ -70,11 +70,11 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
if (prepad) {
mem -= PAD_ALIGN;
mem = (uint8_t *)internal::gde_interface->mem_realloc(mem, p_bytes + PAD_ALIGN);
mem = (uint8_t *)internal::gdextension_interface_mem_realloc(mem, p_bytes + PAD_ALIGN);
ERR_FAIL_COND_V(!mem, nullptr);
return mem + PAD_ALIGN;
} else {
return (uint8_t *)internal::gde_interface->mem_realloc(mem, p_bytes);
return (uint8_t *)internal::gdextension_interface_mem_realloc(mem, p_bytes);
}
}
@ -90,7 +90,7 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
if (prepad) {
mem -= PAD_ALIGN;
}
internal::gde_interface->mem_free(mem);
internal::gdextension_interface_mem_free(mem);
}
_GlobalNil::_GlobalNil() {

View File

@ -96,7 +96,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::gde_interface->variant_new_copy(r_return, ret._native_ptr());
internal::gdextension_interface_variant_new_copy(r_return, ret._native_ptr());
}
void MethodBind::bind_ptrcall(void *p_method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return) {

View File

@ -30,8 +30,38 @@
#include <godot_cpp/core/object.hpp>
#include <godot_cpp/core/class_db.hpp>
namespace godot {
namespace internal {
Object *get_object_instance_binding(GodotObject *p_engine_object) {
if (p_engine_object == nullptr) {
return nullptr;
}
// Get existing instance binding, if one already exists.
GDExtensionObjectPtr instance = gdextension_interface_object_get_instance_binding(p_engine_object, token, nullptr);
if (instance != nullptr) {
return reinterpret_cast<Object *>(instance);
}
// 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()))) {
binding_callbacks = ClassDB::get_instance_binding_callbacks(class_name);
}
if (binding_callbacks == nullptr) {
binding_callbacks = &Object::___binding_callbacks;
}
return reinterpret_cast<Object *>(gdextension_interface_object_get_instance_binding(p_engine_object, token, binding_callbacks));
}
} // namespace internal
MethodInfo::MethodInfo() :
flags(GDEXTENSION_METHOD_FLAG_NORMAL) {}

View File

@ -41,21 +41,335 @@ namespace godot {
namespace internal {
const GDExtensionInterface *gde_interface = nullptr;
GDExtensionInterfaceGetProcAddress gdextension_interface_get_proc_address = nullptr;
GDExtensionClassLibraryPtr library = nullptr;
void *token = nullptr;
GDExtensionGodotVersion godot_version = { 0, 0, 0, nullptr };
// All of the GDExtension interface functions.
GDExtensionInterfaceGetGodotVersion gdextension_interface_get_godot_version = 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;
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;
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;
GDExtensionInterfaceStringNewWithUtf16CharsAndLen gdextension_interface_string_new_with_utf16_chars_and_len = 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;
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;
GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index = nullptr;
GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const = nullptr;
GDExtensionInterfaceArrayRef gdextension_interface_array_ref = nullptr;
GDExtensionInterfaceArraySetTyped gdextension_interface_array_set_typed = nullptr;
GDExtensionInterfaceDictionaryOperatorIndex gdextension_interface_dictionary_operator_index = nullptr;
GDExtensionInterfaceDictionaryOperatorIndexConst gdextension_interface_dictionary_operator_index_const = 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;
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;
GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object = nullptr;
GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object = nullptr;
GDExtensionInterfaceScriptInstanceCreate gdextension_interface_script_instance_create = nullptr;
GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_construct_object = nullptr;
GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind = nullptr;
GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClass gdextension_interface_classdb_register_extension_class = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant = nullptr;
GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property = 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;
} // namespace internal
GDExtensionBinding::Callback GDExtensionBinding::init_callback = nullptr;
GDExtensionBinding::Callback GDExtensionBinding::terminate_callback = nullptr;
GDExtensionInitializationLevel GDExtensionBinding::minimum_initialization_level = GDEXTENSION_INITIALIZATION_CORE;
GDExtensionBool GDExtensionBinding::init(const GDExtensionInterface *p_interface, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
internal::gde_interface = p_interface;
#define LOAD_PROC_ADDRESS(m_name, m_type) \
internal::gdextension_interface_##m_name = (m_type)p_get_proc_address(#m_name); \
ERR_FAIL_NULL_V_MSG(internal::gdextension_interface_##m_name, false, "Unable to load GDExtension interface function " #m_name "()")
// Partial definition of the legacy interface so we can detect it and show an error.
typedef struct {
uint32_t version_major;
uint32_t version_minor;
uint32_t version_patch;
const char *version_string;
GDExtensionInterfaceFunctionPtr unused1;
GDExtensionInterfaceFunctionPtr unused2;
GDExtensionInterfaceFunctionPtr unused3;
GDExtensionInterfacePrintError print_error;
GDExtensionInterfacePrintErrorWithMessage print_error_with_message;
} LegacyGDExtensionInterface;
GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
// Make sure we weren't passed the legacy struct.
uint32_t *raw_interface = (uint32_t *)(void *)p_get_proc_address;
if (raw_interface[0] == 4 && raw_interface[1] == 0) {
// Use the legacy interface only to give a nice error.
LegacyGDExtensionInterface *legacy_interface = (LegacyGDExtensionInterface *)p_get_proc_address;
internal::gdextension_interface_print_error_with_message = (GDExtensionInterfacePrintErrorWithMessage)legacy_interface->print_error_with_message;
ERR_FAIL_V_MSG(false, "Cannot load a GDExtension built for Godot 4.1+ in Godot 4.0.");
}
// Load the "print_error_with_message" function first (needed by the ERR_FAIL_NULL_V_MSG() macro).
internal::gdextension_interface_print_error_with_message = (GDExtensionInterfacePrintErrorWithMessage)p_get_proc_address("print_error_with_message");
if (!internal::gdextension_interface_print_error_with_message) {
printf("ERROR: Unable to load GDExtension interface function print_error_with_message().\n");
return false;
}
internal::gdextension_interface_get_proc_address = p_get_proc_address;
internal::library = p_library;
internal::token = p_library;
LOAD_PROC_ADDRESS(get_godot_version, GDExtensionInterfaceGetGodotVersion);
LOAD_PROC_ADDRESS(mem_alloc, GDExtensionInterfaceMemAlloc);
LOAD_PROC_ADDRESS(mem_realloc, GDExtensionInterfaceMemRealloc);
LOAD_PROC_ADDRESS(mem_free, GDExtensionInterfaceMemFree);
LOAD_PROC_ADDRESS(print_error, GDExtensionInterfacePrintError);
LOAD_PROC_ADDRESS(print_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_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_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_utf16_chars_and_len, GDExtensionInterfaceStringNewWithUtf16CharsAndLen);
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(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(array_operator_index, GDExtensionInterfaceArrayOperatorIndex);
LOAD_PROC_ADDRESS(array_operator_index_const, GDExtensionInterfaceArrayOperatorIndexConst);
LOAD_PROC_ADDRESS(array_ref, GDExtensionInterfaceArrayRef);
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(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_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(ref_get_object, GDExtensionInterfaceRefGetObject);
LOAD_PROC_ADDRESS(ref_set_object, GDExtensionInterfaceRefSetObject);
LOAD_PROC_ADDRESS(script_instance_create, GDExtensionInterfaceScriptInstanceCreate);
LOAD_PROC_ADDRESS(classdb_construct_object, GDExtensionInterfaceClassdbConstructObject);
LOAD_PROC_ADDRESS(classdb_get_method_bind, GDExtensionInterfaceClassdbGetMethodBind);
LOAD_PROC_ADDRESS(classdb_get_class_tag, GDExtensionInterfaceClassdbGetClassTag);
LOAD_PROC_ADDRESS(classdb_register_extension_class, GDExtensionInterfaceClassdbRegisterExtensionClass);
LOAD_PROC_ADDRESS(classdb_register_extension_class_method, GDExtensionInterfaceClassdbRegisterExtensionClassMethod);
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_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 the Godot version.
internal::gdextension_interface_get_godot_version(&internal::godot_version);
r_initialization->initialize = initialize_level;
r_initialization->deinitialize = deinitialize_level;
r_initialization->minimum_initialization_level = minimum_initialization_level;
@ -63,10 +377,13 @@ GDExtensionBool GDExtensionBinding::init(const GDExtensionInterface *p_interface
ERR_FAIL_COND_V_MSG(init_callback == nullptr, false, "Initialization callback must be defined.");
Variant::init_bindings();
register_engine_classes();
return true;
}
#undef LOAD_PROC_ADDRESS
void GDExtensionBinding::initialize_level(void *userdata, GDExtensionInitializationLevel p_level) {
ClassDB::current_level = p_level;
@ -86,6 +403,11 @@ void GDExtensionBinding::deinitialize_level(void *userdata, GDExtensionInitializ
ClassDB::deinitialize(p_level);
}
GDExtensionBinding::InitObject::InitObject(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
get_proc_address = p_get_proc_address;
library = p_library;
initialization = r_initialization;
}
void GDExtensionBinding::InitObject::register_initializer(Callback p_init) const {
GDExtensionBinding::init_callback = p_init;
@ -100,7 +422,7 @@ void GDExtensionBinding::InitObject::set_minimum_library_initialization_level(Mo
}
GDExtensionBool GDExtensionBinding::InitObject::init() const {
return GDExtensionBinding::init(gde_interface, library, initialization);
return GDExtensionBinding::init(get_proc_address, library, initialization);
}
} // namespace godot

View File

@ -153,19 +153,19 @@ CharWideString::~CharWideString() {
// It's easier to have them written in C++ directly than in a Python script that generates them.
String::String(const char *from) {
internal::gde_interface->string_new_with_latin1_chars(_native_ptr(), from);
internal::gdextension_interface_string_new_with_latin1_chars(_native_ptr(), from);
}
String::String(const wchar_t *from) {
internal::gde_interface->string_new_with_wide_chars(_native_ptr(), from);
internal::gdextension_interface_string_new_with_wide_chars(_native_ptr(), from);
}
String::String(const char16_t *from) {
internal::gde_interface->string_new_with_utf16_chars(_native_ptr(), from);
internal::gdextension_interface_string_new_with_utf16_chars(_native_ptr(), from);
}
String::String(const char32_t *from) {
internal::gde_interface->string_new_with_utf32_chars(_native_ptr(), from);
internal::gdextension_interface_string_new_with_utf32_chars(_native_ptr(), from);
}
String String::utf8(const char *from, int len) {
@ -175,7 +175,7 @@ String String::utf8(const char *from, int len) {
}
void String::parse_utf8(const char *from, int len) {
internal::gde_interface->string_new_with_utf8_chars_and_len(_native_ptr(), from, len);
internal::gdextension_interface_string_new_with_utf8_chars_and_len(_native_ptr(), from, len);
}
String String::utf16(const char16_t *from, int len) {
@ -185,7 +185,7 @@ String String::utf16(const char16_t *from, int len) {
}
void String::parse_utf16(const char16_t *from, int len) {
internal::gde_interface->string_new_with_utf16_chars_and_len(_native_ptr(), from, len);
internal::gdextension_interface_string_new_with_utf16_chars_and_len(_native_ptr(), from, len);
}
String String::num_real(double p_num, bool p_trailing) {
@ -226,10 +226,10 @@ String rtoss(double p_val) {
}
CharString String::utf8() const {
int length = internal::gde_interface->string_to_utf8_chars(_native_ptr(), nullptr, 0);
int length = internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), nullptr, 0);
int size = length + 1;
char *cstr = memnew_arr(char, size);
internal::gde_interface->string_to_utf8_chars(_native_ptr(), cstr, length);
internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), cstr, length);
cstr[length] = '\0';
@ -237,10 +237,10 @@ CharString String::utf8() const {
}
CharString String::ascii() const {
int length = internal::gde_interface->string_to_latin1_chars(_native_ptr(), nullptr, 0);
int length = internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), nullptr, 0);
int size = length + 1;
char *cstr = memnew_arr(char, size);
internal::gde_interface->string_to_latin1_chars(_native_ptr(), cstr, length);
internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), cstr, length);
cstr[length] = '\0';
@ -248,10 +248,10 @@ CharString String::ascii() const {
}
Char16String String::utf16() const {
int length = internal::gde_interface->string_to_utf16_chars(_native_ptr(), nullptr, 0);
int length = internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), nullptr, 0);
int size = length + 1;
char16_t *cstr = memnew_arr(char16_t, size);
internal::gde_interface->string_to_utf16_chars(_native_ptr(), cstr, length);
internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), cstr, length);
cstr[length] = '\0';
@ -259,10 +259,10 @@ Char16String String::utf16() const {
}
Char32String String::utf32() const {
int length = internal::gde_interface->string_to_utf32_chars(_native_ptr(), nullptr, 0);
int length = internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), nullptr, 0);
int size = length + 1;
char32_t *cstr = memnew_arr(char32_t, size);
internal::gde_interface->string_to_utf32_chars(_native_ptr(), cstr, length);
internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), cstr, length);
cstr[length] = '\0';
@ -270,10 +270,10 @@ Char32String String::utf32() const {
}
CharWideString String::wide_string() const {
int length = internal::gde_interface->string_to_wide_chars(_native_ptr(), nullptr, 0);
int length = internal::gdextension_interface_string_to_wide_chars(_native_ptr(), nullptr, 0);
int size = length + 1;
wchar_t *cstr = memnew_arr(wchar_t, size);
internal::gde_interface->string_to_wide_chars(_native_ptr(), cstr, length);
internal::gdextension_interface_string_to_wide_chars(_native_ptr(), cstr, length);
cstr[length] = '\0';
@ -353,44 +353,44 @@ String String::operator+(const char32_t p_char) {
}
String &String::operator+=(const String &p_str) {
internal::gde_interface->string_operator_plus_eq_string((GDExtensionStringPtr)this, (GDExtensionConstStringPtr)&p_str);
internal::gdextension_interface_string_operator_plus_eq_string((GDExtensionStringPtr)this, (GDExtensionConstStringPtr)&p_str);
return *this;
}
String &String::operator+=(char32_t p_char) {
internal::gde_interface->string_operator_plus_eq_char((GDExtensionStringPtr)this, p_char);
internal::gdextension_interface_string_operator_plus_eq_char((GDExtensionStringPtr)this, p_char);
return *this;
}
String &String::operator+=(const char *p_str) {
internal::gde_interface->string_operator_plus_eq_cstr((GDExtensionStringPtr)this, p_str);
internal::gdextension_interface_string_operator_plus_eq_cstr((GDExtensionStringPtr)this, p_str);
return *this;
}
String &String::operator+=(const wchar_t *p_str) {
internal::gde_interface->string_operator_plus_eq_wcstr((GDExtensionStringPtr)this, p_str);
internal::gdextension_interface_string_operator_plus_eq_wcstr((GDExtensionStringPtr)this, p_str);
return *this;
}
String &String::operator+=(const char32_t *p_str) {
internal::gde_interface->string_operator_plus_eq_c32str((GDExtensionStringPtr)this, p_str);
internal::gdextension_interface_string_operator_plus_eq_c32str((GDExtensionStringPtr)this, p_str);
return *this;
}
const char32_t &String::operator[](int p_index) const {
return *internal::gde_interface->string_operator_index_const((GDExtensionStringPtr)this, p_index);
return *internal::gdextension_interface_string_operator_index_const((GDExtensionStringPtr)this, p_index);
}
char32_t &String::operator[](int p_index) {
return *internal::gde_interface->string_operator_index((GDExtensionStringPtr)this, p_index);
return *internal::gdextension_interface_string_operator_index((GDExtensionStringPtr)this, p_index);
}
const char32_t *String::ptr() const {
return internal::gde_interface->string_operator_index_const((GDExtensionStringPtr)this, 0);
return internal::gdextension_interface_string_operator_index_const((GDExtensionStringPtr)this, 0);
}
char32_t *String::ptrw() {
return internal::gde_interface->string_operator_index((GDExtensionStringPtr)this, 0);
return internal::gdextension_interface_string_operator_index((GDExtensionStringPtr)this, 0);
}
bool operator==(const char *p_chr, const String &p_str) {

View File

@ -47,183 +47,183 @@
namespace godot {
const uint8_t &PackedByteArray::operator[](int p_index) const {
return *internal::gde_interface->packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *internal::gdextension_interface_packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
}
uint8_t &PackedByteArray::operator[](int p_index) {
return *internal::gde_interface->packed_byte_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *internal::gdextension_interface_packed_byte_array_operator_index((GDExtensionTypePtr *)this, p_index);
}
const uint8_t *PackedByteArray::ptr() const {
return internal::gde_interface->packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return internal::gdextension_interface_packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
uint8_t *PackedByteArray::ptrw() {
return internal::gde_interface->packed_byte_array_operator_index((GDExtensionTypePtr *)this, 0);
return internal::gdextension_interface_packed_byte_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const Color &PackedColorArray::operator[](int p_index) const {
const Color *color = (const Color *)internal::gde_interface->packed_color_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
const Color *color = (const Color *)internal::gdextension_interface_packed_color_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *color;
}
Color &PackedColorArray::operator[](int p_index) {
Color *color = (Color *)internal::gde_interface->packed_color_array_operator_index((GDExtensionTypePtr *)this, p_index);
Color *color = (Color *)internal::gdextension_interface_packed_color_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *color;
}
const Color *PackedColorArray::ptr() const {
return (const Color *)internal::gde_interface->packed_color_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return (const Color *)internal::gdextension_interface_packed_color_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
Color *PackedColorArray::ptrw() {
return (Color *)internal::gde_interface->packed_color_array_operator_index((GDExtensionTypePtr *)this, 0);
return (Color *)internal::gdextension_interface_packed_color_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const float &PackedFloat32Array::operator[](int p_index) const {
return *internal::gde_interface->packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *internal::gdextension_interface_packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
}
float &PackedFloat32Array::operator[](int p_index) {
return *internal::gde_interface->packed_float32_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *internal::gdextension_interface_packed_float32_array_operator_index((GDExtensionTypePtr *)this, p_index);
}
const float *PackedFloat32Array::ptr() const {
return internal::gde_interface->packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return internal::gdextension_interface_packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
float *PackedFloat32Array::ptrw() {
return internal::gde_interface->packed_float32_array_operator_index((GDExtensionTypePtr *)this, 0);
return internal::gdextension_interface_packed_float32_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const double &PackedFloat64Array::operator[](int p_index) const {
return *internal::gde_interface->packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *internal::gdextension_interface_packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
}
double &PackedFloat64Array::operator[](int p_index) {
return *internal::gde_interface->packed_float64_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *internal::gdextension_interface_packed_float64_array_operator_index((GDExtensionTypePtr *)this, p_index);
}
const double *PackedFloat64Array::ptr() const {
return internal::gde_interface->packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return internal::gdextension_interface_packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
double *PackedFloat64Array::ptrw() {
return internal::gde_interface->packed_float64_array_operator_index((GDExtensionTypePtr *)this, 0);
return internal::gdextension_interface_packed_float64_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const int32_t &PackedInt32Array::operator[](int p_index) const {
return *internal::gde_interface->packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *internal::gdextension_interface_packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
}
int32_t &PackedInt32Array::operator[](int p_index) {
return *internal::gde_interface->packed_int32_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *internal::gdextension_interface_packed_int32_array_operator_index((GDExtensionTypePtr *)this, p_index);
}
const int32_t *PackedInt32Array::ptr() const {
return internal::gde_interface->packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return internal::gdextension_interface_packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
int32_t *PackedInt32Array::ptrw() {
return internal::gde_interface->packed_int32_array_operator_index((GDExtensionTypePtr *)this, 0);
return internal::gdextension_interface_packed_int32_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const int64_t &PackedInt64Array::operator[](int p_index) const {
return *internal::gde_interface->packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *internal::gdextension_interface_packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
}
int64_t &PackedInt64Array::operator[](int p_index) {
return *internal::gde_interface->packed_int64_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *internal::gdextension_interface_packed_int64_array_operator_index((GDExtensionTypePtr *)this, p_index);
}
const int64_t *PackedInt64Array::ptr() const {
return internal::gde_interface->packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return internal::gdextension_interface_packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
int64_t *PackedInt64Array::ptrw() {
return internal::gde_interface->packed_int64_array_operator_index((GDExtensionTypePtr *)this, 0);
return internal::gdextension_interface_packed_int64_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const String &PackedStringArray::operator[](int p_index) const {
const String *string = (const String *)internal::gde_interface->packed_string_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
const String *string = (const String *)internal::gdextension_interface_packed_string_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *string;
}
String &PackedStringArray::operator[](int p_index) {
String *string = (String *)internal::gde_interface->packed_string_array_operator_index((GDExtensionTypePtr *)this, p_index);
String *string = (String *)internal::gdextension_interface_packed_string_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *string;
}
const String *PackedStringArray::ptr() const {
return (const String *)internal::gde_interface->packed_string_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return (const String *)internal::gdextension_interface_packed_string_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
String *PackedStringArray::ptrw() {
return (String *)internal::gde_interface->packed_string_array_operator_index((GDExtensionTypePtr *)this, 0);
return (String *)internal::gdextension_interface_packed_string_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const Vector2 &PackedVector2Array::operator[](int p_index) const {
const Vector2 *vec = (const Vector2 *)internal::gde_interface->packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
const Vector2 *vec = (const Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *vec;
}
Vector2 &PackedVector2Array::operator[](int p_index) {
Vector2 *vec = (Vector2 *)internal::gde_interface->packed_vector2_array_operator_index((GDExtensionTypePtr *)this, p_index);
Vector2 *vec = (Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *vec;
}
const Vector2 *PackedVector2Array::ptr() const {
return (const Vector2 *)internal::gde_interface->packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return (const Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
Vector2 *PackedVector2Array::ptrw() {
return (Vector2 *)internal::gde_interface->packed_vector2_array_operator_index((GDExtensionTypePtr *)this, 0);
return (Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const Vector3 &PackedVector3Array::operator[](int p_index) const {
const Vector3 *vec = (const Vector3 *)internal::gde_interface->packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
const Vector3 *vec = (const Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *vec;
}
Vector3 &PackedVector3Array::operator[](int p_index) {
Vector3 *vec = (Vector3 *)internal::gde_interface->packed_vector3_array_operator_index((GDExtensionTypePtr *)this, p_index);
Vector3 *vec = (Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index((GDExtensionTypePtr *)this, p_index);
return *vec;
}
const Vector3 *PackedVector3Array::ptr() const {
return (const Vector3 *)internal::gde_interface->packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, 0);
return (const Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, 0);
}
Vector3 *PackedVector3Array::ptrw() {
return (Vector3 *)internal::gde_interface->packed_vector3_array_operator_index((GDExtensionTypePtr *)this, 0);
return (Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index((GDExtensionTypePtr *)this, 0);
}
const Variant &Array::operator[](int p_index) const {
const Variant *var = (const Variant *)internal::gde_interface->array_operator_index_const((GDExtensionTypePtr *)this, p_index);
const Variant *var = (const Variant *)internal::gdextension_interface_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
return *var;
}
Variant &Array::operator[](int p_index) {
Variant *var = (Variant *)internal::gde_interface->array_operator_index((GDExtensionTypePtr *)this, p_index);
Variant *var = (Variant *)internal::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::gde_interface->array_set_typed((GDExtensionTypePtr *)this, (GDExtensionVariantType)p_type, (GDExtensionConstStringNamePtr)&p_class_name, (GDExtensionConstVariantPtr)&p_script);
internal::gdextension_interface_array_set_typed((GDExtensionTypePtr *)this, (GDExtensionVariantType)p_type, (GDExtensionConstStringNamePtr)&p_class_name, (GDExtensionConstVariantPtr)&p_script);
}
void Array::_ref(const Array &p_from) const {
internal::gde_interface->array_ref((GDExtensionTypePtr *)this, (GDExtensionConstTypePtr *)&p_from);
internal::gdextension_interface_array_ref((GDExtensionTypePtr *)this, (GDExtensionConstTypePtr *)&p_from);
}
const Variant &Dictionary::operator[](const Variant &p_key) const {
const Variant *var = (const Variant *)internal::gde_interface->dictionary_operator_index_const((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
const Variant *var = (const Variant *)internal::gdextension_interface_dictionary_operator_index_const((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
return *var;
}
Variant &Dictionary::operator[](const Variant &p_key) {
Variant *var = (Variant *)internal::gde_interface->dictionary_operator_index((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
Variant *var = (Variant *)internal::gdextension_interface_dictionary_operator_index((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
return *var;
}

View File

@ -33,6 +33,7 @@
#include <godot_cpp/godot.hpp>
#include <godot_cpp/core/binder_common.hpp>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/defs.hpp>
#include <utility>
@ -45,8 +46,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::gde_interface->get_variant_from_type_constructor((GDExtensionVariantType)i);
to_type_constructor[i] = internal::gde_interface->get_variant_to_type_constructor((GDExtensionVariantType)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);
}
StringName::init_bindings();
@ -69,15 +70,15 @@ void Variant::init_bindings() {
}
Variant::Variant() {
internal::gde_interface->variant_new_nil(_native_ptr());
internal::gdextension_interface_variant_new_nil(_native_ptr());
}
Variant::Variant(GDExtensionConstVariantPtr native_ptr) {
internal::gde_interface->variant_new_copy(_native_ptr(), native_ptr);
internal::gdextension_interface_variant_new_copy(_native_ptr(), native_ptr);
}
Variant::Variant(const Variant &other) {
internal::gde_interface->variant_new_copy(_native_ptr(), other._native_ptr());
internal::gdextension_interface_variant_new_copy(_native_ptr(), other._native_ptr());
}
Variant::Variant(Variant &&other) {
@ -248,7 +249,7 @@ Variant::Variant(const PackedColorArray &v) {
}
Variant::~Variant() {
internal::gde_interface->variant_destroy(_native_ptr());
internal::gdextension_interface_variant_destroy(_native_ptr());
}
Variant::operator bool() const {
@ -411,7 +412,7 @@ Variant::operator Object *() const {
if (obj == nullptr) {
return nullptr;
}
return reinterpret_cast<Object *>(internal::gde_interface->object_get_instance_binding(obj, internal::token, &Object::___binding_callbacks));
return internal::get_object_instance_binding(obj);
}
Variant::operator ObjectID() const {
@ -509,7 +510,7 @@ Variant::operator PackedColorArray() const {
Variant &Variant::operator=(const Variant &other) {
clear();
internal::gde_interface->variant_new_copy(_native_ptr(), other._native_ptr());
internal::gdextension_interface_variant_new_copy(_native_ptr(), other._native_ptr());
return *this;
}
@ -549,22 +550,22 @@ bool Variant::operator<(const Variant &other) const {
}
void Variant::call(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
internal::gde_interface->variant_call(_native_ptr(), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
internal::gdextension_interface_variant_call(_native_ptr(), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
}
void Variant::call_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
internal::gde_interface->variant_call_static(static_cast<GDExtensionVariantType>(type), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &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);
}
void Variant::evaluate(const Operator &op, const Variant &a, const Variant &b, Variant &r_ret, bool &r_valid) {
GDExtensionBool valid;
internal::gde_interface->variant_evaluate(static_cast<GDExtensionVariantOperator>(op), a._native_ptr(), b._native_ptr(), r_ret._native_ptr(), &valid);
internal::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::gde_interface->variant_set(_native_ptr(), key._native_ptr(), value._native_ptr(), &valid);
internal::gdextension_interface_variant_set(_native_ptr(), key._native_ptr(), value._native_ptr(), &valid);
if (r_valid) {
*r_valid = PtrToArg<bool>::convert(&valid);
}
@ -572,27 +573,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::gde_interface->variant_set_named(_native_ptr(), name._native_ptr(), value._native_ptr(), &valid);
internal::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::gde_interface->variant_set_indexed(_native_ptr(), index, value._native_ptr(), &valid, &oob);
internal::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::gde_interface->variant_set_keyed(_native_ptr(), key._native_ptr(), value._native_ptr(), &valid);
internal::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::gde_interface->variant_get(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
internal::gdextension_interface_variant_get(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
if (r_valid) {
*r_valid = PtrToArg<bool>::convert(&valid);
}
@ -602,7 +603,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::gde_interface->variant_get_named(_native_ptr(), name._native_ptr(), result._native_ptr(), &valid);
internal::gdextension_interface_variant_get_named(_native_ptr(), name._native_ptr(), result._native_ptr(), &valid);
r_valid = PtrToArg<bool>::convert(&valid);
return result;
}
@ -611,7 +612,7 @@ Variant Variant::get_indexed(int64_t index, bool &r_valid, bool &r_oob) const {
Variant result;
GDExtensionBool valid;
GDExtensionBool oob;
internal::gde_interface->variant_get_indexed(_native_ptr(), index, result._native_ptr(), &valid, &oob);
internal::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;
@ -620,7 +621,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::gde_interface->variant_get_keyed(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
internal::gdextension_interface_variant_get_keyed(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
r_valid = PtrToArg<bool>::convert(&valid);
return result;
}
@ -637,36 +638,36 @@ bool Variant::in(const Variant &index, bool *r_valid) const {
bool Variant::iter_init(Variant &r_iter, bool &r_valid) const {
GDExtensionBool valid;
internal::gde_interface->variant_iter_init(_native_ptr(), r_iter._native_ptr(), &valid);
internal::gdextension_interface_variant_iter_init(_native_ptr(), r_iter._native_ptr(), &valid);
return PtrToArg<bool>::convert(&valid);
}
bool Variant::iter_next(Variant &r_iter, bool &r_valid) const {
GDExtensionBool valid;
internal::gde_interface->variant_iter_next(_native_ptr(), r_iter._native_ptr(), &valid);
internal::gdextension_interface_variant_iter_next(_native_ptr(), r_iter._native_ptr(), &valid);
return PtrToArg<bool>::convert(&valid);
}
Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
Variant result;
GDExtensionBool valid;
internal::gde_interface->variant_iter_get(_native_ptr(), r_iter._native_ptr(), result._native_ptr(), &valid);
internal::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::gde_interface->variant_get_type(_native_ptr()));
return static_cast<Variant::Type>(internal::gdextension_interface_variant_get_type(_native_ptr()));
}
bool Variant::has_method(const StringName &method) const {
GDExtensionBool has = internal::gde_interface->variant_has_method(_native_ptr(), method._native_ptr());
GDExtensionBool has = internal::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::gde_interface->variant_has_key(_native_ptr(), key._native_ptr(), &valid);
GDExtensionBool has = internal::gdextension_interface_variant_has_key(_native_ptr(), key._native_ptr(), &valid);
if (r_valid) {
*r_valid = PtrToArg<bool>::convert(&valid);
}
@ -674,33 +675,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::gde_interface->variant_has_member(static_cast<GDExtensionVariantType>(type), member._native_ptr());
GDExtensionBool has = internal::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::gde_interface->variant_hash(_native_ptr());
GDExtensionInt hash = internal::gdextension_interface_variant_hash(_native_ptr());
return PtrToArg<uint32_t>::convert(&hash);
}
uint32_t Variant::recursive_hash(int recursion_count) const {
GDExtensionInt hash = internal::gde_interface->variant_recursive_hash(_native_ptr(), recursion_count);
GDExtensionInt hash = internal::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::gde_interface->variant_hash_compare(_native_ptr(), variant._native_ptr());
GDExtensionBool compare = internal::gdextension_interface_variant_hash_compare(_native_ptr(), variant._native_ptr());
return PtrToArg<bool>::convert(&compare);
}
bool Variant::booleanize() const {
GDExtensionBool booleanized = internal::gde_interface->variant_booleanize(_native_ptr());
GDExtensionBool booleanized = internal::gdextension_interface_variant_booleanize(_native_ptr());
return PtrToArg<bool>::convert(&booleanized);
}
String Variant::stringify() const {
String result;
internal::gde_interface->variant_stringify(_native_ptr(), result._native_ptr());
internal::gdextension_interface_variant_stringify(_native_ptr(), result._native_ptr());
return result;
}
@ -708,23 +709,23 @@ Variant Variant::duplicate(bool deep) const {
Variant result;
GDExtensionBool _deep;
PtrToArg<bool>::encode(deep, &_deep);
internal::gde_interface->variant_duplicate(_native_ptr(), result._native_ptr(), _deep);
internal::gdextension_interface_variant_duplicate(_native_ptr(), result._native_ptr(), _deep);
return result;
}
String Variant::get_type_name(Variant::Type type) {
String result;
internal::gde_interface->variant_get_type_name(static_cast<GDExtensionVariantType>(type), result._native_ptr());
internal::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::gde_interface->variant_can_convert(static_cast<GDExtensionVariantType>(from), static_cast<GDExtensionVariantType>(to));
GDExtensionBool can = internal::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::gde_interface->variant_can_convert_strict(static_cast<GDExtensionVariantType>(from), static_cast<GDExtensionVariantType>(to));
GDExtensionBool can = internal::gdextension_interface_variant_can_convert_strict(static_cast<GDExtensionVariantType>(from), static_cast<GDExtensionVariantType>(to));
return PtrToArg<bool>::convert(&can);
}
@ -775,9 +776,9 @@ void Variant::clear() {
};
if (unlikely(needs_deinit[get_type()])) { // Make it fast for types that don't need deinit.
internal::gde_interface->variant_destroy(_native_ptr());
internal::gdextension_interface_variant_destroy(_native_ptr());
}
internal::gde_interface->variant_new_nil(_native_ptr());
internal::gdextension_interface_variant_new_nil(_native_ptr());
}
} // namespace godot

View File

@ -1,11 +1,8 @@
# godot-cpp example / integration test
# godot-cpp integration test
This project is used to perform integration testing of the godot-cpp
extension, to validate PRs and implemented APIs.
It can also be used as a quick example of how to set up a godot-cpp
project, both on the C++ side and in the Godot project itself.
## License
This is free and unencumbered software released into the public domain.

View File

@ -18,14 +18,14 @@ sources = Glob("src/*.cpp")
if env["platform"] == "macos":
library = env.SharedLibrary(
"demo/bin/libgdexample.{}.{}.framework/libgdexample.{}.{}".format(
"project/bin/libgdexample.{}.{}.framework/libgdexample.{}.{}".format(
env["platform"], env["target"], env["platform"], env["target"]
),
source=sources,
)
else:
library = env.SharedLibrary(
"demo/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
"project/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
source=sources,
)

View File

@ -1,80 +0,0 @@
extends Node
func _ready():
# Bind signals
prints("Signal bind")
$Button.button_up.connect($Example.emit_custom_signal.bind("Button", 42))
prints("")
# To string.
prints("To string")
prints(" Example --> ", $Example.to_string())
prints(" ExampleMin --> ", $Example/ExampleMin.to_string())
# Call static methods.
prints("Static method calls")
prints(" static (109)", Example.test_static(9, 100));
Example.test_static2();
# Property list.
prints("Property list")
$Example.property_from_list = Vector3(100, 200, 300)
prints(" property value ", $Example.property_from_list)
# Call methods.
prints("Instance method calls")
$Example.simple_func()
($Example as Example).simple_const_func() # Force use of ptrcall
prints(" returned", $Example.return_something("some string"))
prints(" returned const", $Example.return_something_const())
var null_ref = $Example.return_empty_ref()
prints(" returned empty ref", null_ref)
var ret_ref = $Example.return_extended_ref()
prints(" returned ref", ret_ref.get_instance_id(), ", id:", ret_ref.get_id())
prints(" returned ", $Example.get_v4())
prints(" test node argument", $Example.test_node_argument($Example))
prints("VarArg method calls")
var ref = ExampleRef.new()
prints(" sending ref: ", ref.get_instance_id(), "returned ref: ", $Example.extended_ref_checks(ref).get_instance_id())
prints(" vararg args", $Example.varargs_func("some", "arguments", "to", "test"))
prints(" vararg_nv ret", $Example.varargs_func_nv("some", "arguments", "to", "test"))
$Example.varargs_func_void("some", "arguments", "to", "test")
prints("Method calls with default values")
prints(" defval (300)", $Example.def_args())
prints(" defval (250)", $Example.def_args(50))
prints(" defval (150)", $Example.def_args(50, 100))
prints("Array and Dictionary")
prints(" test array", $Example.test_array())
prints(" test tarray", $Example.test_tarray())
prints(" test dictionary", $Example.test_dictionary())
var array: Array[int] = [1, 2, 3]
$Example.test_tarray_arg(array)
prints("String += operator")
prints(" test string +=", $Example.test_string_ops())
prints("PackedArray iterators")
prints(" test packed array iterators", $Example.test_vector_ops())
prints("Properties")
prints(" custom position is", $Example.group_subgroup_custom_position)
$Example.group_subgroup_custom_position = Vector2(50, 50)
prints(" custom position now is", $Example.group_subgroup_custom_position)
prints("Constants")
prints(" FIRST", $Example.FIRST)
prints(" ANSWER_TO_EVERYTHING", $Example.ANSWER_TO_EVERYTHING)
prints(" CONSTANT_WITHOUT_ENUM", $Example.CONSTANT_WITHOUT_ENUM)
prints("BitFields")
prints(" FLAG_ONE", Example.FLAG_ONE)
prints(" FLAG_TWO", Example.FLAG_TWO)
prints(" returned BitField", $Example.test_bitfield(0))
prints(" returned BitField", $Example.test_bitfield(Example.FLAG_ONE | Example.FLAG_TWO))
func _on_Example_custom_signal(signal_name, value):
prints("Example emitted:", signal_name, value)

View File

@ -1,6 +1,7 @@
[configuration]
entry_symbol = "example_library_init"
compatibility_minimum = 4.1
[libraries]

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.cte
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false

114
test/project/main.gd Normal file
View File

@ -0,0 +1,114 @@
extends "res://test_base.gd"
var custom_signal_emitted = null
func _ready():
var example: Example = $Example
# Signal.
example.emit_custom_signal("Button", 42)
assert_equal(custom_signal_emitted, ["Button", 42])
# To string.
assert_equal(example.to_string(),'Example:[ GDExtension::Example <--> Instance ID:%s ]' % example.get_instance_id())
# It appears there's a bug with instance ids :-(
#assert_equal($Example/ExampleMin.to_string(), 'ExampleMin:[Wrapped:%s]' % $Example/ExampleMin.get_instance_id())
# Call static methods.
assert_equal(Example.test_static(9, 100), 109);
# It's void and static, so all we know is that it didn't crash.
Example.test_static2()
# Property list.
example.property_from_list = Vector3(100, 200, 300)
assert_equal(example.property_from_list, Vector3(100, 200, 300))
# Call simple methods.
example.simple_func()
assert_equal(custom_signal_emitted, ['simple_func', 3])
example.simple_const_func()
assert_equal(custom_signal_emitted, ['simple_const_func', 4])
# Pass custom reference.
assert_equal(example.custom_ref_func(null), -1)
var ref1 = ExampleRef.new()
ref1.id = 27
assert_equal(example.custom_ref_func(ref1), 27)
ref1.id += 1;
assert_equal(example.custom_const_ref_func(ref1), 28)
# Pass core reference.
assert_equal(example.image_ref_func(null), "invalid")
assert_equal(example.image_const_ref_func(null), "invalid")
var image = Image.new()
assert_equal(example.image_ref_func(image), "valid")
assert_equal(example.image_const_ref_func(image), "valid")
# Return values.
assert_equal(example.return_something("some string"), "some string42")
assert_equal(example.return_something_const(), get_viewport())
var null_ref = example.return_empty_ref()
assert_equal(null_ref, null)
var ret_ref = example.return_extended_ref()
assert_not_equal(ret_ref.get_instance_id(), 0)
assert_equal(ret_ref.get_id(), 0)
assert_equal(example.get_v4(), Vector4(1.2, 3.4, 5.6, 7.8))
assert_equal(example.test_node_argument(example), example)
# VarArg method calls.
var var_ref = ExampleRef.new()
assert_not_equal(example.extended_ref_checks(var_ref).get_instance_id(), var_ref.get_instance_id())
assert_equal(example.varargs_func("some", "arguments", "to", "test"), 4)
assert_equal(example.varargs_func_nv("some", "arguments", "to", "test"), 46)
example.varargs_func_void("some", "arguments", "to", "test")
assert_equal(custom_signal_emitted, ["varargs_func_void", 5])
# Method calls with default values.
assert_equal(example.def_args(), 300)
assert_equal(example.def_args(50), 250)
assert_equal(example.def_args(50, 100), 150)
# Array and Dictionary
assert_equal(example.test_array(), [1, 2])
assert_equal(example.test_tarray(), [ Vector2(1, 2), Vector2(2, 3) ])
assert_equal(example.test_dictionary(), {"hello": "world", "foo": "bar"})
var array: Array[int] = [1, 2, 3]
assert_equal(example.test_tarray_arg(array), 6)
# String += operator
assert_equal(example.test_string_ops(), "ABCĎE")
# UtilityFunctions::str()
assert_equal(example.test_str_utility(), "Hello, World! The answer is 42")
# PackedArray iterators
assert_equal(example.test_vector_ops(), 105)
# Properties.
assert_equal(example.group_subgroup_custom_position, Vector2(0, 0))
example.group_subgroup_custom_position = Vector2(50, 50)
assert_equal(example.group_subgroup_custom_position, Vector2(50, 50))
# Constants.
assert_equal(Example.FIRST, 0)
assert_equal(Example.ANSWER_TO_EVERYTHING, 42)
assert_equal(Example.CONSTANT_WITHOUT_ENUM, 314)
# BitFields.
assert_equal(Example.FLAG_ONE, 1)
assert_equal(Example.FLAG_TWO, 2)
assert_equal(example.test_bitfield(0), 0)
assert_equal(example.test_bitfield(Example.FLAG_ONE | Example.FLAG_TWO), 3)
# Virtual method.
var event = InputEventKey.new()
event.key_label = KEY_H
event.unicode = 72
get_viewport().push_input(event)
assert_equal(custom_signal_emitted, ["_input: H", 72])
exit_with_status()
func _on_Example_custom_signal(signal_name, value):
custom_signal_emitted = [signal_name, value]

View File

@ -1,9 +1,9 @@
[gd_scene load_steps=2 format=3 uid="uid://dmx2xuigcpvt4"]
[ext_resource type="Script" path="res://main.gd" id="1_c326s"]
[ext_resource type="Script" path="res://main.gd" id="1_qesh5"]
[node name="Node" type="Node"]
script = ExtResource("1_c326s")
script = ExtResource("1_qesh5")
[node name="Example" type="Example" parent="."]

View File

@ -12,7 +12,7 @@ config_version=5
config/name="GDExtension Test Project"
run/main_scene="res://main.tscn"
config/features=PackedStringArray("4.0")
config/features=PackedStringArray("4.1")
config/icon="res://icon.png"
[native_extensions]

59
test/project/test_base.gd Normal file
View File

@ -0,0 +1,59 @@
extends Node
var test_passes := 0
var test_failures := 0
func __get_stack_frame():
var me = get_script()
for s in get_stack():
if s.source == me.resource_path:
return s
return null
func __assert_pass():
test_passes += 1
func __assert_fail():
test_failures += 1
var s = __get_stack_frame()
if s != null:
print_rich ("[color=red] == FAILURE: In function %s() from '%s' on line %s[/color]" % [s.function, s.source, s.line])
else:
print_rich ("[color=red] == FAILURE (run with --debug to get more information!) ==[/color]")
func assert_equal(actual, expected):
if actual == expected:
__assert_pass()
else:
__assert_fail()
print (" |-> Expected '%s' but got '%s'" % [expected, actual])
func assert_true(v):
assert_equal(v, true)
func assert_false(v):
assert_equal(v, false)
func assert_not_equal(actual, expected):
if actual != expected:
__assert_pass()
else:
__assert_fail()
print (" |-> Expected '%s' NOT to equal '%s'" % [expected, actual])
func exit_with_status() -> void:
var success: bool = (test_failures == 0)
print ("")
print_rich ("[color=%s] ==== TESTS FINISHED ==== [/color]" % ("green" if success else "red"))
print ("")
print_rich (" PASSES: [color=green]%s[/color]" % test_passes)
print_rich (" FAILURES: [color=red]%s[/color]" % test_failures)
print ("")
if success:
print_rich("[color=green] ******** PASSED ******** [/color]")
else:
print_rich("[color=red] ******** FAILED ********[/color]")
print("")
get_tree().quit(0 if success else 1)

24
test/run-tests.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
GODOT=${GODOT:-godot}
END_STRING="==== TESTS FINISHED ===="
FAILURE_STRING="******** FAILED ********"
OUTPUT=$($GODOT --path project --debug --headless --quit)
ERRCODE=$?
echo "$OUTPUT"
echo
if ! echo "$OUTPUT" | grep -e "$END_STRING" >/dev/null; then
echo "ERROR: Tests failed to complete"
exit 1
fi
if echo "$OUTPUT" | grep -e "$FAILURE_STRING" >/dev/null; then
exit 1
fi
# Success!
exit 0

View File

@ -13,27 +13,26 @@
using namespace godot;
int ExampleRef::instance_count = 0;
int ExampleRef::last_id = 0;
void ExampleRef::set_id(int p_id) {
id = p_id;
}
int ExampleRef::get_id() const {
return id;
}
void ExampleRef::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_id", "id"), &ExampleRef::set_id);
ClassDB::bind_method(D_METHOD("get_id"), &ExampleRef::get_id);
ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id");
}
ExampleRef::ExampleRef() {
id = ++last_id;
instance_count++;
UtilityFunctions::print("ExampleRef ", itos(id), " created, current instance count: ", itos(instance_count));
id = 0;
}
ExampleRef::~ExampleRef() {
instance_count--;
UtilityFunctions::print("ExampleRef ", itos(id), " destroyed, current instance count: ", itos(instance_count));
}
int Example::test_static(int p_a, int p_b) {
@ -41,7 +40,7 @@ int Example::test_static(int p_a, int p_b) {
}
void Example::test_static2() {
UtilityFunctions::print(" void static");
//UtilityFunctions::print(" void static");
}
int Example::def_args(int p_a, int p_b) {
@ -49,7 +48,7 @@ int Example::def_args(int p_a, int p_b) {
}
void Example::_notification(int p_what) {
UtilityFunctions::print("Notification: ", String::num(p_what));
//UtilityFunctions::print("Notification: ", String::num(p_what));
}
bool Example::_set(const StringName &p_name, const Variant &p_value) {
@ -112,6 +111,10 @@ void Example::_bind_methods() {
// Methods.
ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
ClassDB::bind_method(D_METHOD("simple_const_func"), &Example::simple_const_func);
ClassDB::bind_method(D_METHOD("custom_ref_func", "ref"), &Example::custom_ref_func);
ClassDB::bind_method(D_METHOD("custom_const_ref_func", "ref"), &Example::custom_const_ref_func);
ClassDB::bind_method(D_METHOD("image_ref_func", "image"), &Example::image_ref_func);
ClassDB::bind_method(D_METHOD("image_const_ref_func", "image"), &Example::image_const_ref_func);
ClassDB::bind_method(D_METHOD("return_something"), &Example::return_something);
ClassDB::bind_method(D_METHOD("return_something_const"), &Example::return_something_const);
ClassDB::bind_method(D_METHOD("return_empty_ref"), &Example::return_empty_ref);
@ -124,6 +127,7 @@ void Example::_bind_methods() {
ClassDB::bind_method(D_METHOD("test_dictionary"), &Example::test_dictionary);
ClassDB::bind_method(D_METHOD("test_node_argument"), &Example::test_node_argument);
ClassDB::bind_method(D_METHOD("test_string_ops"), &Example::test_string_ops);
ClassDB::bind_method(D_METHOD("test_str_utility"), &Example::test_str_utility);
ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_ops);
ClassDB::bind_method(D_METHOD("test_bitfield", "flags"), &Example::test_bitfield);
@ -179,29 +183,43 @@ void Example::_bind_methods() {
}
Example::Example() {
UtilityFunctions::print("Constructor.");
//UtilityFunctions::print("Constructor.");
}
Example::~Example() {
UtilityFunctions::print("Destructor.");
//UtilityFunctions::print("Destructor.");
}
// Methods.
void Example::simple_func() {
UtilityFunctions::print(" Simple func called.");
emit_custom_signal("simple_func", 3);
}
void Example::simple_const_func() const {
UtilityFunctions::print(" Simple const func called.");
((Example *)this)->emit_custom_signal("simple_const_func", 4);
}
int Example::custom_ref_func(Ref<ExampleRef> p_ref) {
return p_ref.is_valid() ? p_ref->get_id() : -1;
}
int Example::custom_const_ref_func(const Ref<ExampleRef> &p_ref) {
return p_ref.is_valid() ? p_ref->get_id() : -1;
}
String Example::image_ref_func(Ref<Image> p_image) {
return p_image.is_valid() ? String("valid") : String("invalid");
}
String Example::image_const_ref_func(const Ref<Image> &p_image) {
return p_image.is_valid() ? String("valid") : String("invalid");
}
String Example::return_something(const String &base) {
UtilityFunctions::print(" Return something called.");
return base;
return base + String("42");
}
Viewport *Example::return_something_const() const {
UtilityFunctions::print(" Return something const called.");
if (is_inside_tree()) {
Viewport *result = get_viewport();
return result;
@ -221,32 +239,23 @@ ExampleRef *Example::return_extended_ref() const {
return memnew(ExampleRef());
}
Example *Example::test_node_argument(Example *p_node) const {
UtilityFunctions::print(" Test node argument called with ", p_node ? String::num(p_node->get_instance_id()) : "null");
return p_node;
}
Ref<ExampleRef> Example::extended_ref_checks(Ref<ExampleRef> p_ref) const {
// This is therefor the prefered way of instancing and returning a refcounted object:
Ref<ExampleRef> ref;
ref.instantiate();
UtilityFunctions::print(" Example ref checks called with value: ", p_ref->get_instance_id(), ", returning value: ", ref->get_instance_id());
return ref;
}
Variant Example::varargs_func(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
UtilityFunctions::print(" Varargs (Variant return) called with ", String::num((double)arg_count), " arguments");
return arg_count;
}
int Example::varargs_func_nv(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
UtilityFunctions::print(" Varargs (int return) called with ", String::num((double)arg_count), " arguments");
return 42;
return 42 + arg_count;
}
void Example::varargs_func_void(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
UtilityFunctions::print(" Varargs (no return) called with ", String::num((double)arg_count), " arguments");
emit_custom_signal("varargs_func_void", arg_count + 1);
}
void Example::emit_custom_signal(const String &name, int value) {
@ -272,6 +281,10 @@ String Example::test_string_ops() const {
return s;
}
String Example::test_str_utility() const {
return UtilityFunctions::str("Hello, ", "World", "! The answer is ", 42);
}
int Example::test_vector_ops() const {
PackedInt32Array arr;
arr.push_back(10);
@ -285,10 +298,12 @@ int Example::test_vector_ops() const {
return ret;
}
void Example::test_tarray_arg(const TypedArray<int64_t> &p_array) {
int Example::test_tarray_arg(const TypedArray<int64_t> &p_array) {
int sum = 0;
for (int i = 0; i < p_array.size(); i++) {
UtilityFunctions::print(p_array[i]);
sum += (int)p_array[i];
}
return sum;
}
TypedArray<Vector2> Example::test_tarray() const {
@ -310,8 +325,11 @@ Dictionary Example::test_dictionary() const {
return dict;
}
Example *Example::test_node_argument(Example *p_node) const {
return p_node;
}
BitField<Example::Flags> Example::test_bitfield(BitField<Flags> flags) {
UtilityFunctions::print(" Got BitField: ", String::num_int64(flags));
return flags;
}
@ -335,3 +353,10 @@ bool Example::_has_point(const Vector2 &point) const {
return false;
}
void Example::_input(const Ref<InputEvent> &event) {
const InputEventKey *key_event = Object::cast_to<const InputEventKey>(*event);
if (key_event) {
emit_custom_signal(String("_input: ") + key_event->get_key_label(), key_event->get_unicode());
}
}

View File

@ -16,6 +16,8 @@
#include <godot_cpp/classes/control.hpp>
#include <godot_cpp/classes/global_constants.hpp>
#include <godot_cpp/classes/image.hpp>
#include <godot_cpp/classes/input_event_key.hpp>
#include <godot_cpp/classes/viewport.hpp>
#include <godot_cpp/core/binder_common.hpp>
@ -38,6 +40,7 @@ public:
ExampleRef();
~ExampleRef();
void set_id(int p_id);
int get_id() const;
};
@ -90,8 +93,13 @@ public:
// Functions.
void simple_func();
void simple_const_func() const;
int custom_ref_func(Ref<ExampleRef> p_ref);
int custom_const_ref_func(const Ref<ExampleRef> &p_ref);
String image_ref_func(Ref<Image> p_image);
String image_const_ref_func(const Ref<Image> &p_image);
String return_something(const String &base);
Viewport *return_something_const() const;
Ref<ExampleRef> return_ref() const;
Ref<ExampleRef> return_empty_ref() const;
ExampleRef *return_extended_ref() const;
Ref<ExampleRef> extended_ref_checks(Ref<ExampleRef> p_ref) const;
@ -102,11 +110,12 @@ public:
int def_args(int p_a = 100, int p_b = 200);
Array test_array() const;
void test_tarray_arg(const TypedArray<int64_t> &p_array);
int test_tarray_arg(const TypedArray<int64_t> &p_array);
TypedArray<Vector2> test_tarray() const;
Dictionary test_dictionary() const;
Example *test_node_argument(Example *p_node) const;
String test_string_ops() const;
String test_str_utility() const;
int test_vector_ops() const;
BitField<Flags> test_bitfield(BitField<Flags> flags);
@ -122,6 +131,7 @@ public:
// Virtual function override (no need to bind manually).
virtual bool _has_point(const Vector2 &point) const override;
virtual void _input(const Ref<InputEvent> &event) override;
};
VARIANT_ENUM_CAST(Example::Constants);

View File

@ -36,8 +36,8 @@ void uninitialize_example_module(ModuleInitializationLevel p_level) {
extern "C" {
// Initialization.
GDExtensionBool GDE_EXPORT example_library_init(const GDExtensionInterface *p_interface, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
godot::GDExtensionBinding::InitObject init_obj(p_interface, p_library, r_initialization);
GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
init_obj.register_initializer(initialize_example_module);
init_obj.register_terminator(uninitialize_example_module);