mirror of
https://github.com/godotengine/godot-cpp.git
synced 2026-01-03 18:09:13 +03:00
Compare commits
206 Commits
godot-4.1.
...
godot-4.2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98c143a483 | ||
|
|
28d43fb99a | ||
|
|
77f1d228cd | ||
|
|
ab5b9f2ceb | ||
|
|
ef4d771444 | ||
|
|
66ced64c1e | ||
|
|
fc5366c026 | ||
|
|
7e5fa8e7a9 | ||
|
|
f8477fb9f2 | ||
|
|
ef723ca9ec | ||
|
|
7473b984cb | ||
|
|
98ad839827 | ||
|
|
a07b1f6e07 | ||
|
|
f002ca18c7 | ||
|
|
3fe7c2e87b | ||
|
|
7ddd278dea | ||
|
|
cae4bf58ac | ||
|
|
1517a24f72 | ||
|
|
1b8cfaab71 | ||
|
|
dc19986497 | ||
|
|
c2d4ccd592 | ||
|
|
51c752c46b | ||
|
|
45dc04f2cf | ||
|
|
dc76664cea | ||
|
|
97214ecd7a | ||
|
|
300e74364b | ||
|
|
3129672a4f | ||
|
|
c0b2d85ffc | ||
|
|
62eed50524 | ||
|
|
f9b66e3c72 | ||
|
|
81a72ff06b | ||
|
|
0472b6bdd4 | ||
|
|
aaffda23a5 | ||
|
|
78ffea5b13 | ||
|
|
f93a6c5a5b | ||
|
|
b03e56922d | ||
|
|
54136ee835 | ||
|
|
0f78fc45bd | ||
|
|
11b2700b23 | ||
|
|
20c4e843b0 | ||
|
|
f3143c7a9c | ||
|
|
943d1c8cdf | ||
|
|
588d869a3b | ||
|
|
5be275d73b | ||
|
|
4fed88afcf | ||
|
|
7fb8acaa53 | ||
|
|
2f16eddf15 | ||
|
|
adc9def046 | ||
|
|
32409472b7 | ||
|
|
79d2a9c456 | ||
|
|
d0fdc3adf3 | ||
|
|
78bf5a42ed | ||
|
|
f5e4f95cde | ||
|
|
6fd4e151b8 | ||
|
|
e854e0b592 | ||
|
|
fa10d1a303 | ||
|
|
eea33b4133 | ||
|
|
7cd79e4cc6 | ||
|
|
8d17966e81 | ||
|
|
f426b12b5b | ||
|
|
4439a4a569 | ||
|
|
c4b7b08c91 | ||
|
|
9d528c30ee | ||
|
|
3d22ab88a3 | ||
|
|
5deb29b283 | ||
|
|
c51c5425ba | ||
|
|
306774b5a4 | ||
|
|
39c139c814 | ||
|
|
73757e3a9f | ||
|
|
adb0cfc59c | ||
|
|
29b34d92bb | ||
|
|
cc89bd2132 | ||
|
|
4af46132c2 | ||
|
|
bcac96c8c2 | ||
|
|
d239312e7b | ||
|
|
59392bc1fa | ||
|
|
92dd34ae96 | ||
|
|
648b8c4489 | ||
|
|
d33bd47219 | ||
|
|
2dfe7929de | ||
|
|
93260e1700 | ||
|
|
e4eee8b12d | ||
|
|
86dbd5fa0d | ||
|
|
6eb5d450bd | ||
|
|
db884e9b1d | ||
|
|
c1196a1ab0 | ||
|
|
4b76485a4e | ||
|
|
f79bd795d5 | ||
|
|
1ab94699c5 | ||
|
|
c82f2a3714 | ||
|
|
edb52293d9 | ||
|
|
379ce2b5e5 | ||
|
|
a61cdc8860 | ||
|
|
bf1c03ab5f | ||
|
|
421c61e730 | ||
|
|
d733663e8b | ||
|
|
0a6a19e33b | ||
|
|
5182624141 | ||
|
|
7a260f5e93 | ||
|
|
2d5024ac8e | ||
|
|
7a3cfe8089 | ||
|
|
5c4a7dc7b2 | ||
|
|
a926b96103 | ||
|
|
7a5cbcac21 | ||
|
|
64eac01d04 | ||
|
|
b507b3e591 | ||
|
|
4320c62c76 | ||
|
|
18bfa133ab | ||
|
|
c4d3f019da | ||
|
|
4f0eb2f520 | ||
|
|
292a50dd08 | ||
|
|
6e05b978b8 | ||
|
|
55618ebf58 | ||
|
|
29248c31ae | ||
|
|
3d814f9e4a | ||
|
|
ef2f63a00c | ||
|
|
5134c82573 | ||
|
|
cd61a9bbe8 | ||
|
|
96bec613a0 | ||
|
|
6ad187cc7e | ||
|
|
98737b2678 | ||
|
|
0369f6fea0 | ||
|
|
2b4bcbb0ce | ||
|
|
bf2f9e2f55 | ||
|
|
df849651d9 | ||
|
|
60dfa3445a | ||
|
|
c44c3d5ebf | ||
|
|
c18c1916c3 | ||
|
|
4314f91b7d | ||
|
|
db15731e4d | ||
|
|
381df0081a | ||
|
|
a963b8b7c7 | ||
|
|
3a02feddc3 | ||
|
|
a3dfbbde85 | ||
|
|
b1fd1b65fd | ||
|
|
52ca3ef547 | ||
|
|
0d6de7a80e | ||
|
|
06ffc7e952 | ||
|
|
73500966ae | ||
|
|
634ed09ec0 | ||
|
|
1e5767693e | ||
|
|
6caf4909d4 | ||
|
|
aa6867e6c9 | ||
|
|
16ffb2795a | ||
|
|
ca3e25de04 | ||
|
|
b488f009bd | ||
|
|
80f98de905 | ||
|
|
0e5975dd26 | ||
|
|
5cdc2fc099 | ||
|
|
adcc95534b | ||
|
|
82e960a810 | ||
|
|
f651df5e7a | ||
|
|
5d4ff63930 | ||
|
|
982e01ec7f | ||
|
|
2d1f852baf | ||
|
|
0db95a92a6 | ||
|
|
8990d5a40e | ||
|
|
54092861f1 | ||
|
|
9ada7065d6 | ||
|
|
b3596a18e1 | ||
|
|
9a6c741d5d | ||
|
|
c2d99fd519 | ||
|
|
dd9586b841 | ||
|
|
f8b4f60cb9 | ||
|
|
6d9416eb17 | ||
|
|
f0405f18a3 | ||
|
|
c370f0f24a | ||
|
|
1588dc8437 | ||
|
|
a7d3f00b26 | ||
|
|
e586e11637 | ||
|
|
7ed7a84782 | ||
|
|
112e41bd8f | ||
|
|
52eb77efd4 | ||
|
|
74b352e979 | ||
|
|
f5c8e5190f | ||
|
|
524bbd3ee9 | ||
|
|
3cd3f24150 | ||
|
|
5c262844ad | ||
|
|
df5500565a | ||
|
|
d5fab0b9f8 | ||
|
|
fecb2959b4 | ||
|
|
5eebc6b20c | ||
|
|
600e749d9b | ||
|
|
c47bd60c73 | ||
|
|
a745c2ac47 | ||
|
|
5834e16a22 | ||
|
|
6f913563d8 | ||
|
|
845226d66a | ||
|
|
d168dd021e | ||
|
|
494b51698d | ||
|
|
8bc1c1dbeb | ||
|
|
c5d8447861 | ||
|
|
c6b2c82570 | ||
|
|
1d49bef096 | ||
|
|
d15550fdee | ||
|
|
baf0b9e0f7 | ||
|
|
7d8cb7c155 | ||
|
|
9d9f4279ed | ||
|
|
6d195137fe | ||
|
|
2586ad016e | ||
|
|
548c758677 | ||
|
|
3162be28e5 | ||
|
|
ef5a185dc4 | ||
|
|
efc16b49d9 | ||
|
|
3536803e9e | ||
|
|
4df112cd95 |
@@ -103,7 +103,7 @@ endif()
|
||||
|
||||
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
|
||||
# saves around 20% of binary size and very significant build time (GH-80513).
|
||||
option(GODOT_DISABLE_EXCEPTIONS OFF "Force disabling exception handling code")
|
||||
option(GODOT_DISABLE_EXCEPTIONS ON "Force disabling exception handling code")
|
||||
if (GODOT_DISABLE_EXCEPTIONS)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -D_HAS_EXCEPTIONS=0")
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
> from Godot's `master` branch.
|
||||
>
|
||||
> For users of stable branches, switch to the branch matching your target Godot version:
|
||||
> - [`4.0`](https://github.com/godotengine/godot-cpp/tree/4.0)
|
||||
> - [`4.2`](https://github.com/godotengine/godot-cpp/tree/4.2)
|
||||
> - [`4.1`](https://github.com/godotengine/godot-cpp/tree/4.1)
|
||||
> - [`4.0`](https://github.com/godotengine/godot-cpp/tree/4.0)
|
||||
>
|
||||
> Or check out the Git tag matching your Godot version (e.g. `godot-4.1.1-stable`).
|
||||
>
|
||||
|
||||
@@ -110,6 +110,8 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
||||
|
||||
for native_struct in api["native_structures"]:
|
||||
struct_name = native_struct["name"]
|
||||
if struct_name == "ObjectID":
|
||||
continue
|
||||
snake_struct_name = camel_to_snake(struct_name)
|
||||
|
||||
header_filename = include_gen_folder / "classes" / (snake_struct_name + ".hpp")
|
||||
@@ -122,6 +124,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
||||
include_gen_folder / "variant" / "builtin_binds.hpp",
|
||||
include_gen_folder / "variant" / "utility_functions.hpp",
|
||||
include_gen_folder / "variant" / "variant_size.hpp",
|
||||
include_gen_folder / "variant" / "builtin_vararg_methods.hpp",
|
||||
include_gen_folder / "classes" / "global_constants.hpp",
|
||||
include_gen_folder / "classes" / "global_constants_binds.hpp",
|
||||
include_gen_folder / "core" / "version.hpp",
|
||||
@@ -343,6 +346,40 @@ def generate_builtin_bindings(api, output_dir, build_config):
|
||||
|
||||
builtin_binds_file.write("\n".join(builtin_binds))
|
||||
|
||||
# Create a header to implement all builtin class vararg methods and be included in "variant.hpp".
|
||||
builtin_vararg_methods_header = include_gen_folder / "builtin_vararg_methods.hpp"
|
||||
builtin_vararg_methods_header.open("w+").write(
|
||||
generate_builtin_class_vararg_method_implements_header(api["builtin_classes"])
|
||||
)
|
||||
|
||||
|
||||
def generate_builtin_class_vararg_method_implements_header(builtin_classes):
|
||||
result = []
|
||||
|
||||
add_header("builtin_vararg_methods.hpp", result)
|
||||
|
||||
header_guard = "GODOT_CPP_BUILTIN_VARARG_METHODS_HPP"
|
||||
result.append(f"#ifndef {header_guard}")
|
||||
result.append(f"#define {header_guard}")
|
||||
result.append("")
|
||||
for builtin_api in builtin_classes:
|
||||
if not "methods" in builtin_api:
|
||||
continue
|
||||
class_name = builtin_api["name"]
|
||||
for method in builtin_api["methods"]:
|
||||
if not method["is_vararg"]:
|
||||
continue
|
||||
|
||||
result += make_varargs_template(
|
||||
method, "is_static" in method and method["is_static"], class_name, False, False, True
|
||||
)
|
||||
result.append("")
|
||||
|
||||
result.append("")
|
||||
result.append(f"#endif // ! {header_guard}")
|
||||
|
||||
return "\n".join(result)
|
||||
|
||||
|
||||
def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_classes):
|
||||
result = []
|
||||
@@ -365,6 +402,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
if class_name == "String":
|
||||
result.append("#include <godot_cpp/variant/char_string.hpp>")
|
||||
result.append("#include <godot_cpp/variant/char_utils.hpp>")
|
||||
result.append("#include <godot_cpp/classes/global_constants.hpp>")
|
||||
|
||||
if class_name == "PackedStringArray":
|
||||
result.append("#include <godot_cpp/variant/string.hpp>")
|
||||
@@ -382,6 +420,9 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
if class_name == "Array":
|
||||
result.append("#include <godot_cpp/variant/array_helpers.hpp>")
|
||||
|
||||
if class_name == "Callable":
|
||||
result.append("#include <godot_cpp/variant/callable_custom.hpp>")
|
||||
|
||||
for include in fully_used_classes:
|
||||
if include == "TypedArray":
|
||||
result.append("#include <godot_cpp/variant/typed_array.hpp>")
|
||||
@@ -489,10 +530,16 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
|
||||
# Special cases.
|
||||
if class_name == "String" or class_name == "StringName" or class_name == "NodePath":
|
||||
result.append(f"\t{class_name}(const char *from);")
|
||||
if class_name == "StringName":
|
||||
result.append(f"\t{class_name}(const char *from, bool p_static = false);")
|
||||
else:
|
||||
result.append(f"\t{class_name}(const char *from);")
|
||||
result.append(f"\t{class_name}(const wchar_t *from);")
|
||||
result.append(f"\t{class_name}(const char16_t *from);")
|
||||
result.append(f"\t{class_name}(const char32_t *from);")
|
||||
if class_name == "Callable":
|
||||
result.append("\tCallable(CallableCustom *p_custom);")
|
||||
result.append("\tCallableCustom *get_custom() const;")
|
||||
|
||||
if "constants" in builtin_api:
|
||||
axis_constants_count = 0
|
||||
@@ -560,6 +607,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
result.append("\tChar32String utf32() const;")
|
||||
result.append("\tCharWideString wide_string() const;")
|
||||
result.append("\tstatic String num_real(double p_num, bool p_trailing = true);")
|
||||
result.append("\tError resize(int64_t p_size);")
|
||||
|
||||
if "members" in builtin_api:
|
||||
for member in builtin_api["members"]:
|
||||
@@ -1084,6 +1132,8 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
|
||||
class_api["alias_for"] = "ClassDB"
|
||||
engine_classes[class_api["name"]] = class_api["is_refcounted"]
|
||||
for native_struct in api["native_structures"]:
|
||||
if native_struct["name"] == "ObjectID":
|
||||
continue
|
||||
engine_classes[native_struct["name"]] = False
|
||||
native_structures.append(native_struct["name"])
|
||||
|
||||
@@ -1211,6 +1261,8 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
|
||||
|
||||
for native_struct in api["native_structures"]:
|
||||
struct_name = native_struct["name"]
|
||||
if struct_name == "ObjectID":
|
||||
continue
|
||||
snake_struct_name = camel_to_snake(struct_name)
|
||||
|
||||
header_filename = include_gen_folder / (snake_struct_name + ".hpp")
|
||||
@@ -1320,7 +1372,11 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
|
||||
if "enums" in class_api:
|
||||
for enum_api in class_api["enums"]:
|
||||
result.append(f'\tenum {enum_api["name"]} {{')
|
||||
if enum_api["is_bitfield"]:
|
||||
result.append(f'\tenum {enum_api["name"]} : uint64_t {{')
|
||||
else:
|
||||
result.append(f'\tenum {enum_api["name"]} {{')
|
||||
|
||||
for value in enum_api["values"]:
|
||||
result.append(f'\t\t{value["name"]} = {value["value"]},')
|
||||
result.append("\t};")
|
||||
@@ -1677,6 +1733,8 @@ def generate_global_constants(api, output_dir):
|
||||
header.append(f"#ifndef {header_guard}")
|
||||
header.append(f"#define {header_guard}")
|
||||
header.append("")
|
||||
header.append("#include <cstdint>")
|
||||
header.append("")
|
||||
header.append("namespace godot {")
|
||||
header.append("")
|
||||
|
||||
@@ -1689,7 +1747,11 @@ def generate_global_constants(api, output_dir):
|
||||
if enum_def["name"].startswith("Variant."):
|
||||
continue
|
||||
|
||||
header.append(f'\tenum {enum_def["name"]} {{')
|
||||
if enum_def["is_bitfield"]:
|
||||
header.append(f'\tenum {enum_def["name"]} : uint64_t {{')
|
||||
else:
|
||||
header.append(f'\tenum {enum_def["name"]} {{')
|
||||
|
||||
for value in enum_def["values"]:
|
||||
header.append(f'\t\t{value["name"]} = {value["value"]},')
|
||||
header.append("\t};")
|
||||
@@ -2039,10 +2101,22 @@ def make_signature(
|
||||
return function_signature
|
||||
|
||||
|
||||
def make_varargs_template(function_data, static=False):
|
||||
def make_varargs_template(
|
||||
function_data,
|
||||
static=False,
|
||||
class_befor_signature="",
|
||||
with_public_declare=True,
|
||||
with_indent=True,
|
||||
for_builtin_classes=False,
|
||||
):
|
||||
result = []
|
||||
|
||||
function_signature = "\tpublic: template<typename... Args> "
|
||||
function_signature = ""
|
||||
|
||||
if with_public_declare:
|
||||
function_signature = "public: "
|
||||
|
||||
function_signature += "template<typename... Args> "
|
||||
|
||||
if static:
|
||||
function_signature += "static "
|
||||
@@ -2063,6 +2137,8 @@ def make_varargs_template(function_data, static=False):
|
||||
if not function_signature.endswith("*"):
|
||||
function_signature += " "
|
||||
|
||||
if len(class_befor_signature) > 0:
|
||||
function_signature += class_befor_signature + "::"
|
||||
function_signature += f'{escape_identifier(function_data["name"])}'
|
||||
|
||||
method_arguments = []
|
||||
@@ -2083,7 +2159,7 @@ def make_varargs_template(function_data, static=False):
|
||||
function_signature += " {"
|
||||
result.append(function_signature)
|
||||
|
||||
args_array = f"\t\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args {{ "
|
||||
args_array = f"\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args {{ "
|
||||
for argument in method_arguments:
|
||||
if argument["type"] == "Variant":
|
||||
args_array += argument["name"]
|
||||
@@ -2093,20 +2169,43 @@ def make_varargs_template(function_data, static=False):
|
||||
|
||||
args_array += "Variant(args)... };"
|
||||
result.append(args_array)
|
||||
result.append(f"\t\tstd::array<const Variant *, {len(method_arguments)} + sizeof...(Args)> call_args;")
|
||||
result.append("\t\tfor(size_t i = 0; i < variant_args.size(); i++) {")
|
||||
result.append("\t\t\tcall_args[i] = &variant_args[i];")
|
||||
result.append("\t\t}")
|
||||
|
||||
call_line = "\t\t"
|
||||
|
||||
if return_type != "void":
|
||||
call_line += "return "
|
||||
|
||||
call_line += f'{escape_identifier(function_data["name"])}_internal(call_args.data(), variant_args.size());'
|
||||
result.append(call_line)
|
||||
result.append(f"\tstd::array<const Variant *, {len(method_arguments)} + sizeof...(Args)> call_args;")
|
||||
result.append("\tfor(size_t i = 0; i < variant_args.size(); i++) {")
|
||||
result.append("\t\tcall_args[i] = &variant_args[i];")
|
||||
result.append("\t}")
|
||||
|
||||
call_line = "\t"
|
||||
|
||||
if not for_builtin_classes:
|
||||
if return_type != "void":
|
||||
call_line += "return "
|
||||
|
||||
call_line += f'{escape_identifier(function_data["name"])}_internal(call_args.data(), variant_args.size());'
|
||||
result.append(call_line)
|
||||
else:
|
||||
base = "(GDExtensionTypePtr)&opaque"
|
||||
if static:
|
||||
base = "nullptr"
|
||||
|
||||
ret = "nullptr"
|
||||
if return_type != "void":
|
||||
ret = "&ret"
|
||||
result.append(f'\t{correct_type(function_data["return_type"])} ret;')
|
||||
|
||||
function_name = function_data["name"]
|
||||
result.append(
|
||||
f"\t_method_bindings.method_{function_name}({base}, reinterpret_cast<GDExtensionConstTypePtr *>(call_args.data()), {ret}, {len(method_arguments)} + sizeof...(Args));"
|
||||
)
|
||||
|
||||
if return_type != "void":
|
||||
result.append("\treturn ret;")
|
||||
|
||||
result.append("}")
|
||||
|
||||
if with_indent:
|
||||
for i in range(len(result)):
|
||||
result[i] = "\t" + result[i]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -258,14 +258,19 @@ typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExte
|
||||
typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list);
|
||||
typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name);
|
||||
typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
|
||||
typedef void (*GDExtensionClassNotification)(GDExtensionClassInstancePtr p_instance, int32_t p_what);
|
||||
typedef GDExtensionBool (*GDExtensionClassValidateProperty)(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property);
|
||||
typedef void (*GDExtensionClassNotification)(GDExtensionClassInstancePtr p_instance, int32_t p_what); // Deprecated. Use GDExtensionClassNotification2 instead.
|
||||
typedef void (*GDExtensionClassNotification2)(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed);
|
||||
typedef void (*GDExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr p_out);
|
||||
typedef void (*GDExtensionClassReference)(GDExtensionClassInstancePtr p_instance);
|
||||
typedef void (*GDExtensionClassUnreference)(GDExtensionClassInstancePtr p_instance);
|
||||
typedef void (*GDExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret);
|
||||
typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance)(void *p_userdata);
|
||||
typedef void (*GDExtensionClassFreeInstance)(void *p_userdata, GDExtensionClassInstancePtr p_instance);
|
||||
typedef GDExtensionClassCallVirtual (*GDExtensionClassGetVirtual)(void *p_userdata, GDExtensionConstStringNamePtr p_name);
|
||||
typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance)(void *p_class_userdata);
|
||||
typedef void (*GDExtensionClassFreeInstance)(void *p_class_userdata, GDExtensionClassInstancePtr p_instance);
|
||||
typedef GDExtensionClassInstancePtr (*GDExtensionClassRecreateInstance)(void *p_class_userdata, GDExtensionObjectPtr p_object);
|
||||
typedef GDExtensionClassCallVirtual (*GDExtensionClassGetVirtual)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name);
|
||||
typedef void *(*GDExtensionClassGetVirtualCallData)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name);
|
||||
typedef void (*GDExtensionClassCallVirtualWithData)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, void *p_virtual_call_userdata, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret);
|
||||
|
||||
typedef struct {
|
||||
GDExtensionBool is_virtual;
|
||||
@@ -285,7 +290,40 @@ typedef struct {
|
||||
GDExtensionClassGetVirtual get_virtual_func; // Queries a virtual function by name and returns a callback to invoke the requested virtual function.
|
||||
GDExtensionClassGetRID get_rid_func;
|
||||
void *class_userdata; // Per-class user data, later accessible in instance bindings.
|
||||
} GDExtensionClassCreationInfo;
|
||||
} GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo2 instead.
|
||||
|
||||
typedef struct {
|
||||
GDExtensionBool is_virtual;
|
||||
GDExtensionBool is_abstract;
|
||||
GDExtensionBool is_exposed;
|
||||
GDExtensionClassSet set_func;
|
||||
GDExtensionClassGet get_func;
|
||||
GDExtensionClassGetPropertyList get_property_list_func;
|
||||
GDExtensionClassFreePropertyList free_property_list_func;
|
||||
GDExtensionClassPropertyCanRevert property_can_revert_func;
|
||||
GDExtensionClassPropertyGetRevert property_get_revert_func;
|
||||
GDExtensionClassValidateProperty validate_property_func;
|
||||
GDExtensionClassNotification2 notification_func;
|
||||
GDExtensionClassToString to_string_func;
|
||||
GDExtensionClassReference reference_func;
|
||||
GDExtensionClassUnreference unreference_func;
|
||||
GDExtensionClassCreateInstance create_instance_func; // (Default) constructor; mandatory. If the class is not instantiable, consider making it virtual or abstract.
|
||||
GDExtensionClassFreeInstance free_instance_func; // Destructor; mandatory.
|
||||
GDExtensionClassRecreateInstance recreate_instance_func;
|
||||
// Queries a virtual function by name and returns a callback to invoke the requested virtual function.
|
||||
GDExtensionClassGetVirtual get_virtual_func;
|
||||
// Paired with `call_virtual_with_data_func`, this is an alternative to `get_virtual_func` for extensions that
|
||||
// need or benefit from extra data when calling virtual functions.
|
||||
// Returns user data that will be passed to `call_virtual_with_data_func`.
|
||||
// Returning `NULL` from this function signals to Godot that the virtual function is not overridden.
|
||||
// Data returned from this function should be managed by the extension and must be valid until the extension is deinitialized.
|
||||
// You should supply either `get_virtual_func`, or `get_virtual_call_data_func` with `call_virtual_with_data_func`.
|
||||
GDExtensionClassGetVirtualCallData get_virtual_call_data_func;
|
||||
// Used to call virtual functions when `get_virtual_call_data_func` is not null.
|
||||
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
|
||||
GDExtensionClassGetRID get_rid_func;
|
||||
void *class_userdata; // Per-class user data, later accessible in instance bindings.
|
||||
} GDExtensionClassCreationInfo2;
|
||||
|
||||
typedef void *GDExtensionClassLibraryPtr;
|
||||
|
||||
@@ -343,6 +381,47 @@ typedef struct {
|
||||
GDExtensionVariantPtr *default_arguments;
|
||||
} GDExtensionClassMethodInfo;
|
||||
|
||||
typedef void (*GDExtensionCallableCustomCall)(void *callable_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
|
||||
typedef GDExtensionBool (*GDExtensionCallableCustomIsValid)(void *callable_userdata);
|
||||
typedef void (*GDExtensionCallableCustomFree)(void *callable_userdata);
|
||||
|
||||
typedef uint32_t (*GDExtensionCallableCustomHash)(void *callable_userdata);
|
||||
typedef GDExtensionBool (*GDExtensionCallableCustomEqual)(void *callable_userdata_a, void *callable_userdata_b);
|
||||
typedef GDExtensionBool (*GDExtensionCallableCustomLessThan)(void *callable_userdata_a, void *callable_userdata_b);
|
||||
|
||||
typedef void (*GDExtensionCallableCustomToString)(void *callable_userdata, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out);
|
||||
|
||||
typedef struct {
|
||||
/* Only `call_func` and `token` are strictly required, however, `object_id` should be passed if its not a static method.
|
||||
*
|
||||
* `token` should point to an address that uniquely identifies the GDExtension (for example, the
|
||||
* `GDExtensionClassLibraryPtr` passed to the entry symbol function.
|
||||
*
|
||||
* `hash_func`, `equal_func`, and `less_than_func` are optional. If not provided both `call_func` and
|
||||
* `callable_userdata` together are used as the identity of the callable for hashing and comparison purposes.
|
||||
*
|
||||
* The hash returned by `hash_func` is cached, `hash_func` will not be called more than once per callable.
|
||||
*
|
||||
* `is_valid_func` is necessary if the validity of the callable can change before destruction.
|
||||
*
|
||||
* `free_func` is necessary if `callable_userdata` needs to be cleaned up when the callable is freed.
|
||||
*/
|
||||
void *callable_userdata;
|
||||
void *token;
|
||||
|
||||
GDObjectInstanceID object_id;
|
||||
|
||||
GDExtensionCallableCustomCall call_func;
|
||||
GDExtensionCallableCustomIsValid is_valid_func;
|
||||
GDExtensionCallableCustomFree free_func;
|
||||
|
||||
GDExtensionCallableCustomHash hash_func;
|
||||
GDExtensionCallableCustomEqual equal_func;
|
||||
GDExtensionCallableCustomLessThan less_than_func;
|
||||
|
||||
GDExtensionCallableCustomToString to_string_func;
|
||||
} GDExtensionCallableCustomInfo;
|
||||
|
||||
/* SCRIPT INSTANCE EXTENSION */
|
||||
|
||||
typedef void *GDExtensionScriptInstanceDataPtr; // Pointer to custom ScriptInstance native implementation.
|
||||
@@ -351,7 +430,10 @@ typedef GDExtensionBool (*GDExtensionScriptInstanceSet)(GDExtensionScriptInstanc
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceGet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
|
||||
typedef const GDExtensionPropertyInfo *(*GDExtensionScriptInstanceGetPropertyList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
|
||||
typedef void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list);
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceGetClassCategory)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionPropertyInfo *p_class_category);
|
||||
|
||||
typedef GDExtensionVariantType (*GDExtensionScriptInstanceGetPropertyType)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceValidateProperty)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionPropertyInfo *p_property);
|
||||
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyCanRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyGetRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
|
||||
@@ -366,7 +448,8 @@ typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanc
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceHasMethod)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
|
||||
|
||||
typedef void (*GDExtensionScriptInstanceCall)(GDExtensionScriptInstanceDataPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
|
||||
typedef void (*GDExtensionScriptInstanceNotification)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what);
|
||||
typedef void (*GDExtensionScriptInstanceNotification)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what); // Deprecated. Use GDExtensionScriptInstanceNotification2 instead.
|
||||
typedef void (*GDExtensionScriptInstanceNotification2)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what, GDExtensionBool p_reversed);
|
||||
typedef void (*GDExtensionScriptInstanceToString)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out);
|
||||
|
||||
typedef void (*GDExtensionScriptInstanceRefCountIncremented)(GDExtensionScriptInstanceDataPtr p_instance);
|
||||
@@ -420,7 +503,48 @@ typedef struct {
|
||||
|
||||
GDExtensionScriptInstanceFree free_func;
|
||||
|
||||
} GDExtensionScriptInstanceInfo;
|
||||
} GDExtensionScriptInstanceInfo; // Deprecated. Use GDExtensionScriptInstanceInfo2 instead.
|
||||
|
||||
typedef struct {
|
||||
GDExtensionScriptInstanceSet set_func;
|
||||
GDExtensionScriptInstanceGet get_func;
|
||||
GDExtensionScriptInstanceGetPropertyList get_property_list_func;
|
||||
GDExtensionScriptInstanceFreePropertyList free_property_list_func;
|
||||
GDExtensionScriptInstanceGetClassCategory get_class_category_func; // Optional. Set to NULL for the default behavior.
|
||||
|
||||
GDExtensionScriptInstancePropertyCanRevert property_can_revert_func;
|
||||
GDExtensionScriptInstancePropertyGetRevert property_get_revert_func;
|
||||
|
||||
GDExtensionScriptInstanceGetOwner get_owner_func;
|
||||
GDExtensionScriptInstanceGetPropertyState get_property_state_func;
|
||||
|
||||
GDExtensionScriptInstanceGetMethodList get_method_list_func;
|
||||
GDExtensionScriptInstanceFreeMethodList free_method_list_func;
|
||||
GDExtensionScriptInstanceGetPropertyType get_property_type_func;
|
||||
GDExtensionScriptInstanceValidateProperty validate_property_func;
|
||||
|
||||
GDExtensionScriptInstanceHasMethod has_method_func;
|
||||
|
||||
GDExtensionScriptInstanceCall call_func;
|
||||
GDExtensionScriptInstanceNotification2 notification_func;
|
||||
|
||||
GDExtensionScriptInstanceToString to_string_func;
|
||||
|
||||
GDExtensionScriptInstanceRefCountIncremented refcount_incremented_func;
|
||||
GDExtensionScriptInstanceRefCountDecremented refcount_decremented_func;
|
||||
|
||||
GDExtensionScriptInstanceGetScript get_script_func;
|
||||
|
||||
GDExtensionScriptInstanceIsPlaceholder is_placeholder_func;
|
||||
|
||||
GDExtensionScriptInstanceSet set_fallback_func;
|
||||
GDExtensionScriptInstanceGet get_fallback_func;
|
||||
|
||||
GDExtensionScriptInstanceGetLanguage get_language_func;
|
||||
|
||||
GDExtensionScriptInstanceFree free_func;
|
||||
|
||||
} GDExtensionScriptInstanceInfo2;
|
||||
|
||||
/* INITIALIZATION */
|
||||
|
||||
@@ -466,7 +590,10 @@ typedef GDExtensionInterfaceFunctionPtr (*GDExtensionInterfaceGetProcAddress)(co
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* GDExtensionInterfaceGetGodotVersion *get_godot_version = (GDExtensionInterfaceGetGodotVersion)p_get_proc_address("get_godot_version");
|
||||
* GDExtensionInterfaceGetGodotVersion get_godot_version = (GDExtensionInterfaceGetGodotVersion)p_get_proc_address("get_godot_version");
|
||||
*
|
||||
* (Note that snippet may cause "cast between incompatible function types" on some compilers, you can
|
||||
* silence this by adding an intermediary `void*` cast.)
|
||||
*
|
||||
* You can then call it like a normal function:
|
||||
*
|
||||
@@ -1313,7 +1440,7 @@ typedef void (*GDExtensionInterfaceStringNewWithWideChars)(GDExtensionUninitiali
|
||||
*
|
||||
* @param r_dest A pointer to a Variant to hold the newly created String.
|
||||
* @param p_contents A pointer to a Latin-1 encoded C string.
|
||||
* @param p_size The number of characters.
|
||||
* @param p_size The number of characters (= number of bytes).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNewWithLatin1CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size);
|
||||
|
||||
@@ -1325,7 +1452,7 @@ typedef void (*GDExtensionInterfaceStringNewWithLatin1CharsAndLen)(GDExtensionUn
|
||||
*
|
||||
* @param r_dest A pointer to a Variant to hold the newly created String.
|
||||
* @param p_contents A pointer to a UTF-8 encoded C string.
|
||||
* @param p_size The number of characters.
|
||||
* @param p_size The number of bytes (not code units).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size);
|
||||
|
||||
@@ -1337,9 +1464,9 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen)(GDExtensionUnin
|
||||
*
|
||||
* @param r_dest A pointer to a Variant to hold the newly created String.
|
||||
* @param p_contents A pointer to a UTF-16 encoded C string.
|
||||
* @param p_size The number of characters.
|
||||
* @param p_size The number of characters (not bytes).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_size);
|
||||
typedef void (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count);
|
||||
|
||||
/**
|
||||
* @name string_new_with_utf32_chars_and_len
|
||||
@@ -1349,9 +1476,9 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen)(GDExtensionUni
|
||||
*
|
||||
* @param r_dest A pointer to a Variant to hold the newly created String.
|
||||
* @param p_contents A pointer to a UTF-32 encoded C string.
|
||||
* @param p_size The number of characters.
|
||||
* @param p_size The number of characters (not bytes).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNewWithUtf32CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_size);
|
||||
typedef void (*GDExtensionInterfaceStringNewWithUtf32CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_char_count);
|
||||
|
||||
/**
|
||||
* @name string_new_with_wide_chars_and_len
|
||||
@@ -1361,9 +1488,9 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf32CharsAndLen)(GDExtensionUni
|
||||
*
|
||||
* @param r_dest A pointer to a Variant to hold the newly created String.
|
||||
* @param p_contents A pointer to a wide C string.
|
||||
* @param p_size The number of characters.
|
||||
* @param p_size The number of characters (not bytes).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNewWithWideCharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_size);
|
||||
typedef void (*GDExtensionInterfaceStringNewWithWideCharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_char_count);
|
||||
|
||||
/**
|
||||
* @name string_to_latin1_chars
|
||||
@@ -1526,6 +1653,69 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqWcstr)(GDExtensionStringP
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringOperatorPlusEqC32str)(GDExtensionStringPtr p_self, const char32_t *p_b);
|
||||
|
||||
/**
|
||||
* @name string_resize
|
||||
* @since 4.2
|
||||
*
|
||||
* Resizes the underlying string data to the given number of characters.
|
||||
*
|
||||
* Space needs to be allocated for the null terminating character ('\0') which
|
||||
* also must be added manually, in order for all string functions to work correctly.
|
||||
*
|
||||
* Warning: This is an error-prone operation - only use it if there's no other
|
||||
* efficient way to accomplish your goal.
|
||||
*
|
||||
* @param p_self A pointer to the String.
|
||||
* @param p_resize The new length for the String.
|
||||
*
|
||||
* @return Error code signifying if the operation successful.
|
||||
*/
|
||||
typedef GDExtensionInt (*GDExtensionInterfaceStringResize)(GDExtensionStringPtr p_self, GDExtensionInt p_resize);
|
||||
|
||||
/* INTERFACE: StringName Utilities */
|
||||
|
||||
/**
|
||||
* @name string_name_new_with_latin1_chars
|
||||
* @since 4.2
|
||||
*
|
||||
* Creates a StringName from a Latin-1 encoded C string.
|
||||
*
|
||||
* If `p_is_static` is true, then:
|
||||
* - The StringName will reuse the `p_contents` buffer instead of copying it.
|
||||
* You must guarantee that the buffer remains valid for the duration of the application (e.g. string literal).
|
||||
* - You must not call a destructor for this StringName. Incrementing the initial reference once should achieve this.
|
||||
*
|
||||
* `p_is_static` is purely an optimization and can easily introduce undefined behavior if used wrong. In case of doubt, set it to false.
|
||||
*
|
||||
* @param r_dest A pointer to uninitialized storage, into which the newly created StringName is constructed.
|
||||
* @param p_contents A pointer to a C string (null terminated and Latin-1 or ASCII encoded).
|
||||
* @param p_is_static Whether the StringName reuses the buffer directly (see above).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNameNewWithLatin1Chars)(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionBool p_is_static);
|
||||
|
||||
/**
|
||||
* @name string_name_new_with_utf8_chars
|
||||
* @since 4.2
|
||||
*
|
||||
* Creates a StringName from a UTF-8 encoded C string.
|
||||
*
|
||||
* @param r_dest A pointer to uninitialized storage, into which the newly created StringName is constructed.
|
||||
* @param p_contents A pointer to a C string (null terminated and UTF-8 encoded).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNameNewWithUtf8Chars)(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents);
|
||||
|
||||
/**
|
||||
* @name string_name_new_with_utf8_chars_and_len
|
||||
* @since 4.2
|
||||
*
|
||||
* Creates a StringName from a UTF-8 encoded string with a given number of characters.
|
||||
*
|
||||
* @param r_dest A pointer to uninitialized storage, into which the newly created StringName is constructed.
|
||||
* @param p_contents A pointer to a C string (null terminated and UTF-8 encoded).
|
||||
* @param p_size The number of bytes (not UTF-8 code points).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNameNewWithUtf8CharsAndLen)(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionInt p_size);
|
||||
|
||||
/* INTERFACE: XMLParser Utilities */
|
||||
|
||||
/**
|
||||
@@ -2004,6 +2194,17 @@ typedef void *(*GDExtensionInterfaceObjectGetInstanceBinding)(GDExtensionObjectP
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceObjectSetInstanceBinding)(GDExtensionObjectPtr p_o, void *p_token, void *p_binding, const GDExtensionInstanceBindingCallbacks *p_callbacks);
|
||||
|
||||
/**
|
||||
* @name object_free_instance_binding
|
||||
* @since 4.2
|
||||
*
|
||||
* Free an Object's instance binding.
|
||||
*
|
||||
* @param p_o A pointer to the Object.
|
||||
* @param p_library A token the library received by the GDExtension's entry point function.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceObjectFreeInstanceBinding)(GDExtensionObjectPtr p_o, void *p_token);
|
||||
|
||||
/**
|
||||
* @name object_set_instance
|
||||
* @since 4.1
|
||||
@@ -2097,6 +2298,7 @@ typedef void (*GDExtensionInterfaceRefSetObject)(GDExtensionRefPtr p_ref, GDExte
|
||||
/**
|
||||
* @name script_instance_create
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.2. Use `script_instance_create2` instead.
|
||||
*
|
||||
* Creates a script instance that contains the given info and instance data.
|
||||
*
|
||||
@@ -2107,6 +2309,91 @@ typedef void (*GDExtensionInterfaceRefSetObject)(GDExtensionRefPtr p_ref, GDExte
|
||||
*/
|
||||
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)(const GDExtensionScriptInstanceInfo *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
|
||||
|
||||
/**
|
||||
* @name script_instance_create2
|
||||
* @since 4.2
|
||||
*
|
||||
* Creates a script instance that contains the given info and instance data.
|
||||
*
|
||||
* @param p_info A pointer to a GDExtensionScriptInstanceInfo2 struct.
|
||||
* @param p_instance_data A pointer to a data representing the script instance in the GDExtension. This will be passed to all the function pointers on p_info.
|
||||
*
|
||||
* @return A pointer to a ScriptInstanceExtension object.
|
||||
*/
|
||||
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate2)(const GDExtensionScriptInstanceInfo2 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
|
||||
|
||||
/**
|
||||
* @name placeholder_script_instance_create
|
||||
* @since 4.2
|
||||
*
|
||||
* Creates a placeholder script instance for a given script and instance.
|
||||
*
|
||||
* This interface is optional as a custom placeholder could also be created with script_instance_create().
|
||||
*
|
||||
* @param p_language A pointer to a ScriptLanguage.
|
||||
* @param p_script A pointer to a Script.
|
||||
* @param p_owner A pointer to an Object.
|
||||
*
|
||||
* @return A pointer to a PlaceHolderScriptInstance object.
|
||||
*/
|
||||
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfacePlaceHolderScriptInstanceCreate)(GDExtensionObjectPtr p_language, GDExtensionObjectPtr p_script, GDExtensionObjectPtr p_owner);
|
||||
|
||||
/**
|
||||
* @name placeholder_script_instance_update
|
||||
* @since 4.2
|
||||
*
|
||||
* Updates a placeholder script instance with the given properties and values.
|
||||
*
|
||||
* The passed in placeholder must be an instance of PlaceHolderScriptInstance
|
||||
* such as the one returned by placeholder_script_instance_create().
|
||||
*
|
||||
* @param p_placeholder A pointer to a PlaceHolderScriptInstance.
|
||||
* @param p_properties A pointer to an Array of Dictionary representing PropertyInfo.
|
||||
* @param p_values A pointer to a Dictionary mapping StringName to Variant values.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfacePlaceHolderScriptInstanceUpdate)(GDExtensionScriptInstancePtr p_placeholder, GDExtensionConstTypePtr p_properties, GDExtensionConstTypePtr p_values);
|
||||
|
||||
/**
|
||||
* @name object_get_script_instance
|
||||
* @since 4.2
|
||||
*
|
||||
* Get the script instance data attached to this object.
|
||||
*
|
||||
* @param p_object A pointer to the Object.
|
||||
* @param p_language A pointer to the language expected for this script instance.
|
||||
*
|
||||
* @return A GDExtensionScriptInstanceDataPtr that was attached to this object as part of script_instance_create.
|
||||
*/
|
||||
typedef GDExtensionScriptInstanceDataPtr (*GDExtensionInterfaceObjectGetScriptInstance)(GDExtensionConstObjectPtr p_object, GDExtensionObjectPtr p_language);
|
||||
|
||||
/* INTERFACE: Callable */
|
||||
|
||||
/**
|
||||
* @name callable_custom_create
|
||||
* @since 4.2
|
||||
*
|
||||
* Creates a custom Callable object from a function pointer.
|
||||
*
|
||||
* Provided struct can be safely freed once the function returns.
|
||||
*
|
||||
* @param r_callable A pointer that will receive the new Callable.
|
||||
* @param p_callable_custom_info The info required to construct a Callable.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceCallableCustomCreate)(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo *p_callable_custom_info);
|
||||
|
||||
/**
|
||||
* @name callable_custom_get_userdata
|
||||
* @since 4.2
|
||||
*
|
||||
* Retrieves the userdata pointer from a custom Callable.
|
||||
*
|
||||
* If the Callable is not a custom Callable or the token does not match the one provided to callable_custom_create() via GDExtensionCallableCustomInfo then NULL will be returned.
|
||||
*
|
||||
* @param p_callable A pointer to a Callable.
|
||||
* @param p_token A pointer to an address that uniquely identifies the GDExtension.
|
||||
*/
|
||||
typedef void *(*GDExtensionInterfaceCallableCustomGetUserData)(GDExtensionConstTypePtr p_callable, void *p_token);
|
||||
|
||||
/* INTERFACE: ClassDB */
|
||||
|
||||
/**
|
||||
@@ -2154,6 +2441,7 @@ typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNa
|
||||
/**
|
||||
* @name classdb_register_extension_class
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.2. Use `classdb_register_extension_class2` instead.
|
||||
*
|
||||
* Registers an extension class in the ClassDB.
|
||||
*
|
||||
@@ -2166,6 +2454,21 @@ typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNa
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo *p_extension_funcs);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class2
|
||||
* @since 4.2
|
||||
*
|
||||
* Registers an extension class in the ClassDB.
|
||||
*
|
||||
* Provided struct can be safely freed once the function returns.
|
||||
*
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param p_class_name A pointer to a StringName with the class name.
|
||||
* @param p_parent_class_name A pointer to a StringName with the parent class name.
|
||||
* @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo2 struct.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class_method
|
||||
* @since 4.1
|
||||
@@ -2211,6 +2514,23 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant)
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassProperty)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionPropertyInfo *p_info, GDExtensionConstStringNamePtr p_setter, GDExtensionConstStringNamePtr p_getter);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class_property_indexed
|
||||
* @since 4.2
|
||||
*
|
||||
* Registers an indexed property on an extension class in the ClassDB.
|
||||
*
|
||||
* Provided struct can be safely freed once the function returns.
|
||||
*
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param p_class_name A pointer to a StringName with the class name.
|
||||
* @param p_info A pointer to a GDExtensionPropertyInfo struct.
|
||||
* @param p_setter A pointer to a StringName with the name of the setter method.
|
||||
* @param p_getter A pointer to a StringName with the name of the getter method.
|
||||
* @param p_index The index to pass as the first argument to the getter and setter methods.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionPropertyInfo *p_info, GDExtensionConstStringNamePtr p_setter, GDExtensionConstStringNamePtr p_getter, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class_property_group
|
||||
* @since 4.1
|
||||
|
||||
@@ -48,9 +48,19 @@ typedef void GodotObject;
|
||||
// Base for all engine classes, to contain the pointer to the engine instance.
|
||||
class Wrapped {
|
||||
friend class GDExtensionBinding;
|
||||
friend class ClassDB;
|
||||
friend void postinitialize_handler(Wrapped *);
|
||||
|
||||
protected:
|
||||
#ifdef HOT_RELOAD_ENABLED
|
||||
struct RecreateInstance {
|
||||
GDExtensionClassInstancePtr wrapper;
|
||||
GDExtensionObjectPtr owner;
|
||||
RecreateInstance *next;
|
||||
};
|
||||
inline static RecreateInstance *recreate_instance = nullptr;
|
||||
#endif
|
||||
|
||||
virtual const StringName *_get_extension_class_name() const; // This is needed to retrieve the class name before the godot object has its _extension and _extension_instance members assigned.
|
||||
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const = 0;
|
||||
|
||||
@@ -60,20 +70,22 @@ protected:
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const {}
|
||||
bool _property_can_revert(const StringName &p_name) const { return false; }
|
||||
bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return false; }
|
||||
void _validate_property(PropertyInfo &p_property) const {}
|
||||
String _to_string() const { return "[" + String(get_class_static()) + ":" + itos(get_instance_id()) + "]"; }
|
||||
|
||||
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what) {}
|
||||
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) {}
|
||||
static GDExtensionBool set_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value) { return false; }
|
||||
static GDExtensionBool get_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
|
||||
static const GDExtensionPropertyInfo *get_property_list_bind(GDExtensionClassInstancePtr p_instance, uint32_t *r_count) { return nullptr; }
|
||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) {}
|
||||
static GDExtensionBool property_can_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name) { return false; }
|
||||
static GDExtensionBool property_get_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
|
||||
static GDExtensionBool validate_property_bind(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property) { return false; }
|
||||
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) {}
|
||||
|
||||
// The only reason this has to be held here, is when we return results of `_get_property_list` to Godot, we pass
|
||||
// pointers to strings in this list. They have to remain valid to pass the bridge, until the list is freed by Godot...
|
||||
::godot::List<::godot::PropertyInfo> plist_owned;
|
||||
GDExtensionPropertyInfo *plist = nullptr;
|
||||
uint32_t plist_size = 0;
|
||||
|
||||
void _postinitialize();
|
||||
|
||||
@@ -97,6 +109,9 @@ public:
|
||||
|
||||
namespace internal {
|
||||
|
||||
GDExtensionPropertyInfo *create_c_property_list(const ::godot::List<::godot::PropertyInfo> &plist_cpp, uint32_t *r_size);
|
||||
void free_c_property_list(GDExtensionPropertyInfo *plist);
|
||||
|
||||
typedef void (*EngineClassRegistrationCallback)();
|
||||
void add_engine_class_registration_callback(EngineClassRegistrationCallback p_callback);
|
||||
void register_engine_class(const StringName &p_name, const GDExtensionInstanceBindingCallbacks *p_callbacks);
|
||||
@@ -117,7 +132,10 @@ struct EngineClassRegistration {
|
||||
|
||||
} // namespace godot
|
||||
|
||||
#define GDCLASS(m_class, m_inherits) \
|
||||
// Use this on top of your own classes.
|
||||
// Note: the trail of `***` is to keep sane diffs in PRs, because clang-format otherwise moves every `\` which makes
|
||||
// every line of the macro different
|
||||
#define GDCLASS(m_class, m_inherits) /***********************************************************************************************************************************************/ \
|
||||
private: \
|
||||
void operator=(const m_class &p_rval) {} \
|
||||
friend class ::godot::ClassDB; \
|
||||
@@ -160,6 +178,10 @@ protected:
|
||||
return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name, ::godot::Variant &) const) & m_class::_property_get_revert; \
|
||||
} \
|
||||
\
|
||||
static void (::godot::Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \
|
||||
return (void(::godot::Wrapped::*)(::godot::PropertyInfo & p_property) const) & m_class::_validate_property; \
|
||||
} \
|
||||
\
|
||||
static ::godot::String (::godot::Wrapped::*_get_to_string())() const { \
|
||||
return (::godot::String(::godot::Wrapped::*)() const) & m_class::_to_string; \
|
||||
} \
|
||||
@@ -194,18 +216,18 @@ public:
|
||||
return m_inherits::get_class_static(); \
|
||||
} \
|
||||
\
|
||||
static GDExtensionObjectPtr create(void *data) { \
|
||||
m_class *new_object = memnew(m_class); \
|
||||
return new_object->_owner; \
|
||||
} \
|
||||
\
|
||||
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what) { \
|
||||
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) { \
|
||||
if (p_instance && m_class::_get_notification()) { \
|
||||
m_inherits::notification_bind(p_instance, p_what); \
|
||||
if (!p_reversed) { \
|
||||
m_inherits::notification_bind(p_instance, p_what, p_reversed); \
|
||||
} \
|
||||
if (m_class::_get_notification() != m_inherits::_get_notification()) { \
|
||||
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
||||
cls->_notification(p_what); \
|
||||
} \
|
||||
if (p_reversed) { \
|
||||
m_inherits::notification_bind(p_instance, p_what, p_reversed); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -231,40 +253,29 @@ public:
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
static inline bool has_get_property_list() { \
|
||||
return m_class::_get_get_property_list() && m_class::_get_get_property_list() != m_inherits::_get_get_property_list(); \
|
||||
} \
|
||||
\
|
||||
static const GDExtensionPropertyInfo *get_property_list_bind(GDExtensionClassInstancePtr p_instance, uint32_t *r_count) { \
|
||||
if (p_instance && m_class::_get_get_property_list()) { \
|
||||
if (m_class::_get_get_property_list() != m_inherits::_get_get_property_list()) { \
|
||||
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
||||
ERR_FAIL_COND_V_MSG(!cls->plist_owned.is_empty() || cls->plist != nullptr || cls->plist_size != 0, nullptr, "Internal error, property list was not freed by engine!"); \
|
||||
cls->_get_property_list(&cls->plist_owned); \
|
||||
cls->plist = reinterpret_cast<GDExtensionPropertyInfo *>(memalloc(sizeof(GDExtensionPropertyInfo) * cls->plist_owned.size())); \
|
||||
cls->plist_size = 0; \
|
||||
for (const ::godot::PropertyInfo &E : cls->plist_owned) { \
|
||||
cls->plist[cls->plist_size].type = static_cast<GDExtensionVariantType>(E.type); \
|
||||
cls->plist[cls->plist_size].name = E.name._native_ptr(); \
|
||||
cls->plist[cls->plist_size].hint = E.hint; \
|
||||
cls->plist[cls->plist_size].hint_string = E.hint_string._native_ptr(); \
|
||||
cls->plist[cls->plist_size].class_name = E.class_name._native_ptr(); \
|
||||
cls->plist[cls->plist_size].usage = E.usage; \
|
||||
cls->plist_size++; \
|
||||
} \
|
||||
if (r_count) \
|
||||
*r_count = cls->plist_size; \
|
||||
return cls->plist; \
|
||||
} \
|
||||
return m_inherits::get_property_list_bind(p_instance, r_count); \
|
||||
if (!p_instance) { \
|
||||
if (r_count) \
|
||||
*r_count = 0; \
|
||||
return nullptr; \
|
||||
} \
|
||||
return nullptr; \
|
||||
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
||||
::godot::List<::godot::PropertyInfo> &plist_cpp = cls->plist_owned; \
|
||||
ERR_FAIL_COND_V_MSG(!plist_cpp.is_empty(), nullptr, "Internal error, property list was not freed by engine!"); \
|
||||
cls->_get_property_list(&plist_cpp); \
|
||||
return ::godot::internal::create_c_property_list(plist_cpp, r_count); \
|
||||
} \
|
||||
\
|
||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) { \
|
||||
if (p_instance) { \
|
||||
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
||||
ERR_FAIL_COND_MSG(cls->plist == nullptr, "Internal error, property list double free!"); \
|
||||
memfree(cls->plist); \
|
||||
cls->plist = nullptr; \
|
||||
cls->plist_size = 0; \
|
||||
cls->plist_owned.clear(); \
|
||||
/* TODO `GDExtensionClassFreePropertyList` is ill-defined, we need a non-const pointer to free this. */ \
|
||||
::godot::internal::free_c_property_list(const_cast<GDExtensionPropertyInfo *>(p_list)); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -290,6 +301,21 @@ public:
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
static GDExtensionBool validate_property_bind(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property) { \
|
||||
bool ret = false; \
|
||||
if (p_instance && m_class::_get_validate_property()) { \
|
||||
ret = m_inherits::validate_property_bind(p_instance, p_property); \
|
||||
if (m_class::_get_validate_property() != m_inherits::_get_validate_property()) { \
|
||||
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
||||
::godot::PropertyInfo info(p_property); \
|
||||
cls->_validate_property(info); \
|
||||
info._update(p_property); \
|
||||
return true; \
|
||||
} \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) { \
|
||||
if (p_instance && m_class::_get_to_string()) { \
|
||||
if (m_class::_get_to_string() != m_inherits::_get_to_string()) { \
|
||||
@@ -397,16 +423,12 @@ public:
|
||||
return m_inherits::get_class_static(); \
|
||||
} \
|
||||
\
|
||||
static GDExtensionObjectPtr create(void *data) { \
|
||||
return nullptr; \
|
||||
} \
|
||||
\
|
||||
static void free(void *data, GDExtensionClassInstancePtr ptr) { \
|
||||
} \
|
||||
\
|
||||
static void *_gde_binding_create_callback(void *p_token, void *p_instance) { \
|
||||
/* Do not call memnew here, we don't want the post-initializer to be called */ \
|
||||
return new ("") m_class((GodotObject *)p_instance); \
|
||||
return new ("", "") m_class((GodotObject *)p_instance); \
|
||||
} \
|
||||
static void _gde_binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \
|
||||
/* Explicitly call the deconstructor to ensure proper lifecycle for non-trivial members */ \
|
||||
|
||||
@@ -276,12 +276,66 @@ void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) co
|
||||
(void)p_args;
|
||||
}
|
||||
|
||||
template <typename T, typename... P>
|
||||
void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, GDExtensionCallError &r_error) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((size_t)p_argcount < sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
|
||||
}
|
||||
|
||||
template <typename T, typename R, typename... P>
|
||||
void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((size_t)p_argcount < sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
|
||||
}
|
||||
|
||||
template <typename T, typename R, typename... P>
|
||||
void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((size_t)p_argcount < sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
call_with_variant_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
|
||||
}
|
||||
|
||||
template <typename T, typename... P>
|
||||
void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const std::vector<Variant> &default_values) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.argument = (int32_t)sizeof...(P);
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -292,7 +346,7 @@ void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const G
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (missing > dvs) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument = (int32_t)sizeof...(P);
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -316,7 +370,7 @@ void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const,
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.argument = (int32_t)sizeof...(P);
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -327,7 +381,7 @@ void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const,
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (missing > dvs) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument = (int32_t)sizeof...(P);
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -351,7 +405,7 @@ void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.argument = (int32_t)sizeof...(P);
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -362,7 +416,7 @@ void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (missing > dvs) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument = (int32_t)sizeof...(P);
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -386,7 +440,7 @@ void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const,
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.argument = (int32_t)sizeof...(P);
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -397,7 +451,7 @@ void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const,
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (missing > dvs) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument = (int32_t)sizeof...(P);
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -498,7 +552,7 @@ void call_with_variant_args_static_dv(void (*p_method)(P...), const GDExtensionC
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.argument = sizeof...(P);
|
||||
r_error.expected = sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -509,7 +563,7 @@ void call_with_variant_args_static_dv(void (*p_method)(P...), const GDExtensionC
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (missing > dvs) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument = sizeof...(P);
|
||||
r_error.expected = sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -538,6 +592,42 @@ void call_with_ptr_args_static_method(void (*p_method)(P...), const GDExtensionC
|
||||
call_with_ptr_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
|
||||
}
|
||||
|
||||
template <typename R, typename... P>
|
||||
void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((size_t)p_argcount < sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
call_with_variant_args_static_ret<R, P...>(p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
|
||||
}
|
||||
|
||||
template <typename... P>
|
||||
void call_with_variant_args_static_ret(void (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((size_t)p_argcount < sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.expected = (int32_t)sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
call_with_variant_args_static<P...>(p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
|
||||
}
|
||||
|
||||
template <typename R, typename... P, size_t... Is>
|
||||
void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, Variant &r_ret, GDExtensionCallError &r_error, IndexSequence<Is...>) {
|
||||
r_error.error = GDEXTENSION_CALL_OK;
|
||||
@@ -554,7 +644,7 @@ void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const GDExtension
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.argument = sizeof...(P);
|
||||
r_error.expected = sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -565,7 +655,7 @@ void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const GDExtension
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (missing > dvs) {
|
||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument = sizeof...(P);
|
||||
r_error.expected = sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
|
||||
#include <godot_cpp/classes/class_db_singleton.hpp>
|
||||
|
||||
// Makes callable_mp readily available in all classes connecting signals.
|
||||
// Needs to come after method_bind and object have been included.
|
||||
#include <godot_cpp/variant/callable_method_pointer.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <string>
|
||||
@@ -81,15 +85,6 @@ class ClassDB {
|
||||
friend class godot::GDExtensionBinding;
|
||||
|
||||
public:
|
||||
struct PropertySetGet {
|
||||
int index;
|
||||
StringName setter;
|
||||
StringName getter;
|
||||
MethodBind *_setptr;
|
||||
MethodBind *_getptr;
|
||||
Variant::Type type;
|
||||
};
|
||||
|
||||
struct ClassInfo {
|
||||
StringName name;
|
||||
StringName parent_name;
|
||||
@@ -115,13 +110,42 @@ private:
|
||||
static void bind_method_godot(const StringName &p_class_name, MethodBind *p_method);
|
||||
|
||||
template <typename T, bool is_abstract>
|
||||
static void _register_class(bool p_virtual = false);
|
||||
static void _register_class(bool p_virtual = false, bool p_exposed = true);
|
||||
|
||||
template <typename T>
|
||||
static GDExtensionObjectPtr _create_instance_func(void *data) {
|
||||
if constexpr (!std::is_abstract_v<T>) {
|
||||
T *new_object = memnew(T);
|
||||
return new_object->_owner;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static GDExtensionClassInstancePtr _recreate_instance_func(void *data, GDExtensionObjectPtr obj) {
|
||||
if constexpr (!std::is_abstract_v<T>) {
|
||||
#ifdef HOT_RELOAD_ENABLED
|
||||
T *new_instance = (T *)memalloc(sizeof(T));
|
||||
Wrapped::RecreateInstance recreate_data = { new_instance, obj, Wrapped::recreate_instance };
|
||||
Wrapped::recreate_instance = &recreate_data;
|
||||
memnew_placement(new_instance, T);
|
||||
return new_instance;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
static void register_class(bool p_virtual = false);
|
||||
template <typename T>
|
||||
static void register_abstract_class();
|
||||
template <typename T>
|
||||
static void register_internal_class();
|
||||
|
||||
_FORCE_INLINE_ static void _register_engine_class(const StringName &p_name, const GDExtensionInstanceBindingCallbacks *p_callbacks) {
|
||||
instance_binding_callbacks[p_name] = p_callbacks;
|
||||
@@ -172,7 +196,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename T, bool is_abstract>
|
||||
void ClassDB::_register_class(bool p_virtual) {
|
||||
void ClassDB::_register_class(bool p_virtual, bool p_exposed) {
|
||||
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
|
||||
instance_binding_callbacks[T::get_class_static()] = &T::_gde_binding_callbacks;
|
||||
|
||||
@@ -190,27 +214,32 @@ void ClassDB::_register_class(bool p_virtual) {
|
||||
class_register_order.push_back(cl.name);
|
||||
|
||||
// Register this class with Godot
|
||||
GDExtensionClassCreationInfo class_info = {
|
||||
GDExtensionClassCreationInfo2 class_info = {
|
||||
p_virtual, // GDExtensionBool is_virtual;
|
||||
is_abstract, // GDExtensionBool is_abstract;
|
||||
p_exposed, // GDExtensionBool is_exposed;
|
||||
T::set_bind, // GDExtensionClassSet set_func;
|
||||
T::get_bind, // GDExtensionClassGet get_func;
|
||||
T::get_property_list_bind, // GDExtensionClassGetPropertyList get_property_list_func;
|
||||
T::has_get_property_list() ? T::get_property_list_bind : nullptr, // GDExtensionClassGetPropertyList get_property_list_func;
|
||||
T::free_property_list_bind, // GDExtensionClassFreePropertyList free_property_list_func;
|
||||
T::property_can_revert_bind, // GDExtensionClassPropertyCanRevert property_can_revert_func;
|
||||
T::property_get_revert_bind, // GDExtensionClassPropertyGetRevert property_get_revert_func;
|
||||
T::notification_bind, // GDExtensionClassNotification notification_func;
|
||||
T::validate_property_bind, // GDExtensionClassValidateProperty validate_property_func;
|
||||
T::notification_bind, // GDExtensionClassNotification2 notification_func;
|
||||
T::to_string_bind, // GDExtensionClassToString to_string_func;
|
||||
nullptr, // GDExtensionClassReference reference_func;
|
||||
nullptr, // GDExtensionClassUnreference unreference_func;
|
||||
T::create, // GDExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
|
||||
&_create_instance_func<T>, // GDExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
|
||||
T::free, // GDExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
|
||||
&_recreate_instance_func<T>, // GDExtensionClassRecreateInstance recreate_instance_func;
|
||||
&ClassDB::get_virtual_func, // GDExtensionClassGetVirtual get_virtual_func;
|
||||
nullptr, // GDExtensionClassGetVirtualCallData get_virtual_call_data_func;
|
||||
nullptr, // GDExtensionClassCallVirtualWithData call_virtual_func;
|
||||
nullptr, // GDExtensionClassGetRID get_rid;
|
||||
(void *)&T::get_class_static(), // void *class_userdata;
|
||||
};
|
||||
|
||||
internal::gdextension_interface_classdb_register_extension_class(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
|
||||
internal::gdextension_interface_classdb_register_extension_class2(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();
|
||||
@@ -229,6 +258,11 @@ void ClassDB::register_abstract_class() {
|
||||
ClassDB::_register_class<T, true>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ClassDB::register_internal_class() {
|
||||
ClassDB::_register_class<T, false>(false, false);
|
||||
}
|
||||
|
||||
template <typename N, typename 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.
|
||||
@@ -287,6 +321,7 @@ MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p
|
||||
#define GDREGISTER_CLASS(m_class) ClassDB::register_class<m_class>();
|
||||
#define GDREGISTER_VIRTUAL_CLASS(m_class) ClassDB::register_class<m_class>(true);
|
||||
#define GDREGISTER_ABSTRACT_CLASS(m_class) ClassDB::register_abstract_class<m_class>();
|
||||
#define GDREGISTER_INTERNAL_CLASS(m_class) ClassDB::register_internal_class<m_class>();
|
||||
|
||||
} // namespace godot
|
||||
|
||||
|
||||
@@ -40,20 +40,21 @@
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
void *operator new(size_t p_size, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool
|
||||
void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)); ///< operator new that takes a description and uses MemoryStaticPool
|
||||
void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory
|
||||
// p_dummy argument is added to avoid conflicts with the engine functions when both engine and GDExtension are built as a static library on iOS.
|
||||
void *operator new(size_t p_size, const char *p_dummy, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool
|
||||
void *operator new(size_t p_size, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)); ///< operator new that takes a description and uses MemoryStaticPool
|
||||
void *operator new(size_t p_size, const char *p_dummy, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory
|
||||
|
||||
_ALWAYS_INLINE_ void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description) {
|
||||
_ALWAYS_INLINE_ void *operator new(size_t p_size, const char *p_dummy, void *p_pointer, size_t check, const char *p_description) {
|
||||
return p_pointer;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// When compiling with VC++ 2017, the above declarations of placement new generate many irrelevant warnings (C4291).
|
||||
// The purpose of the following definitions is to muffle these warnings, not to provide a usable implementation of placement delete.
|
||||
void operator delete(void *p_mem, const char *p_description);
|
||||
void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size));
|
||||
void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description);
|
||||
void operator delete(void *p_mem, const char *p_dummy, const char *p_description);
|
||||
void operator delete(void *p_mem, const char *p_dummy, void *(*p_allocfunc)(size_t p_size));
|
||||
void operator delete(void *p_mem, const char *p_dummy, void *p_pointer, size_t check, const char *p_description);
|
||||
#endif
|
||||
|
||||
namespace godot {
|
||||
@@ -93,10 +94,10 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
|
||||
#define memrealloc(m_mem, m_size) ::godot::Memory::realloc_static(m_mem, m_size)
|
||||
#define memfree(m_mem) ::godot::Memory::free_static(m_mem)
|
||||
|
||||
#define memnew(m_class) ::godot::_post_initialize(new ("") m_class)
|
||||
#define memnew(m_class) ::godot::_post_initialize(new ("", "") m_class)
|
||||
|
||||
#define memnew_allocator(m_class, m_allocator) ::godot::_post_initialize(new (m_allocator::alloc) m_class)
|
||||
#define memnew_placement(m_placement, m_class) ::godot::_post_initialize(new (m_placement, sizeof(m_class), "") m_class)
|
||||
#define memnew_allocator(m_class, m_allocator) ::godot::_post_initialize(new ("", m_allocator::alloc) m_class)
|
||||
#define memnew_placement(m_placement, m_class) ::godot::_post_initialize(new ("", m_placement, sizeof(m_class), "") m_class)
|
||||
|
||||
// Generic comparator used in Map, List, etc.
|
||||
template <typename T>
|
||||
@@ -168,7 +169,7 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
|
||||
|
||||
/* call operator new */
|
||||
for (size_t i = 0; i < p_elements; i++) {
|
||||
new (&elems[i], sizeof(T), p_descr) T;
|
||||
new ("", &elems[i], sizeof(T), p_descr) T;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
#include <godot_cpp/core/defs.hpp>
|
||||
|
||||
#include <godot_cpp/core/object_id.hpp>
|
||||
|
||||
#include <godot_cpp/core/property_info.hpp>
|
||||
|
||||
#include <godot_cpp/variant/variant.hpp>
|
||||
@@ -49,6 +51,7 @@
|
||||
#define ADD_GROUP(m_name, m_prefix) ::godot::ClassDB::add_property_group(get_class_static(), m_name, m_prefix)
|
||||
#define ADD_SUBGROUP(m_name, m_prefix) ::godot::ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix)
|
||||
#define ADD_PROPERTY(m_property, m_setter, m_getter) ::godot::ClassDB::add_property(get_class_static(), m_property, m_setter, m_getter)
|
||||
#define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ::godot::ClassDB::add_property(get_class_static(), m_property, m_setter, m_getter, m_index)
|
||||
|
||||
namespace godot {
|
||||
|
||||
@@ -105,28 +108,6 @@ MethodInfo::MethodInfo(const PropertyInfo &p_ret, StringName p_name, const Args
|
||||
arguments = { args... };
|
||||
}
|
||||
|
||||
class ObjectID {
|
||||
uint64_t id = 0;
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ bool is_ref_counted() const { return (id & (uint64_t(1) << 63)) != 0; }
|
||||
_FORCE_INLINE_ bool is_valid() const { return id != 0; }
|
||||
_FORCE_INLINE_ bool is_null() const { return id == 0; }
|
||||
_FORCE_INLINE_ operator uint64_t() const { return id; }
|
||||
_FORCE_INLINE_ operator int64_t() const { return id; }
|
||||
|
||||
_FORCE_INLINE_ bool operator==(const ObjectID &p_id) const { return id == p_id.id; }
|
||||
_FORCE_INLINE_ bool operator!=(const ObjectID &p_id) const { return id != p_id.id; }
|
||||
_FORCE_INLINE_ bool operator<(const ObjectID &p_id) const { return id < p_id.id; }
|
||||
|
||||
_FORCE_INLINE_ void operator=(int64_t p_int64) { id = p_int64; }
|
||||
_FORCE_INLINE_ void operator=(uint64_t p_uint64) { id = p_uint64; }
|
||||
|
||||
_FORCE_INLINE_ ObjectID() {}
|
||||
_FORCE_INLINE_ explicit ObjectID(const uint64_t p_id) { id = p_id; }
|
||||
_FORCE_INLINE_ explicit ObjectID(const int64_t p_id) { id = p_id; }
|
||||
};
|
||||
|
||||
class ObjectDB {
|
||||
public:
|
||||
static Object *get_instance(uint64_t p_object_id) {
|
||||
|
||||
62
include/godot_cpp/core/object_id.hpp
Normal file
62
include/godot_cpp/core/object_id.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/**************************************************************************/
|
||||
/* object_id.hpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GODOT_OBJECT_ID_HPP
|
||||
#define GODOT_OBJECT_ID_HPP
|
||||
|
||||
#include <godot_cpp/core/defs.hpp>
|
||||
|
||||
namespace godot {
|
||||
|
||||
class ObjectID {
|
||||
uint64_t id = 0;
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ bool is_ref_counted() const { return (id & (uint64_t(1) << 63)) != 0; }
|
||||
_FORCE_INLINE_ bool is_valid() const { return id != 0; }
|
||||
_FORCE_INLINE_ bool is_null() const { return id == 0; }
|
||||
_FORCE_INLINE_ operator uint64_t() const { return id; }
|
||||
_FORCE_INLINE_ operator int64_t() const { return id; }
|
||||
|
||||
_FORCE_INLINE_ bool operator==(const ObjectID &p_id) const { return id == p_id.id; }
|
||||
_FORCE_INLINE_ bool operator!=(const ObjectID &p_id) const { return id != p_id.id; }
|
||||
_FORCE_INLINE_ bool operator<(const ObjectID &p_id) const { return id < p_id.id; }
|
||||
|
||||
_FORCE_INLINE_ void operator=(int64_t p_int64) { id = p_int64; }
|
||||
_FORCE_INLINE_ void operator=(uint64_t p_uint64) { id = p_uint64; }
|
||||
|
||||
_FORCE_INLINE_ ObjectID() {}
|
||||
_FORCE_INLINE_ explicit ObjectID(const uint64_t p_id) { id = p_id; }
|
||||
_FORCE_INLINE_ explicit ObjectID(const int64_t p_id) { id = p_id; }
|
||||
};
|
||||
|
||||
} // namespace godot
|
||||
|
||||
#endif // GODOT_OBJECT_ID_HPP
|
||||
@@ -68,6 +68,18 @@ struct PropertyInfo {
|
||||
|
||||
PropertyInfo(GDExtensionVariantType p_type, const StringName &p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const StringName &p_class_name = "") :
|
||||
PropertyInfo((Variant::Type)p_type, p_name, p_hint, p_hint_string, p_usage, p_class_name) {}
|
||||
|
||||
PropertyInfo(const GDExtensionPropertyInfo *p_info) :
|
||||
PropertyInfo(p_info->type, *reinterpret_cast<StringName *>(p_info->name), (PropertyHint)p_info->hint, *reinterpret_cast<String *>(p_info->hint_string), p_info->usage, *reinterpret_cast<StringName *>(p_info->class_name)) {}
|
||||
|
||||
void _update(GDExtensionPropertyInfo *p_info) {
|
||||
p_info->type = (GDExtensionVariantType)type;
|
||||
*(reinterpret_cast<StringName *>(p_info->name)) = name;
|
||||
p_info->hint = hint;
|
||||
*(reinterpret_cast<String *>(p_info->hint_string)) = hint_string;
|
||||
p_info->usage = usage;
|
||||
*(reinterpret_cast<StringName *>(p_info->class_name)) = class_name;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace godot
|
||||
|
||||
@@ -123,6 +123,8 @@ extern "C" GDExtensionInterfaceStringOperatorPlusEqChar gdextension_interface_st
|
||||
extern "C" GDExtensionInterfaceStringOperatorPlusEqCstr gdextension_interface_string_operator_plus_eq_cstr;
|
||||
extern "C" GDExtensionInterfaceStringOperatorPlusEqWcstr gdextension_interface_string_operator_plus_eq_wcstr;
|
||||
extern "C" GDExtensionInterfaceStringOperatorPlusEqC32str gdextension_interface_string_operator_plus_eq_c32str;
|
||||
extern "C" GDExtensionInterfaceStringResize gdextension_interface_string_resize;
|
||||
extern "C" GDExtensionInterfaceStringNameNewWithLatin1Chars gdextension_interface_string_name_new_with_latin1_chars;
|
||||
extern "C" GDExtensionInterfaceXmlParserOpenBuffer gdextension_interface_xml_parser_open_buffer;
|
||||
extern "C" GDExtensionInterfaceFileAccessStoreBuffer gdextension_interface_file_access_store_buffer;
|
||||
extern "C" GDExtensionInterfaceFileAccessGetBuffer gdextension_interface_file_access_get_buffer;
|
||||
@@ -163,16 +165,21 @@ extern "C" GDExtensionInterfaceObjectGetClassName gdextension_interface_object_g
|
||||
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" GDExtensionInterfaceCallableCustomCreate gdextension_interface_callable_custom_create;
|
||||
extern "C" GDExtensionInterfaceCallableCustomGetUserData gdextension_interface_callable_custom_get_userdata;
|
||||
extern "C" GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object;
|
||||
extern "C" GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object;
|
||||
extern "C" GDExtensionInterfaceScriptInstanceCreate gdextension_interface_script_instance_create;
|
||||
extern "C" GDExtensionInterfaceScriptInstanceCreate2 gdextension_interface_script_instance_create2;
|
||||
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create;
|
||||
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update;
|
||||
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" GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2;
|
||||
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" GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup gdextension_interface_classdb_register_extension_class_property_group;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup gdextension_interface_classdb_register_extension_class_property_subgroup;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassSignal gdextension_interface_classdb_register_extension_class_signal;
|
||||
|
||||
@@ -201,11 +201,11 @@ inline bool AABB::encloses(const AABB &p_aabb) const {
|
||||
|
||||
return (
|
||||
(src_min.x <= dst_min.x) &&
|
||||
(src_max.x > dst_max.x) &&
|
||||
(src_max.x >= dst_max.x) &&
|
||||
(src_min.y <= dst_min.y) &&
|
||||
(src_max.y > dst_max.y) &&
|
||||
(src_max.y >= dst_max.y) &&
|
||||
(src_min.z <= dst_min.z) &&
|
||||
(src_max.z > dst_max.z));
|
||||
(src_max.z >= dst_max.z));
|
||||
}
|
||||
|
||||
Vector3 AABB::get_support(const Vector3 &p_normal) const {
|
||||
|
||||
64
include/godot_cpp/variant/callable_custom.hpp
Normal file
64
include/godot_cpp/variant/callable_custom.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/**************************************************************************/
|
||||
/* callable_custom.hpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GODOT_CALLABLE_CUSTOM_HPP
|
||||
#define GODOT_CALLABLE_CUSTOM_HPP
|
||||
|
||||
#include <godot_cpp/core/object_id.hpp>
|
||||
#include <godot_cpp/variant/string_name.hpp>
|
||||
|
||||
namespace godot {
|
||||
|
||||
class Object;
|
||||
|
||||
class CallableCustomBase {
|
||||
public:
|
||||
virtual ObjectID get_object() const = 0;
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const = 0;
|
||||
virtual ~CallableCustomBase() {}
|
||||
};
|
||||
|
||||
class CallableCustom : public CallableCustomBase {
|
||||
public:
|
||||
typedef bool (*CompareEqualFunc)(const CallableCustom *p_a, const CallableCustom *p_b);
|
||||
typedef bool (*CompareLessFunc)(const CallableCustom *p_a, const CallableCustom *p_b);
|
||||
|
||||
virtual uint32_t hash() const = 0;
|
||||
virtual String get_as_text() const = 0;
|
||||
virtual CompareEqualFunc get_compare_equal_func() const = 0;
|
||||
virtual CompareLessFunc get_compare_less_func() const = 0;
|
||||
virtual bool is_valid() const;
|
||||
virtual ObjectID get_object() const = 0;
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const = 0;
|
||||
};
|
||||
|
||||
} // namespace godot
|
||||
|
||||
#endif // GODOT_CALLABLE_CUSTOM_HPP
|
||||
248
include/godot_cpp/variant/callable_method_pointer.hpp
Normal file
248
include/godot_cpp/variant/callable_method_pointer.hpp
Normal file
@@ -0,0 +1,248 @@
|
||||
/**************************************************************************/
|
||||
/* callable_method_pointer.hpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GODOT_CALLABLE_METHOD_POINTER_HPP
|
||||
#define GODOT_CALLABLE_METHOD_POINTER_HPP
|
||||
|
||||
#include <godot_cpp/core/binder_common.hpp>
|
||||
#include <godot_cpp/variant/variant.hpp>
|
||||
|
||||
namespace godot {
|
||||
|
||||
class CallableCustomMethodPointerBase : public CallableCustomBase {
|
||||
uint32_t *comp_ptr = nullptr;
|
||||
uint32_t comp_size;
|
||||
uint32_t h;
|
||||
|
||||
protected:
|
||||
void _setup(uint32_t *p_base_ptr, uint32_t p_ptr_size);
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ const uint32_t *get_comp_ptr() const { return comp_ptr; }
|
||||
_FORCE_INLINE_ uint32_t get_comp_size() const { return comp_size; }
|
||||
_FORCE_INLINE_ uint32_t get_hash() const { return h; }
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_method_pointer);
|
||||
|
||||
} // namespace internal
|
||||
|
||||
//
|
||||
// No return value.
|
||||
//
|
||||
|
||||
template <typename T, typename... P>
|
||||
class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
|
||||
struct Data {
|
||||
T *instance;
|
||||
void (T::*method)(P...);
|
||||
} data;
|
||||
static_assert(sizeof(Data) % 4 == 0);
|
||||
|
||||
public:
|
||||
virtual ObjectID get_object() const override {
|
||||
return ObjectID(data.instance->get_instance_id());
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
|
||||
}
|
||||
|
||||
CallableCustomMethodPointer(T *p_instance, void (T::*p_method)(P...)) {
|
||||
memset(&data, 0, sizeof(Data));
|
||||
data.instance = p_instance;
|
||||
data.method = p_method;
|
||||
_setup((uint32_t *)&data, sizeof(Data));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename... P>
|
||||
Callable create_custom_callable_function_pointer(T *p_instance, void (T::*p_method)(P...)) {
|
||||
typedef CallableCustomMethodPointer<T, P...> CCMP;
|
||||
CCMP *ccmp = memnew(CCMP(p_instance, p_method));
|
||||
return ::godot::internal::create_callable_from_ccmp(ccmp);
|
||||
}
|
||||
|
||||
//
|
||||
// With return value.
|
||||
//
|
||||
|
||||
template <typename T, typename R, typename... P>
|
||||
class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
|
||||
struct Data {
|
||||
T *instance;
|
||||
R(T::*method)
|
||||
(P...);
|
||||
} data;
|
||||
static_assert(sizeof(Data) % 4 == 0);
|
||||
|
||||
public:
|
||||
virtual ObjectID get_object() const override {
|
||||
return ObjectID(data.instance->get_instance_id());
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
}
|
||||
|
||||
CallableCustomMethodPointerRet(T *p_instance, R (T::*p_method)(P...)) {
|
||||
memset(&data, 0, sizeof(Data));
|
||||
data.instance = p_instance;
|
||||
data.method = p_method;
|
||||
_setup((uint32_t *)&data, sizeof(Data));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... P>
|
||||
Callable create_custom_callable_function_pointer(T *p_instance, R (T::*p_method)(P...)) {
|
||||
typedef CallableCustomMethodPointerRet<T, R, P...> CCMP; // Messes with memnew otherwise.
|
||||
CCMP *ccmp = memnew(CCMP(p_instance, p_method));
|
||||
return ::godot::internal::create_callable_from_ccmp(ccmp);
|
||||
}
|
||||
|
||||
//
|
||||
// Const with return value.
|
||||
//
|
||||
|
||||
template <typename T, typename R, typename... P>
|
||||
class CallableCustomMethodPointerRetC : public CallableCustomMethodPointerBase {
|
||||
struct Data {
|
||||
T *instance;
|
||||
R(T::*method)
|
||||
(P...) const;
|
||||
} data;
|
||||
static_assert(sizeof(Data) % 4 == 0);
|
||||
|
||||
public:
|
||||
virtual ObjectID get_object() const override {
|
||||
return ObjectID(data.instance->get_instance_id());
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_retc(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
}
|
||||
|
||||
CallableCustomMethodPointerRetC(const T *p_instance, R (T::*p_method)(P...) const) {
|
||||
memset(&data, 0, sizeof(Data));
|
||||
data.instance = const_cast<T *>(p_instance);
|
||||
data.method = p_method;
|
||||
_setup((uint32_t *)&data, sizeof(Data));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename R, typename... P>
|
||||
Callable create_custom_callable_function_pointer(const T *p_instance, R (T::*p_method)(P...) const) {
|
||||
typedef CallableCustomMethodPointerRetC<T, R, P...> CCMP; // Messes with memnew otherwise.
|
||||
CCMP *ccmp = memnew(CCMP(p_instance, p_method));
|
||||
return ::godot::internal::create_callable_from_ccmp(ccmp);
|
||||
}
|
||||
|
||||
//
|
||||
// Static method with no return value.
|
||||
//
|
||||
|
||||
template <typename... P>
|
||||
class CallableCustomStaticMethodPointer : public CallableCustomMethodPointerBase {
|
||||
struct Data {
|
||||
void (*method)(P...);
|
||||
} data;
|
||||
static_assert(sizeof(Data) % 4 == 0);
|
||||
|
||||
public:
|
||||
virtual ObjectID get_object() const override {
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
r_return_value = Variant();
|
||||
}
|
||||
|
||||
CallableCustomStaticMethodPointer(void (*p_method)(P...)) {
|
||||
memset(&data, 0, sizeof(Data));
|
||||
data.method = p_method;
|
||||
_setup((uint32_t *)&data, sizeof(Data));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... P>
|
||||
Callable create_custom_callable_static_function_pointer(void (*p_method)(P...)) {
|
||||
typedef CallableCustomStaticMethodPointer<P...> CCMP;
|
||||
CCMP *ccmp = memnew(CCMP(p_method));
|
||||
return ::godot::internal::create_callable_from_ccmp(ccmp);
|
||||
}
|
||||
|
||||
//
|
||||
// Static method with return value.
|
||||
//
|
||||
|
||||
template <typename R, typename... P>
|
||||
class CallableCustomStaticMethodPointerRet : public CallableCustomMethodPointerBase {
|
||||
struct Data {
|
||||
R(*method)
|
||||
(P...);
|
||||
} data;
|
||||
static_assert(sizeof(Data) % 4 == 0);
|
||||
|
||||
public:
|
||||
virtual ObjectID get_object() const override {
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
}
|
||||
|
||||
CallableCustomStaticMethodPointerRet(R (*p_method)(P...)) {
|
||||
memset(&data, 0, sizeof(Data));
|
||||
data.method = p_method;
|
||||
_setup((uint32_t *)&data, sizeof(Data));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename... P>
|
||||
Callable create_custom_callable_static_function_pointer(R (*p_method)(P...)) {
|
||||
typedef CallableCustomStaticMethodPointerRet<R, P...> CCMP;
|
||||
CCMP *ccmp = memnew(CCMP(p_method));
|
||||
return ::godot::internal::create_callable_from_ccmp(ccmp);
|
||||
}
|
||||
|
||||
//
|
||||
// The API:
|
||||
//
|
||||
|
||||
#define callable_mp(I, M) ::godot::create_custom_callable_function_pointer(I, M)
|
||||
#define callable_mp_static(M) ::godot::create_custom_callable_static_function_pointer(M)
|
||||
|
||||
} // namespace godot
|
||||
|
||||
#endif // GODOT_CALLABLE_METHOD_POINTER_HPP
|
||||
@@ -354,6 +354,14 @@ String vformat(const String &p_text, const VarArgs... p_args) {
|
||||
return p_text % args_array;
|
||||
}
|
||||
|
||||
#include <godot_cpp/variant/builtin_vararg_methods.hpp>
|
||||
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
using PackedRealArray = PackedFloat64Array;
|
||||
#else
|
||||
using PackedRealArray = PackedFloat32Array;
|
||||
#endif // REAL_T_IS_DOUBLE
|
||||
|
||||
} // namespace godot
|
||||
|
||||
#endif // GODOT_VARIANT_HPP
|
||||
|
||||
@@ -59,6 +59,25 @@ void Wrapped::_postinitialize() {
|
||||
}
|
||||
|
||||
Wrapped::Wrapped(const StringName p_godot_class) {
|
||||
#ifdef HOT_RELOAD_ENABLED
|
||||
if (unlikely(Wrapped::recreate_instance)) {
|
||||
RecreateInstance *recreate_data = Wrapped::recreate_instance;
|
||||
RecreateInstance *previous = nullptr;
|
||||
while (recreate_data) {
|
||||
if (recreate_data->wrapper == this) {
|
||||
_owner = recreate_data->owner;
|
||||
if (previous) {
|
||||
previous->next = recreate_data->next;
|
||||
} else {
|
||||
Wrapped::recreate_instance = recreate_data->next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
previous = recreate_data;
|
||||
recreate_data = recreate_data->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
_owner = godot::internal::gdextension_interface_classdb_construct_object(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
|
||||
}
|
||||
|
||||
@@ -77,6 +96,31 @@ std::vector<EngineClassRegistrationCallback> &get_engine_class_registration_call
|
||||
return engine_class_registration_callbacks;
|
||||
}
|
||||
|
||||
GDExtensionPropertyInfo *create_c_property_list(const ::godot::List<::godot::PropertyInfo> &plist_cpp, uint32_t *r_size) {
|
||||
GDExtensionPropertyInfo *plist = nullptr;
|
||||
// Linked list size can be expensive to get so we cache it
|
||||
const uint32_t plist_size = plist_cpp.size();
|
||||
if (r_size != nullptr) {
|
||||
*r_size = plist_size;
|
||||
}
|
||||
plist = reinterpret_cast<GDExtensionPropertyInfo *>(memalloc(sizeof(GDExtensionPropertyInfo) * plist_size));
|
||||
unsigned int i = 0;
|
||||
for (const ::godot::PropertyInfo &E : plist_cpp) {
|
||||
plist[i].type = static_cast<GDExtensionVariantType>(E.type);
|
||||
plist[i].name = E.name._native_ptr();
|
||||
plist[i].hint = E.hint;
|
||||
plist[i].hint_string = E.hint_string._native_ptr();
|
||||
plist[i].class_name = E.class_name._native_ptr();
|
||||
plist[i].usage = E.usage;
|
||||
++i;
|
||||
}
|
||||
return plist;
|
||||
}
|
||||
|
||||
void free_c_property_list(GDExtensionPropertyInfo *plist) {
|
||||
memfree(plist);
|
||||
}
|
||||
|
||||
void add_engine_class_registration_callback(EngineClassRegistrationCallback p_callback) {
|
||||
get_engine_class_registration_callbacks().push_back(p_callback);
|
||||
}
|
||||
|
||||
@@ -105,15 +105,7 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf
|
||||
p_pinfo.usage, // DEFAULT //uint32_t usage;
|
||||
};
|
||||
|
||||
PropertySetGet setget;
|
||||
setget.setter = p_setter;
|
||||
setget.getter = p_getter;
|
||||
setget._setptr = setter;
|
||||
setget._getptr = getter;
|
||||
setget.index = p_index;
|
||||
setget.type = p_pinfo.type;
|
||||
|
||||
internal::gdextension_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_indexed(internal::library, info.name._native_ptr(), &prop_info, p_setter._native_ptr(), p_getter._native_ptr(), p_index);
|
||||
}
|
||||
|
||||
MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_method) {
|
||||
@@ -360,6 +352,7 @@ void ClassDB::initialize(GDExtensionInitializationLevel p_level) {
|
||||
}
|
||||
|
||||
void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
|
||||
std::set<StringName> to_erase;
|
||||
for (std::vector<StringName>::reverse_iterator i = class_register_order.rbegin(); i != class_register_order.rend(); ++i) {
|
||||
const StringName &name = *i;
|
||||
const ClassInfo &cl = classes[name];
|
||||
@@ -370,9 +363,20 @@ void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
|
||||
|
||||
internal::gdextension_interface_classdb_unregister_extension_class(internal::library, name._native_ptr());
|
||||
|
||||
for (auto method : cl.method_map) {
|
||||
for (const std::pair<const StringName, MethodBind *> &method : cl.method_map) {
|
||||
memdelete(method.second);
|
||||
}
|
||||
|
||||
classes.erase(name);
|
||||
to_erase.insert(name);
|
||||
}
|
||||
|
||||
{
|
||||
// The following is equivalent to c++20 `std::erase_if(class_register_order, [&](const StringName& name){ return to_erase.contains(name); });`
|
||||
std::vector<StringName>::iterator it = std::remove_if(class_register_order.begin(), class_register_order.end(), [&](const StringName &p_name) {
|
||||
return to_erase.count(p_name) > 0;
|
||||
});
|
||||
class_register_order.erase(it, class_register_order.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,28 +103,29 @@ _GlobalNil _GlobalNilClass::_nil;
|
||||
|
||||
} // namespace godot
|
||||
|
||||
void *operator new(size_t p_size, const char *p_description) {
|
||||
// p_dummy argument is added to avoid conflicts with the engine functions when both engine and GDExtension are built as a static library on iOS.
|
||||
void *operator new(size_t p_size, const char *p_dummy, const char *p_description) {
|
||||
return godot::Memory::alloc_static(p_size);
|
||||
}
|
||||
|
||||
void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) {
|
||||
void *operator new(size_t p_size, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)) {
|
||||
return p_allocfunc(p_size);
|
||||
}
|
||||
|
||||
using namespace godot;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
void operator delete(void *p_mem, const char *p_description) {
|
||||
void operator delete(void *p_mem, const char *p_dummy, const char *p_description) {
|
||||
ERR_PRINT("Call to placement delete should not happen.");
|
||||
CRASH_NOW();
|
||||
}
|
||||
|
||||
void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)) {
|
||||
void operator delete(void *p_mem, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)) {
|
||||
ERR_PRINT("Call to placement delete should not happen.");
|
||||
CRASH_NOW();
|
||||
}
|
||||
|
||||
void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description) {
|
||||
void operator delete(void *p_mem, const char *p_dummy, void *p_pointer, size_t check, const char *p_description) {
|
||||
ERR_PRINT("Call to placement delete should not happen.");
|
||||
CRASH_NOW();
|
||||
}
|
||||
|
||||
@@ -129,6 +129,8 @@ GDExtensionInterfaceStringOperatorPlusEqChar gdextension_interface_string_operat
|
||||
GDExtensionInterfaceStringOperatorPlusEqCstr gdextension_interface_string_operator_plus_eq_cstr = nullptr;
|
||||
GDExtensionInterfaceStringOperatorPlusEqWcstr gdextension_interface_string_operator_plus_eq_wcstr = nullptr;
|
||||
GDExtensionInterfaceStringOperatorPlusEqC32str gdextension_interface_string_operator_plus_eq_c32str = nullptr;
|
||||
GDExtensionInterfaceStringResize gdextension_interface_string_resize = nullptr;
|
||||
GDExtensionInterfaceStringNameNewWithLatin1Chars gdextension_interface_string_name_new_with_latin1_chars = nullptr;
|
||||
GDExtensionInterfaceXmlParserOpenBuffer gdextension_interface_xml_parser_open_buffer = nullptr;
|
||||
GDExtensionInterfaceFileAccessStoreBuffer gdextension_interface_file_access_store_buffer = nullptr;
|
||||
GDExtensionInterfaceFileAccessGetBuffer gdextension_interface_file_access_get_buffer = nullptr;
|
||||
@@ -169,16 +171,21 @@ GDExtensionInterfaceObjectGetClassName gdextension_interface_object_get_class_na
|
||||
GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to = nullptr;
|
||||
GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id = nullptr;
|
||||
GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id = nullptr;
|
||||
GDExtensionInterfaceCallableCustomCreate gdextension_interface_callable_custom_create = nullptr;
|
||||
GDExtensionInterfaceCallableCustomGetUserData gdextension_interface_callable_custom_get_userdata = nullptr;
|
||||
GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object = nullptr;
|
||||
GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object = nullptr;
|
||||
GDExtensionInterfaceScriptInstanceCreate gdextension_interface_script_instance_create = nullptr;
|
||||
GDExtensionInterfaceScriptInstanceCreate2 gdextension_interface_script_instance_create2 = nullptr;
|
||||
GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create = nullptr;
|
||||
GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update = 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;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2 = 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;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup gdextension_interface_classdb_register_extension_class_property_group = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup gdextension_interface_classdb_register_extension_class_property_subgroup = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassSignal gdextension_interface_classdb_register_extension_class_signal = nullptr;
|
||||
@@ -359,6 +366,8 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
LOAD_PROC_ADDRESS(string_operator_plus_eq_cstr, GDExtensionInterfaceStringOperatorPlusEqCstr);
|
||||
LOAD_PROC_ADDRESS(string_operator_plus_eq_wcstr, GDExtensionInterfaceStringOperatorPlusEqWcstr);
|
||||
LOAD_PROC_ADDRESS(string_operator_plus_eq_c32str, GDExtensionInterfaceStringOperatorPlusEqC32str);
|
||||
LOAD_PROC_ADDRESS(string_resize, GDExtensionInterfaceStringResize);
|
||||
LOAD_PROC_ADDRESS(string_name_new_with_latin1_chars, GDExtensionInterfaceStringNameNewWithLatin1Chars);
|
||||
LOAD_PROC_ADDRESS(xml_parser_open_buffer, GDExtensionInterfaceXmlParserOpenBuffer);
|
||||
LOAD_PROC_ADDRESS(file_access_store_buffer, GDExtensionInterfaceFileAccessStoreBuffer);
|
||||
LOAD_PROC_ADDRESS(file_access_get_buffer, GDExtensionInterfaceFileAccessGetBuffer);
|
||||
@@ -399,16 +408,21 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
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(callable_custom_create, GDExtensionInterfaceCallableCustomCreate);
|
||||
LOAD_PROC_ADDRESS(callable_custom_get_userdata, GDExtensionInterfaceCallableCustomGetUserData);
|
||||
LOAD_PROC_ADDRESS(ref_get_object, GDExtensionInterfaceRefGetObject);
|
||||
LOAD_PROC_ADDRESS(ref_set_object, GDExtensionInterfaceRefSetObject);
|
||||
LOAD_PROC_ADDRESS(script_instance_create, GDExtensionInterfaceScriptInstanceCreate);
|
||||
LOAD_PROC_ADDRESS(script_instance_create2, GDExtensionInterfaceScriptInstanceCreate2);
|
||||
LOAD_PROC_ADDRESS(placeholder_script_instance_create, GDExtensionInterfacePlaceHolderScriptInstanceCreate);
|
||||
LOAD_PROC_ADDRESS(placeholder_script_instance_update, GDExtensionInterfacePlaceHolderScriptInstanceUpdate);
|
||||
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_class2, GDExtensionInterfaceClassdbRegisterExtensionClass2);
|
||||
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_indexed, GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_group, GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_subgroup, GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_signal, GDExtensionInterfaceClassdbRegisterExtensionClassSignal);
|
||||
|
||||
113
src/variant/callable_custom.cpp
Normal file
113
src/variant/callable_custom.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/**************************************************************************/
|
||||
/* callable_custom.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include <godot_cpp/variant/callable_custom.hpp>
|
||||
|
||||
#include <godot_cpp/core/object.hpp>
|
||||
#include <godot_cpp/variant/callable.hpp>
|
||||
|
||||
namespace godot {
|
||||
|
||||
static void callable_custom_call(void *p_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) {
|
||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
||||
callable_custom->call((const Variant **)p_args, p_argument_count, *(Variant *)r_return, *r_error);
|
||||
}
|
||||
|
||||
static GDExtensionBool callable_custom_is_valid(void *p_userdata) {
|
||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
||||
return callable_custom->is_valid();
|
||||
}
|
||||
|
||||
static void callable_custom_free(void *p_userdata) {
|
||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
||||
memdelete(callable_custom);
|
||||
}
|
||||
|
||||
static uint32_t callable_custom_hash(void *p_userdata) {
|
||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
||||
return callable_custom->hash();
|
||||
}
|
||||
|
||||
static void callable_custom_to_string(void *p_userdata, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) {
|
||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
||||
*((String *)r_out) = callable_custom->get_as_text();
|
||||
*r_is_valid = true;
|
||||
}
|
||||
|
||||
static GDExtensionBool callable_custom_equal_func(void *p_a, void *p_b) {
|
||||
CallableCustom *a = (CallableCustom *)p_a;
|
||||
CallableCustom *b = (CallableCustom *)p_b;
|
||||
CallableCustom::CompareEqualFunc func_a = a->get_compare_equal_func();
|
||||
CallableCustom::CompareEqualFunc func_b = b->get_compare_equal_func();
|
||||
if (func_a != func_b) {
|
||||
return false;
|
||||
}
|
||||
return func_a(a, b);
|
||||
}
|
||||
|
||||
static GDExtensionBool callable_custom_less_than_func(void *p_a, void *p_b) {
|
||||
CallableCustom *a = (CallableCustom *)p_a;
|
||||
CallableCustom *b = (CallableCustom *)p_b;
|
||||
CallableCustom::CompareEqualFunc func_a = a->get_compare_less_func();
|
||||
CallableCustom::CompareEqualFunc func_b = b->get_compare_less_func();
|
||||
if (func_a != func_b) {
|
||||
// Just compare the addresses.
|
||||
return p_a < p_b;
|
||||
}
|
||||
return func_a(a, b);
|
||||
}
|
||||
|
||||
bool CallableCustom::is_valid() const {
|
||||
// The same default implementation as in Godot.
|
||||
return ObjectDB::get_instance(get_object());
|
||||
}
|
||||
|
||||
Callable::Callable(CallableCustom *p_callable_custom) {
|
||||
GDExtensionCallableCustomInfo info = {};
|
||||
info.callable_userdata = p_callable_custom;
|
||||
info.token = internal::token;
|
||||
info.object_id = p_callable_custom->get_object();
|
||||
info.call_func = &callable_custom_call;
|
||||
info.is_valid_func = &callable_custom_is_valid;
|
||||
info.free_func = &callable_custom_free;
|
||||
info.hash_func = &callable_custom_hash;
|
||||
info.equal_func = &callable_custom_equal_func;
|
||||
info.less_than_func = &callable_custom_less_than_func;
|
||||
info.to_string_func = &callable_custom_to_string;
|
||||
|
||||
::godot::internal::gdextension_interface_callable_custom_create(_native_ptr(), &info);
|
||||
}
|
||||
|
||||
CallableCustom *Callable::get_custom() const {
|
||||
CallableCustomBase *callable_custom = (CallableCustomBase *)::godot::internal::gdextension_interface_callable_custom_get_userdata(_native_ptr(), internal::token);
|
||||
return dynamic_cast<CallableCustom *>(callable_custom);
|
||||
}
|
||||
|
||||
} // namespace godot
|
||||
114
src/variant/callable_method_pointer.cpp
Normal file
114
src/variant/callable_method_pointer.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/**************************************************************************/
|
||||
/* callable_method_pointer.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include <godot_cpp/variant/callable_method_pointer.hpp>
|
||||
|
||||
#include <godot_cpp/templates/hashfuncs.hpp>
|
||||
|
||||
namespace godot {
|
||||
|
||||
static void custom_callable_mp_call(void *p_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) {
|
||||
CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata;
|
||||
callable_method_pointer->call((const Variant **)p_args, p_argument_count, *(Variant *)r_return, *r_error);
|
||||
}
|
||||
|
||||
static GDExtensionBool custom_callable_mp_is_valid(void *p_userdata) {
|
||||
CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata;
|
||||
ObjectID object = callable_method_pointer->get_object();
|
||||
return object == ObjectID() || ObjectDB::get_instance(object);
|
||||
}
|
||||
|
||||
static void custom_callable_mp_free(void *p_userdata) {
|
||||
CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata;
|
||||
memdelete(callable_method_pointer);
|
||||
}
|
||||
|
||||
static uint32_t custom_callable_mp_hash(void *p_userdata) {
|
||||
CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata;
|
||||
return callable_method_pointer->get_hash();
|
||||
}
|
||||
|
||||
static GDExtensionBool custom_callable_mp_equal_func(void *p_a, void *p_b) {
|
||||
CallableCustomMethodPointerBase *a = (CallableCustomMethodPointerBase *)p_a;
|
||||
CallableCustomMethodPointerBase *b = (CallableCustomMethodPointerBase *)p_b;
|
||||
|
||||
if (a->get_comp_size() != b->get_comp_size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return memcmp(a->get_comp_ptr(), b->get_comp_ptr(), a->get_comp_size() * 4) == 0;
|
||||
}
|
||||
|
||||
static GDExtensionBool custom_callable_mp_less_than_func(void *p_a, void *p_b) {
|
||||
CallableCustomMethodPointerBase *a = (CallableCustomMethodPointerBase *)p_a;
|
||||
CallableCustomMethodPointerBase *b = (CallableCustomMethodPointerBase *)p_b;
|
||||
|
||||
if (a->get_comp_size() != b->get_comp_size()) {
|
||||
return a->get_comp_size() < b->get_comp_size();
|
||||
}
|
||||
|
||||
return memcmp(a->get_comp_ptr(), b->get_comp_ptr(), a->get_comp_size() * 4) < 0;
|
||||
}
|
||||
|
||||
void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_ptr_size) {
|
||||
comp_ptr = p_base_ptr;
|
||||
comp_size = p_ptr_size / 4;
|
||||
|
||||
for (uint32_t i = 0; i < comp_size; i++) {
|
||||
if (i == 0) {
|
||||
h = hash_murmur3_one_32(comp_ptr[i]);
|
||||
} else {
|
||||
h = hash_murmur3_one_32(comp_ptr[i], h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_method_pointer) {
|
||||
GDExtensionCallableCustomInfo info = {};
|
||||
info.callable_userdata = p_callable_method_pointer;
|
||||
info.token = internal::token;
|
||||
info.object_id = p_callable_method_pointer->get_object();
|
||||
info.call_func = &custom_callable_mp_call;
|
||||
info.is_valid_func = &custom_callable_mp_is_valid;
|
||||
info.free_func = &custom_callable_mp_free;
|
||||
info.hash_func = &custom_callable_mp_hash;
|
||||
info.equal_func = &custom_callable_mp_equal_func;
|
||||
info.less_than_func = &custom_callable_mp_less_than_func;
|
||||
|
||||
Callable callable;
|
||||
::godot::internal::gdextension_interface_callable_custom_create(callable._native_ptr(), &info);
|
||||
return callable;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace godot
|
||||
@@ -289,6 +289,10 @@ CharWideString String::wide_string() const {
|
||||
return str;
|
||||
}
|
||||
|
||||
Error String::resize(int64_t p_size) {
|
||||
return (Error)internal::gdextension_interface_string_resize(_native_ptr(), p_size);
|
||||
}
|
||||
|
||||
String &String::operator=(const char *p_str) {
|
||||
*this = String(p_str);
|
||||
return *this;
|
||||
@@ -454,8 +458,9 @@ String operator+(char32_t p_char, const String &p_str) {
|
||||
return String::chr(p_char) + p_str;
|
||||
}
|
||||
|
||||
StringName::StringName(const char *from) :
|
||||
StringName(String(from)) {}
|
||||
StringName::StringName(const char *from, bool p_static) {
|
||||
internal::gdextension_interface_string_name_new_with_latin1_chars(&opaque, from, p_static);
|
||||
}
|
||||
|
||||
StringName::StringName(const wchar_t *from) :
|
||||
StringName(String(from)) {}
|
||||
|
||||
@@ -72,7 +72,7 @@ endif()
|
||||
|
||||
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
|
||||
# saves around 20% of binary size and very significant build time (GH-80513).
|
||||
option(GODOT_DISABLE_EXCEPTIONS OFF "Force disabling exception handling code")
|
||||
option(GODOT_DISABLE_EXCEPTIONS ON "Force disabling exception handling code")
|
||||
if (GODOT_DISABLE_EXCEPTIONS)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -D_HAS_EXCEPTIONS=0")
|
||||
|
||||
@@ -23,6 +23,17 @@ if env["platform"] == "macos":
|
||||
),
|
||||
source=sources,
|
||||
)
|
||||
elif env["platform"] == "ios":
|
||||
if env["ios_simulator"]:
|
||||
library = env.StaticLibrary(
|
||||
"project/bin/libgdexample.{}.{}.simulator.a".format(env["platform"], env["target"]),
|
||||
source=sources,
|
||||
)
|
||||
else:
|
||||
library = env.StaticLibrary(
|
||||
"project/bin/libgdexample.{}.{}.a".format(env["platform"], env["target"]),
|
||||
source=sources,
|
||||
)
|
||||
else:
|
||||
library = env.SharedLibrary(
|
||||
"project/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
|
||||
|
||||
7
test/generate_xcframework.sh
Executable file
7
test/generate_xcframework.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
scons arch=universal ios_simulator=yes platform=ios target=$1 $2
|
||||
scons arch=arm64 ios_simulator=no platform=ios target=$1 $2
|
||||
|
||||
xcodebuild -create-xcframework -library ./project/bin/libgdexample.ios.$1.a -library ./project/bin/libgdexample.ios.$1.simulator.a -output ./project/bin/libgdexample.ios.$1.xcframework
|
||||
xcodebuild -create-xcframework -library ../bin/libgodot-cpp.ios.$1.arm64.a -library ../bin/libgodot-cpp.ios.$1.universal.simulator.a -output ./project/bin/libgodot-cpp.ios.$1.xcframework
|
||||
@@ -11,8 +11,14 @@ windows.debug.x86_32 = "res://bin/libgdexample.windows.template_debug.x86_32.dll
|
||||
windows.release.x86_32 = "res://bin/libgdexample.windows.template_release.x86_32.dll"
|
||||
windows.debug.x86_64 = "res://bin/libgdexample.windows.template_debug.x86_64.dll"
|
||||
windows.release.x86_64 = "res://bin/libgdexample.windows.template_release.x86_64.dll"
|
||||
windows.debug.arm64 = "res://bin/libgdexample.windows.template_debug.arm64.dll"
|
||||
windows.release.arm64 = "res://bin/libgdexample.windows.template_release.arm64.dll"
|
||||
linux.debug.x86_32 = "res://bin/libgdexample.linux.template_debug.x86_32.so"
|
||||
linux.release.x86_32 = "res://bin/libgdexample.linux.template_release.x86_32.so"
|
||||
linux.debug.x86_64 = "res://bin/libgdexample.linux.template_debug.x86_64.so"
|
||||
linux.release.x86_64 = "res://bin/libgdexample.linux.template_release.x86_64.so"
|
||||
linux.debug.arm32 = "res://bin/libgdexample.linux.template_debug.arm32.so"
|
||||
linux.release.arm32 = "res://bin/libgdexample.linux.template_release.arm32.so"
|
||||
linux.debug.arm64 = "res://bin/libgdexample.linux.template_debug.arm64.so"
|
||||
linux.release.arm64 = "res://bin/libgdexample.linux.template_release.arm64.so"
|
||||
linux.debug.rv64 = "res://bin/libgdexample.linux.template_debug.rv64.so"
|
||||
@@ -21,5 +27,15 @@ android.debug.x86_64 = "res://bin/libgdexample.android.template_debug.x86_64.so"
|
||||
android.release.x86_64 = "res://bin/libgdexample.android.template_release.x86_64.so"
|
||||
android.debug.arm64 = "res://bin/libgdexample.android.template_debug.arm64.so"
|
||||
android.release.arm64 = "res://bin/libgdexample.android.template_release.arm64.so"
|
||||
ios.debug = "res://bin/libgdexample.ios.template_debug.xcframework"
|
||||
ios.release = "res://bin/libgdexample.ios.template_release.xcframework"
|
||||
web.debug.wasm32 = "res://bin/libgdexample.web.template_debug.wasm32.wasm"
|
||||
web.release.wasm32 = "res://bin/libgdexample.web.template_release.wasm32.wasm"
|
||||
|
||||
[dependencies]
|
||||
ios.debug = {
|
||||
"res://bin/libgodot-cpp.ios.template_debug.xcframework": ""
|
||||
}
|
||||
ios.release = {
|
||||
"res://bin/libgodot-cpp.ios.template_release.xcframework": ""
|
||||
}
|
||||
|
||||
@@ -26,6 +26,10 @@ func _ready():
|
||||
# Property list.
|
||||
example.property_from_list = Vector3(100, 200, 300)
|
||||
assert_equal(example.property_from_list, Vector3(100, 200, 300))
|
||||
var prop_list = example.get_property_list()
|
||||
for prop_info in prop_list:
|
||||
if prop_info['name'] == 'mouse_filter':
|
||||
assert_equal(prop_info['usage'], PROPERTY_USAGE_NO_EDITOR)
|
||||
|
||||
# Call simple methods.
|
||||
example.simple_func()
|
||||
@@ -79,6 +83,9 @@ func _ready():
|
||||
var array: Array[int] = [1, 2, 3]
|
||||
assert_equal(example.test_tarray_arg(array), 6)
|
||||
|
||||
example.callable_bind()
|
||||
assert_equal(custom_signal_emitted, ["bound", 11])
|
||||
|
||||
# String += operator
|
||||
assert_equal(example.test_string_ops(), "ABCĎE")
|
||||
|
||||
@@ -89,6 +96,62 @@ func _ready():
|
||||
assert_equal(example.test_string_is_fourty_two("blah"), false)
|
||||
assert_equal(example.test_string_is_fourty_two("fourty two"), true)
|
||||
|
||||
# String::resize().
|
||||
assert_equal(example.test_string_resize("What"), "What!?")
|
||||
|
||||
# mp_callable() with void method.
|
||||
var mp_callable: Callable = example.test_callable_mp()
|
||||
assert_equal(mp_callable.is_valid(), true)
|
||||
mp_callable.call(example, "void", 36)
|
||||
assert_equal(custom_signal_emitted, ["unbound_method1: Example - void", 36])
|
||||
|
||||
# Check that it works with is_connected().
|
||||
assert_equal(example.renamed.is_connected(mp_callable), false)
|
||||
example.renamed.connect(mp_callable)
|
||||
assert_equal(example.renamed.is_connected(mp_callable), true)
|
||||
# Make sure a new object is still treated as equivalent.
|
||||
assert_equal(example.renamed.is_connected(example.test_callable_mp()), true)
|
||||
assert_equal(mp_callable.hash(), example.test_callable_mp().hash())
|
||||
example.renamed.disconnect(mp_callable)
|
||||
assert_equal(example.renamed.is_connected(mp_callable), false)
|
||||
|
||||
# mp_callable() with return value.
|
||||
var mp_callable_ret: Callable = example.test_callable_mp_ret()
|
||||
assert_equal(mp_callable_ret.call(example, "test", 77), "unbound_method2: Example - test - 77")
|
||||
|
||||
# mp_callable() with const method and return value.
|
||||
var mp_callable_retc: Callable = example.test_callable_mp_retc()
|
||||
assert_equal(mp_callable_retc.call(example, "const", 101), "unbound_method3: Example - const - 101")
|
||||
|
||||
# mp_callable_static() with void method.
|
||||
var mp_callable_static: Callable = example.test_callable_mp_static()
|
||||
mp_callable_static.call(example, "static", 83)
|
||||
assert_equal(custom_signal_emitted, ["unbound_static_method1: Example - static", 83])
|
||||
|
||||
# Check that it works with is_connected().
|
||||
assert_equal(example.renamed.is_connected(mp_callable_static), false)
|
||||
example.renamed.connect(mp_callable_static)
|
||||
assert_equal(example.renamed.is_connected(mp_callable_static), true)
|
||||
# Make sure a new object is still treated as equivalent.
|
||||
assert_equal(example.renamed.is_connected(example.test_callable_mp_static()), true)
|
||||
assert_equal(mp_callable_static.hash(), example.test_callable_mp_static().hash())
|
||||
example.renamed.disconnect(mp_callable_static)
|
||||
assert_equal(example.renamed.is_connected(mp_callable_static), false)
|
||||
|
||||
# mp_callable_static() with return value.
|
||||
var mp_callable_static_ret: Callable = example.test_callable_mp_static_ret()
|
||||
assert_equal(mp_callable_static_ret.call(example, "static-ret", 84), "unbound_static_method2: Example - static-ret - 84")
|
||||
|
||||
# CallableCustom.
|
||||
var custom_callable: Callable = example.test_custom_callable();
|
||||
assert_equal(custom_callable.is_custom(), true);
|
||||
assert_equal(custom_callable.is_valid(), true);
|
||||
assert_equal(custom_callable.call(), "Hi")
|
||||
assert_equal(custom_callable.hash(), 27);
|
||||
assert_equal(custom_callable.get_object(), null);
|
||||
assert_equal(custom_callable.get_method(), "");
|
||||
assert_equal(str(custom_callable), "<MyCallableCustom>");
|
||||
|
||||
# PackedArray iterators
|
||||
assert_equal(example.test_vector_ops(), 105)
|
||||
assert_equal(example.test_vector_init_list(), 105)
|
||||
@@ -156,6 +219,10 @@ func _ready():
|
||||
assert_equal(example.test_bitfield(0), 0)
|
||||
assert_equal(example.test_bitfield(Example.FLAG_ONE | Example.FLAG_TWO), 3)
|
||||
|
||||
# Test variant iterator.
|
||||
assert_equal(example.test_variant_iterator([10, 20, 30]), [15, 25, 35])
|
||||
assert_equal(example.test_variant_iterator(null), "iter_init: not valid")
|
||||
|
||||
# RPCs.
|
||||
assert_equal(example.return_last_rpc_arg(), 0)
|
||||
example.test_rpc(42)
|
||||
@@ -179,6 +246,9 @@ func _ready():
|
||||
var example_child = $ExampleChild
|
||||
assert_equal(example_child.get_value1(), 11)
|
||||
assert_equal(example_child.get_value2(), 33)
|
||||
example_child.notification(NOTIFICATION_ENTER_TREE, true)
|
||||
assert_equal(example_child.get_value1(), 11)
|
||||
assert_equal(example_child.get_value2(), 22)
|
||||
|
||||
exit_with_status()
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ config_version=5
|
||||
|
||||
config/name="GDExtension Test Project"
|
||||
run/main_scene="res://main.tscn"
|
||||
config/features=PackedStringArray("4.1")
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[native_extensions]
|
||||
@@ -21,4 +21,5 @@ paths=["res://example.gdextension"]
|
||||
|
||||
[rendering]
|
||||
|
||||
textures/vram_compression/import_etc2_astc=true
|
||||
environment/defaults/default_environment="res://default_env.tres"
|
||||
|
||||
@@ -15,6 +15,46 @@
|
||||
|
||||
using namespace godot;
|
||||
|
||||
class MyCallableCustom : public CallableCustom {
|
||||
public:
|
||||
virtual uint32_t hash() const {
|
||||
return 27;
|
||||
}
|
||||
|
||||
virtual String get_as_text() const {
|
||||
return "<MyCallableCustom>";
|
||||
}
|
||||
|
||||
static bool compare_equal_func(const CallableCustom *p_a, const CallableCustom *p_b) {
|
||||
return p_a == p_b;
|
||||
}
|
||||
|
||||
virtual CompareEqualFunc get_compare_equal_func() const {
|
||||
return &MyCallableCustom::compare_equal_func;
|
||||
}
|
||||
|
||||
static bool compare_less_func(const CallableCustom *p_a, const CallableCustom *p_b) {
|
||||
return (void *)p_a < (void *)p_b;
|
||||
}
|
||||
|
||||
virtual CompareLessFunc get_compare_less_func() const {
|
||||
return &MyCallableCustom::compare_less_func;
|
||||
}
|
||||
|
||||
bool is_valid() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual ObjectID get_object() const {
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const {
|
||||
r_return_value = "Hi";
|
||||
r_call_error.error = GDEXTENSION_CALL_OK;
|
||||
}
|
||||
};
|
||||
|
||||
void ExampleRef::set_id(int p_id) {
|
||||
id = p_id;
|
||||
}
|
||||
@@ -125,6 +165,14 @@ bool Example::_property_get_revert(const StringName &p_name, Variant &r_property
|
||||
}
|
||||
};
|
||||
|
||||
void Example::_validate_property(PropertyInfo &p_property) const {
|
||||
String name = p_property.name;
|
||||
// Test hiding the "mouse_filter" property from the editor.
|
||||
if (name == "mouse_filter") {
|
||||
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
}
|
||||
}
|
||||
|
||||
void Example::_bind_methods() {
|
||||
// Methods.
|
||||
ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
|
||||
@@ -147,6 +195,7 @@ void Example::_bind_methods() {
|
||||
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_string_is_fourty_two"), &Example::test_string_is_fourty_two);
|
||||
ClassDB::bind_method(D_METHOD("test_string_resize"), &Example::test_string_resize);
|
||||
ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_ops);
|
||||
ClassDB::bind_method(D_METHOD("test_vector_init_list"), &Example::test_vector_init_list);
|
||||
|
||||
@@ -163,13 +212,23 @@ void Example::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_variant_call", "variant"), &Example::test_variant_call);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_callable_mp"), &Example::test_callable_mp);
|
||||
ClassDB::bind_method(D_METHOD("test_callable_mp_ret"), &Example::test_callable_mp_ret);
|
||||
ClassDB::bind_method(D_METHOD("test_callable_mp_retc"), &Example::test_callable_mp_retc);
|
||||
ClassDB::bind_method(D_METHOD("test_callable_mp_static"), &Example::test_callable_mp_static);
|
||||
ClassDB::bind_method(D_METHOD("test_callable_mp_static_ret"), &Example::test_callable_mp_static_ret);
|
||||
ClassDB::bind_method(D_METHOD("test_custom_callable"), &Example::test_custom_callable);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_bitfield", "flags"), &Example::test_bitfield);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_variant_iterator", "input"), &Example::test_variant_iterator);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_rpc", "value"), &Example::test_rpc);
|
||||
ClassDB::bind_method(D_METHOD("test_send_rpc", "value"), &Example::test_send_rpc);
|
||||
ClassDB::bind_method(D_METHOD("return_last_rpc_arg"), &Example::return_last_rpc_arg);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("def_args", "a", "b"), &Example::def_args, DEFVAL(100), DEFVAL(200));
|
||||
ClassDB::bind_method(D_METHOD("callable_bind"), &Example::callable_bind);
|
||||
ClassDB::bind_method(D_METHOD("test_post_initialize"), &Example::test_post_initialize);
|
||||
|
||||
ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
|
||||
@@ -327,6 +386,16 @@ bool Example::test_string_is_fourty_two(const String &p_string) const {
|
||||
return strcmp(p_string.utf8().ptr(), "fourty two") == 0;
|
||||
}
|
||||
|
||||
String Example::test_string_resize(String p_string) const {
|
||||
int orig_len = p_string.length();
|
||||
p_string.resize(orig_len + 3);
|
||||
char32_t *data = p_string.ptrw();
|
||||
data[orig_len + 0] = '!';
|
||||
data[orig_len + 1] = '?';
|
||||
data[orig_len + 2] = '\0';
|
||||
return p_string;
|
||||
}
|
||||
|
||||
int Example::test_vector_ops() const {
|
||||
PackedInt32Array arr;
|
||||
arr.push_back(10);
|
||||
@@ -349,6 +418,68 @@ int Example::test_vector_init_list() const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
Callable Example::test_callable_mp() {
|
||||
return callable_mp(this, &Example::unbound_method1);
|
||||
}
|
||||
|
||||
Callable Example::test_callable_mp_ret() {
|
||||
return callable_mp(this, &Example::unbound_method2);
|
||||
}
|
||||
|
||||
Callable Example::test_callable_mp_retc() const {
|
||||
return callable_mp(this, &Example::unbound_method3);
|
||||
}
|
||||
|
||||
Callable Example::test_callable_mp_static() const {
|
||||
return callable_mp_static(&Example::unbound_static_method1);
|
||||
}
|
||||
|
||||
Callable Example::test_callable_mp_static_ret() const {
|
||||
return callable_mp_static(&Example::unbound_static_method2);
|
||||
}
|
||||
|
||||
Callable Example::test_custom_callable() const {
|
||||
return Callable(memnew(MyCallableCustom));
|
||||
}
|
||||
|
||||
void Example::unbound_method1(Object *p_object, String p_string, int p_int) {
|
||||
String test = "unbound_method1: ";
|
||||
test += p_object->get_class();
|
||||
test += " - " + p_string;
|
||||
emit_custom_signal(test, p_int);
|
||||
}
|
||||
|
||||
String Example::unbound_method2(Object *p_object, String p_string, int p_int) {
|
||||
String test = "unbound_method2: ";
|
||||
test += p_object->get_class();
|
||||
test += " - " + p_string;
|
||||
test += " - " + itos(p_int);
|
||||
return test;
|
||||
}
|
||||
|
||||
String Example::unbound_method3(Object *p_object, String p_string, int p_int) const {
|
||||
String test = "unbound_method3: ";
|
||||
test += p_object->get_class();
|
||||
test += " - " + p_string;
|
||||
test += " - " + itos(p_int);
|
||||
return test;
|
||||
}
|
||||
|
||||
void Example::unbound_static_method1(Example *p_object, String p_string, int p_int) {
|
||||
String test = "unbound_static_method1: ";
|
||||
test += p_object->get_class();
|
||||
test += " - " + p_string;
|
||||
p_object->emit_custom_signal(test, p_int);
|
||||
}
|
||||
|
||||
String Example::unbound_static_method2(Object *p_object, String p_string, int p_int) {
|
||||
String test = "unbound_static_method2: ";
|
||||
test += p_object->get_class();
|
||||
test += " - " + p_string;
|
||||
test += " - " + itos(p_int);
|
||||
return test;
|
||||
}
|
||||
|
||||
int Example::test_tarray_arg(const TypedArray<int64_t> &p_array) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < p_array.size(); i++) {
|
||||
@@ -420,6 +551,41 @@ BitField<Example::Flags> Example::test_bitfield(BitField<Flags> flags) {
|
||||
return flags;
|
||||
}
|
||||
|
||||
Variant Example::test_variant_iterator(const Variant &p_input) {
|
||||
Array output;
|
||||
|
||||
Variant iter;
|
||||
|
||||
bool is_init_valid = true;
|
||||
if (!p_input.iter_init(iter, is_init_valid)) {
|
||||
if (!is_init_valid) {
|
||||
return "iter_init: not valid";
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
bool is_iter_next_valid = true;
|
||||
bool is_iter_get_valid = true;
|
||||
do {
|
||||
if (!is_iter_next_valid) {
|
||||
return "iter_next: not valid";
|
||||
}
|
||||
|
||||
Variant value = p_input.iter_get(iter, is_iter_get_valid);
|
||||
if (!is_iter_get_valid) {
|
||||
return "iter_get: not valid";
|
||||
}
|
||||
output.push_back(((int)value) + 5);
|
||||
|
||||
} while (p_input.iter_next(iter, is_iter_next_valid));
|
||||
|
||||
if (!is_iter_next_valid) {
|
||||
return "iter_next: not valid";
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void Example::test_rpc(int p_value) {
|
||||
last_rpc_arg = p_value;
|
||||
}
|
||||
@@ -432,6 +598,11 @@ int Example::return_last_rpc_arg() {
|
||||
return last_rpc_arg;
|
||||
}
|
||||
|
||||
void Example::callable_bind() {
|
||||
Callable c = Callable(this, "emit_custom_signal").bind("bound", 11);
|
||||
c.call();
|
||||
}
|
||||
|
||||
// Properties.
|
||||
void Example::set_custom_position(const Vector2 &pos) {
|
||||
custom_position = pos;
|
||||
|
||||
@@ -71,6 +71,7 @@ protected:
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
bool _property_can_revert(const StringName &p_name) const;
|
||||
bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
|
||||
void _validate_property(PropertyInfo &p_property) const;
|
||||
|
||||
String _to_string() const;
|
||||
|
||||
@@ -126,6 +127,7 @@ public:
|
||||
String test_string_ops() const;
|
||||
String test_str_utility() const;
|
||||
bool test_string_is_fourty_two(const String &p_str) const;
|
||||
String test_string_resize(String p_original) const;
|
||||
int test_vector_ops() const;
|
||||
int test_vector_init_list() const;
|
||||
|
||||
@@ -142,13 +144,30 @@ public:
|
||||
|
||||
Variant test_variant_call(Variant p_variant);
|
||||
|
||||
Callable test_callable_mp();
|
||||
Callable test_callable_mp_ret();
|
||||
Callable test_callable_mp_retc() const;
|
||||
Callable test_callable_mp_static() const;
|
||||
Callable test_callable_mp_static_ret() const;
|
||||
Callable test_custom_callable() const;
|
||||
|
||||
void unbound_method1(Object *p_object, String p_string, int p_int);
|
||||
String unbound_method2(Object *p_object, String p_string, int p_int);
|
||||
String unbound_method3(Object *p_object, String p_string, int p_int) const;
|
||||
static void unbound_static_method1(Example *p_object, String p_string, int p_int);
|
||||
static String unbound_static_method2(Object *p_object, String p_string, int p_int);
|
||||
|
||||
BitField<Flags> test_bitfield(BitField<Flags> flags);
|
||||
|
||||
Variant test_variant_iterator(const Variant &p_input);
|
||||
|
||||
// RPC
|
||||
void test_rpc(int p_value);
|
||||
void test_send_rpc(int p_value);
|
||||
int return_last_rpc_arg();
|
||||
|
||||
void callable_bind();
|
||||
|
||||
// Property.
|
||||
void set_custom_position(const Vector2 &pos);
|
||||
Vector2 get_custom_position() const;
|
||||
@@ -180,11 +199,22 @@ protected:
|
||||
static void _bind_methods() {}
|
||||
};
|
||||
|
||||
class ExampleAbstract : public Object {
|
||||
GDCLASS(ExampleAbstract, Object);
|
||||
class ExampleAbstractBase : public Object {
|
||||
GDCLASS(ExampleAbstractBase, Object);
|
||||
|
||||
protected:
|
||||
static void _bind_methods() {}
|
||||
|
||||
virtual int test_function() = 0;
|
||||
};
|
||||
|
||||
class ExampleConcrete : public ExampleAbstractBase {
|
||||
GDCLASS(ExampleConcrete, ExampleAbstractBase);
|
||||
|
||||
protected:
|
||||
static void _bind_methods() {}
|
||||
|
||||
virtual int test_function() override { return 25; }
|
||||
};
|
||||
|
||||
class ExampleBase : public Node {
|
||||
|
||||
@@ -25,7 +25,8 @@ void initialize_example_module(ModuleInitializationLevel p_level) {
|
||||
GDREGISTER_CLASS(ExampleMin);
|
||||
GDREGISTER_CLASS(Example);
|
||||
GDREGISTER_VIRTUAL_CLASS(ExampleVirtual);
|
||||
GDREGISTER_ABSTRACT_CLASS(ExampleAbstract);
|
||||
GDREGISTER_ABSTRACT_CLASS(ExampleAbstractBase);
|
||||
GDREGISTER_CLASS(ExampleConcrete);
|
||||
GDREGISTER_CLASS(ExampleBase);
|
||||
GDREGISTER_CLASS(ExampleChild);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,14 @@ def generate(env):
|
||||
elif env.get("is_msvc", False):
|
||||
env.Append(CXXFLAGS=["/EHsc"])
|
||||
|
||||
if not env.get("is_msvc", False):
|
||||
if env["symbols_visibility"] == "visible":
|
||||
env.Append(CCFLAGS=["-fvisibility=default"])
|
||||
env.Append(LINKFLAGS=["-fvisibility=default"])
|
||||
elif env["symbols_visibility"] == "hidden":
|
||||
env.Append(CCFLAGS=["-fvisibility=hidden"])
|
||||
env.Append(LINKFLAGS=["-fvisibility=hidden"])
|
||||
|
||||
# Set optimize and debug_symbols flags.
|
||||
# "custom" means do nothing and let users set their own optimization flags.
|
||||
if env.get("is_msvc", False):
|
||||
|
||||
@@ -285,9 +285,24 @@ def options(opts, env):
|
||||
|
||||
opts.Add(
|
||||
BoolVariable(
|
||||
"disable_exceptions",
|
||||
"Force disabling exception handling code",
|
||||
default=env.get("disable_exceptions", False),
|
||||
key="use_hot_reload",
|
||||
help="Enable the extra accounting required to support hot reload.",
|
||||
default=env.get("use_hot_reload", None),
|
||||
)
|
||||
)
|
||||
|
||||
opts.Add(
|
||||
BoolVariable(
|
||||
"disable_exceptions", "Force disabling exception handling code", default=env.get("disable_exceptions", True)
|
||||
)
|
||||
)
|
||||
|
||||
opts.Add(
|
||||
EnumVariable(
|
||||
key="symbols_visibility",
|
||||
help="Symbols visibility on GNU platforms. Use 'auto' to apply the default value.",
|
||||
default=env.get("symbols_visibility", "hidden"),
|
||||
allowed_values=["auto", "visible", "hidden"],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -356,6 +371,7 @@ def generate(env):
|
||||
print("Building for architecture " + env["arch"] + " on platform " + env["platform"])
|
||||
|
||||
# These defaults may be needed by platform tools
|
||||
env.use_hot_reload = env.get("use_hot_reload", env["target"] != "template_release")
|
||||
env.editor_build = env["target"] == "editor"
|
||||
env.dev_build = env["dev_build"]
|
||||
env.debug_features = env["target"] in ["editor", "template_debug"]
|
||||
@@ -377,6 +393,9 @@ def generate(env):
|
||||
|
||||
tool.generate(env)
|
||||
|
||||
if env.use_hot_reload:
|
||||
env.Append(CPPDEFINES=["HOT_RELOAD_ENABLED"])
|
||||
|
||||
if env.editor_build:
|
||||
env.Append(CPPDEFINES=["TOOLS_ENABLED"])
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ def has_ios_osxcross():
|
||||
|
||||
def options(opts):
|
||||
opts.Add(BoolVariable("ios_simulator", "Target iOS Simulator", False))
|
||||
opts.Add("ios_min_version", "Target minimum iphoneos/iphonesimulator version", "10.0")
|
||||
opts.Add("ios_min_version", "Target minimum iphoneos/iphonesimulator version", "12.0")
|
||||
opts.Add(
|
||||
"IOS_TOOLCHAIN_PATH",
|
||||
"Path to iOS toolchain",
|
||||
|
||||
@@ -15,6 +15,9 @@ def generate(env):
|
||||
if env["use_llvm"]:
|
||||
clang.generate(env)
|
||||
clangxx.generate(env)
|
||||
elif env.use_hot_reload:
|
||||
# Required for extensions to truly unload.
|
||||
env.Append(CXXFLAGS=["-fno-gnu-unique"])
|
||||
|
||||
env.Append(CCFLAGS=["-fPIC", "-Wwrite-strings"])
|
||||
env.Append(LINKFLAGS=["-Wl,-R,'$$ORIGIN'"])
|
||||
|
||||
Reference in New Issue
Block a user