summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/SCsub12
-rw-r--r--core/config/engine.cpp2
-rw-r--r--core/config/project_settings.cpp24
-rw-r--r--core/config/project_settings.h8
-rw-r--r--core/core_bind.cpp30
-rw-r--r--core/core_bind.h14
-rw-r--r--core/core_builders.py1
-rw-r--r--core/extension/gdextension.cpp109
-rw-r--r--core/extension/gdextension.h12
-rw-r--r--core/extension/gdextension_interface.cpp106
-rw-r--r--core/extension/gdextension_interface.h126
-rw-r--r--core/input/SCsub2
-rw-r--r--core/input/input.cpp4
-rw-r--r--core/input/input.h3
-rw-r--r--core/input/input_map.cpp29
-rw-r--r--core/input/input_map.h4
-rw-r--r--core/io/resource.cpp17
-rw-r--r--core/io/resource.h2
-rw-r--r--core/io/resource_format_binary.cpp31
-rw-r--r--core/io/resource_format_binary.h1
-rw-r--r--core/io/resource_loader.cpp17
-rw-r--r--core/io/resource_loader.h8
-rw-r--r--core/math/aabb.h6
-rw-r--r--core/math/basis.cpp6
-rw-r--r--core/math/basis.h84
-rw-r--r--core/math/delaunay_2d.h2
-rw-r--r--core/math/geometry_3d.cpp2
-rw-r--r--core/math/projection.h4
-rw-r--r--core/math/quaternion.cpp10
-rw-r--r--core/math/quaternion.h78
-rw-r--r--core/math/random_number_generator.cpp1
-rw-r--r--core/math/random_number_generator.h2
-rw-r--r--core/math/random_pcg.cpp21
-rw-r--r--core/math/random_pcg.h5
-rw-r--r--core/math/rect2.h2
-rw-r--r--core/math/transform_2d.cpp26
-rw-r--r--core/math/transform_2d.h52
-rw-r--r--core/math/transform_3d.cpp14
-rw-r--r--core/math/transform_3d.h20
-rw-r--r--core/math/vector2.cpp10
-rw-r--r--core/math/vector2.h92
-rw-r--r--core/math/vector2i.cpp30
-rw-r--r--core/math/vector2i.h34
-rw-r--r--core/math/vector3.cpp20
-rw-r--r--core/math/vector3.h74
-rw-r--r--core/math/vector3i.h38
-rw-r--r--core/math/vector4.cpp8
-rw-r--r--core/math/vector4.h50
-rw-r--r--core/math/vector4i.h38
-rw-r--r--core/object/class_db.cpp259
-rw-r--r--core/object/class_db.h31
-rw-r--r--core/object/method_bind.h42
-rw-r--r--core/object/object.compat.inc40
-rw-r--r--core/object/object.cpp83
-rw-r--r--core/object/object.h17
-rw-r--r--core/object/script_instance.h2
-rw-r--r--core/object/script_language.cpp7
-rw-r--r--core/object/script_language.h14
-rw-r--r--core/object/script_language_extension.cpp1
-rw-r--r--core/object/script_language_extension.h36
-rw-r--r--core/object/worker_thread_pool.cpp2
-rw-r--r--core/os/midi_driver.cpp3
-rw-r--r--core/os/midi_driver.h2
-rw-r--r--core/string/char_range.inc1314
-rw-r--r--core/string/char_utils.h43
-rw-r--r--core/string/node_path.cpp33
-rw-r--r--core/string/node_path.h2
-rw-r--r--core/string/translation.compat.inc46
-rw-r--r--core/string/translation.cpp76
-rw-r--r--core/string/translation.h22
-rw-r--r--core/string/ustring.cpp33
-rw-r--r--core/string/ustring.h37
-rw-r--r--core/templates/rid_owner.h2
-rw-r--r--core/templates/search_array.h10
-rw-r--r--core/templates/sort_array.h72
-rw-r--r--core/variant/callable.cpp32
-rw-r--r--core/variant/callable.h4
-rw-r--r--core/variant/variant.h2
-rw-r--r--core/variant/variant_call.cpp2
-rw-r--r--core/variant/variant_construct.h2
-rw-r--r--core/variant/variant_internal.h2
-rw-r--r--core/variant/variant_setget.cpp8
-rw-r--r--core/version.h6
83 files changed, 2977 insertions, 601 deletions
diff --git a/core/SCsub b/core/SCsub
index 3b1a7ca79a..1f2166937a 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -202,27 +202,23 @@ env.Depends(
env.CommandNoCache(
"#core/io/certs_compressed.gen.h",
"#thirdparty/certs/ca-certificates.crt",
- env.Run(core_builders.make_certs_header, "Building ca-certificates header."),
+ env.Run(core_builders.make_certs_header),
)
# Authors
env.Depends("#core/authors.gen.h", "../AUTHORS.md")
-env.CommandNoCache(
- "#core/authors.gen.h", "../AUTHORS.md", env.Run(core_builders.make_authors_header, "Generating authors header.")
-)
+env.CommandNoCache("#core/authors.gen.h", "../AUTHORS.md", env.Run(core_builders.make_authors_header))
# Donors
env.Depends("#core/donors.gen.h", "../DONORS.md")
-env.CommandNoCache(
- "#core/donors.gen.h", "../DONORS.md", env.Run(core_builders.make_donors_header, "Generating donors header.")
-)
+env.CommandNoCache("#core/donors.gen.h", "../DONORS.md", env.Run(core_builders.make_donors_header))
# License
env.Depends("#core/license.gen.h", ["../COPYRIGHT.txt", "../LICENSE.txt"])
env.CommandNoCache(
"#core/license.gen.h",
["../COPYRIGHT.txt", "../LICENSE.txt"],
- env.Run(core_builders.make_license_header, "Generating license header."),
+ env.Run(core_builders.make_license_header),
)
# Chain load SCsubs
diff --git a/core/config/engine.cpp b/core/config/engine.cpp
index 2bb8837849..d714ec42c2 100644
--- a/core/config/engine.cpp
+++ b/core/config/engine.cpp
@@ -114,6 +114,8 @@ Dictionary Engine::get_version_info() const {
String hash = String(VERSION_HASH);
dict["hash"] = hash.is_empty() ? String("unknown") : hash;
+ dict["timestamp"] = VERSION_TIMESTAMP;
+
String stringver = String(dict["major"]) + "." + String(dict["minor"]);
if ((int)dict["patch"] != 0) {
stringver += "." + String(dict["patch"]);
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index d3cbae2f29..f5baf1a27e 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -39,6 +39,7 @@
#include "core/io/file_access_pack.h"
#include "core/io/marshalls.h"
#include "core/os/keyboard.h"
+#include "core/templates/rb_set.h"
#include "core/variant/typed_array.h"
#include "core/variant/variant_parser.h"
#include "core/version.h"
@@ -1093,7 +1094,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
} else if (p_path.ends_with(".binary")) {
return _save_settings_binary(p_path, save_props, p_custom, save_features);
} else {
- ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unknown config file format: " + p_path + ".");
+ ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unknown config file format: " + p_path);
}
}
@@ -1318,6 +1319,26 @@ const HashMap<StringName, HashSet<StringName>> &ProjectSettings::get_scene_group
return scene_groups_cache;
}
+#ifdef TOOLS_ENABLED
+void ProjectSettings::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+ const String pf = p_function;
+ if (p_idx == 0) {
+ if (pf == "has_setting" || pf == "set_setting" || pf == "get_setting" || pf == "get_setting_with_override" ||
+ pf == "set_order" || pf == "get_order" || pf == "set_initial_value" || pf == "set_as_basic" ||
+ pf == "set_as_internal" || pf == "set_restart_if_changed" || pf == "clear") {
+ for (const KeyValue<StringName, VariantContainer> &E : props) {
+ if (E.value.hide_from_editor) {
+ continue;
+ }
+
+ r_options->push_back(String(E.key).quote());
+ }
+ }
+ }
+ Object::get_argument_options(p_function, p_idx, r_options);
+}
+#endif
+
void ProjectSettings::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_setting", "name"), &ProjectSettings::has_setting);
ClassDB::bind_method(D_METHOD("set_setting", "name", "value"), &ProjectSettings::set_setting);
@@ -1514,6 +1535,7 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF_INTERNAL("internationalization/locale/translation_remaps", PackedStringArray());
GLOBAL_DEF_INTERNAL("internationalization/locale/translations", PackedStringArray());
GLOBAL_DEF_INTERNAL("internationalization/locale/translations_pot_files", PackedStringArray());
+ GLOBAL_DEF_INTERNAL("internationalization/locale/translation_add_builtin_strings_to_pot", false);
ProjectSettings::get_singleton()->add_hidden_prefix("input/");
}
diff --git a/core/config/project_settings.h b/core/config/project_settings.h
index 385f93e91e..252b10bd3a 100644
--- a/core/config/project_settings.h
+++ b/core/config/project_settings.h
@@ -32,10 +32,6 @@
#define PROJECT_SETTINGS_H
#include "core/object/class_db.h"
-#include "core/os/thread_safe.h"
-#include "core/templates/hash_map.h"
-#include "core/templates/local_vector.h"
-#include "core/templates/rb_set.h"
template <typename T>
class TypedArray;
@@ -222,6 +218,10 @@ public:
String get_scene_groups_cache_path() const;
void load_scene_groups_cache();
+#ifdef TOOLS_ENABLED
+ virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
+#endif
+
ProjectSettings();
~ProjectSettings();
};
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index f5c69b9b98..a0df1b6240 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -145,6 +145,8 @@ void ResourceLoader::_bind_methods() {
BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE);
BIND_ENUM_CONSTANT(CACHE_MODE_REUSE);
BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE);
+ BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE_DEEP);
+ BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE_DEEP);
}
////// ResourceSaver //////
@@ -1517,6 +1519,30 @@ bool ClassDB::is_class_enabled(const StringName &p_class) const {
return ::ClassDB::is_class_enabled(p_class);
}
+#ifdef TOOLS_ENABLED
+void ClassDB::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+ const String pf = p_function;
+ bool first_argument_is_class = false;
+ if (p_idx == 0) {
+ first_argument_is_class = (pf == "get_inheriters_from_class" || pf == "get_parent_class" ||
+ pf == "class_exists" || pf == "can_instantiate" || pf == "instantiate" ||
+ pf == "class_has_signal" || pf == "class_get_signal" || pf == "class_get_signal_list" ||
+ pf == "class_get_property_list" || pf == "class_get_property" || pf == "class_set_property" ||
+ pf == "class_has_method" || pf == "class_get_method_list" ||
+ pf == "class_get_integer_constant_list" || pf == "class_has_integer_constant" || pf == "class_get_integer_constant" ||
+ pf == "class_has_enum" || pf == "class_get_enum_list" || pf == "class_get_enum_constants" || pf == "class_get_integer_constant_enum" ||
+ pf == "is_class_enabled");
+ }
+ if (first_argument_is_class || pf == "is_parent_class") {
+ for (const String &E : get_class_list()) {
+ r_options->push_back(E.quote());
+ }
+ }
+
+ Object::get_argument_options(p_function, p_idx, r_options);
+}
+#endif
+
void ClassDB::_bind_methods() {
::ClassDB::bind_method(D_METHOD("get_class_list"), &ClassDB::get_class_list);
::ClassDB::bind_method(D_METHOD("get_inheriters_from_class", "class"), &ClassDB::get_inheriters_from_class);
@@ -1723,8 +1749,9 @@ bool Engine::is_printing_error_messages() const {
return ::Engine::get_singleton()->is_printing_error_messages();
}
+#ifdef TOOLS_ENABLED
void Engine::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
- String pf = p_function;
+ const String pf = p_function;
if (p_idx == 0 && (pf == "has_singleton" || pf == "get_singleton" || pf == "unregister_singleton")) {
for (const String &E : get_singleton_list()) {
r_options->push_back(E.quote());
@@ -1732,6 +1759,7 @@ void Engine::get_argument_options(const StringName &p_function, int p_idx, List<
}
Object::get_argument_options(p_function, p_idx, r_options);
}
+#endif
void Engine::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_physics_ticks_per_second", "physics_ticks_per_second"), &Engine::set_physics_ticks_per_second);
diff --git a/core/core_bind.h b/core/core_bind.h
index f884426881..64ab4dd7e2 100644
--- a/core/core_bind.h
+++ b/core/core_bind.h
@@ -63,9 +63,11 @@ public:
};
enum CacheMode {
- CACHE_MODE_IGNORE, // Resource and subresources do not use path cache, no path is set into resource.
- CACHE_MODE_REUSE, // Resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available.
- CACHE_MODE_REPLACE, // Resource and subresource use path cache, but replace existing loaded resources when available with information from disk.
+ CACHE_MODE_IGNORE,
+ CACHE_MODE_REUSE,
+ CACHE_MODE_REPLACE,
+ CACHE_MODE_IGNORE_DEEP,
+ CACHE_MODE_REPLACE_DEEP,
};
static ResourceLoader *get_singleton() { return singleton; }
@@ -458,6 +460,10 @@ public:
bool is_class_enabled(const StringName &p_class) const;
+#ifdef TOOLS_ENABLED
+ virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
+#endif
+
ClassDB() {}
~ClassDB() {}
};
@@ -528,7 +534,9 @@ public:
void set_print_error_messages(bool p_enabled);
bool is_printing_error_messages() const;
+#ifdef TOOLS_ENABLED
virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
+#endif
Engine() { singleton = this; }
};
diff --git a/core/core_builders.py b/core/core_builders.py
index 8b6b87ad83..61b7bd695c 100644
--- a/core/core_builders.py
+++ b/core/core_builders.py
@@ -2,6 +2,7 @@
All such functions are invoked in a subprocess on Windows to prevent build flakiness.
"""
+
import zlib
from platform_methods import subprocess_main
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp
index 9b3282ecba..5d43dceece 100644
--- a/core/extension/gdextension.cpp
+++ b/core/extension/gdextension.cpp
@@ -205,6 +205,7 @@ public:
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
#ifdef TOOLS_ENABLED
ERR_FAIL_COND_V_MSG(!valid, Variant(), vformat("Cannot call invalid GDExtension method bind '%s'. It's probably cached - you may need to restart Godot.", name));
+ ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder(), Variant(), vformat("Cannot call GDExtension method bind '%s' on placeholder instance.", name));
#endif
Variant ret;
GDExtensionClassInstancePtr extension_instance = is_static() ? nullptr : p_object->_get_extension_instance();
@@ -218,6 +219,7 @@ public:
virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
#ifdef TOOLS_ENABLED
ERR_FAIL_COND_MSG(!valid, vformat("Cannot call invalid GDExtension method bind '%s'. It's probably cached - you may need to restart Godot.", name));
+ ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder(), vformat("Cannot call GDExtension method bind '%s' on placeholder instance.", name));
#endif
ERR_FAIL_COND_MSG(vararg, "Vararg methods don't have validated call support. This is most likely an engine bug.");
GDExtensionClassInstancePtr extension_instance = is_static() ? nullptr : p_object->_get_extension_instance();
@@ -249,6 +251,7 @@ public:
virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
#ifdef TOOLS_ENABLED
ERR_FAIL_COND_MSG(!valid, vformat("Cannot call invalid GDExtension method bind '%s'. It's probably cached - you may need to restart Godot.", name));
+ ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder(), vformat("Cannot call GDExtension method bind '%s' on placeholder instance.", name));
#endif
ERR_FAIL_COND_MSG(vararg, "Vararg methods don't have ptrcall support. This is most likely an engine bug.");
GDExtensionClassInstancePtr extension_instance = p_object->_get_extension_instance();
@@ -341,10 +344,11 @@ public:
#ifndef DISABLE_DEPRECATED
void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo *p_extension_funcs) {
- const GDExtensionClassCreationInfo2 class_info2 = {
+ const GDExtensionClassCreationInfo3 class_info3 = {
p_extension_funcs->is_virtual, // GDExtensionBool is_virtual;
p_extension_funcs->is_abstract, // GDExtensionBool is_abstract;
true, // GDExtensionBool is_exposed;
+ false, // GDExtensionBool is_runtime;
p_extension_funcs->set_func, // GDExtensionClassSet set_func;
p_extension_funcs->get_func, // GDExtensionClassGet get_func;
p_extension_funcs->get_property_list_func, // GDExtensionClassGetPropertyList get_property_list_func;
@@ -369,15 +373,45 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library
const ClassCreationDeprecatedInfo legacy = {
p_extension_funcs->notification_func,
};
- _register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info2, &legacy);
+ _register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info3, &legacy);
}
-#endif // DISABLE_DEPRECATED
void GDExtension::_register_extension_class2(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs) {
+ const GDExtensionClassCreationInfo3 class_info3 = {
+ p_extension_funcs->is_virtual, // GDExtensionBool is_virtual;
+ p_extension_funcs->is_abstract, // GDExtensionBool is_abstract;
+ p_extension_funcs->is_exposed, // GDExtensionBool is_exposed;
+ false, // GDExtensionBool is_runtime;
+ p_extension_funcs->set_func, // GDExtensionClassSet set_func;
+ p_extension_funcs->get_func, // GDExtensionClassGet get_func;
+ p_extension_funcs->get_property_list_func, // GDExtensionClassGetPropertyList get_property_list_func;
+ p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func;
+ p_extension_funcs->property_can_revert_func, // GDExtensionClassPropertyCanRevert property_can_revert_func;
+ p_extension_funcs->property_get_revert_func, // GDExtensionClassPropertyGetRevert property_get_revert_func;
+ p_extension_funcs->validate_property_func, // GDExtensionClassValidateProperty validate_property_func;
+ p_extension_funcs->notification_func, // GDExtensionClassNotification2 notification_func;
+ p_extension_funcs->to_string_func, // GDExtensionClassToString to_string_func;
+ p_extension_funcs->reference_func, // GDExtensionClassReference reference_func;
+ p_extension_funcs->unreference_func, // GDExtensionClassUnreference unreference_func;
+ p_extension_funcs->create_instance_func, // GDExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
+ p_extension_funcs->free_instance_func, // GDExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
+ p_extension_funcs->recreate_instance_func, // GDExtensionClassRecreateInstance recreate_instance_func;
+ p_extension_funcs->get_virtual_func, // GDExtensionClassGetVirtual get_virtual_func;
+ p_extension_funcs->get_virtual_call_data_func, // GDExtensionClassGetVirtualCallData get_virtual_call_data_func;
+ p_extension_funcs->call_virtual_with_data_func, // GDExtensionClassCallVirtualWithData call_virtual_func;
+ p_extension_funcs->get_rid_func, // GDExtensionClassGetRID get_rid;
+ p_extension_funcs->class_userdata, // void *class_userdata;
+ };
+
+ _register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info3);
+}
+#endif // DISABLE_DEPRECATED
+
+void GDExtension::_register_extension_class3(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs) {
_register_extension_class_internal(p_library, p_class_name, p_parent_class_name, p_extension_funcs);
}
-void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs, const ClassCreationDeprecatedInfo *p_deprecated_funcs) {
+void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs, const ClassCreationDeprecatedInfo *p_deprecated_funcs) {
GDExtension *self = reinterpret_cast<GDExtension *>(p_library);
StringName class_name = *reinterpret_cast<const StringName *>(p_class_name);
@@ -397,15 +431,20 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr
//inheriting from engine class
}
} else {
- ERR_FAIL_MSG("Attempt to register an extension class '" + String(class_name) + "' using non-existing parent class '" + String(parent_class_name) + "'");
+ ERR_FAIL_MSG("Attempt to register an extension class '" + String(class_name) + "' using non-existing parent class '" + String(parent_class_name) + "'.");
}
#ifdef TOOLS_ENABLED
Extension *extension = nullptr;
+ bool is_runtime = (bool)p_extension_funcs->is_runtime;
if (self->is_reloading && self->extension_classes.has(class_name)) {
extension = &self->extension_classes[class_name];
if (!parent_extension && parent_class_name != extension->gdextension.parent_class_name) {
- ERR_FAIL_MSG(vformat("GDExtension class '%s' attempt to change parent type from '%s' to '%s' on hot reload. Restart Godot for this change to take effect.", class_name, extension->gdextension.parent_class_name, parent_class_name));
+ ERR_FAIL_MSG(vformat("GDExtension class '%s' cannot change parent type from '%s' to '%s' on hot reload. Restart Godot for this change to take effect.", class_name, extension->gdextension.parent_class_name, parent_class_name));
+ }
+ if (extension->gdextension.is_runtime != is_runtime) {
+ ERR_PRINT(vformat("GDExtension class '%s' cannot change to/from runtime class on hot reload. Restart Godot for this change to take effect.", class_name));
+ is_runtime = extension->gdextension.is_runtime;
}
extension->is_reloading = false;
} else {
@@ -434,6 +473,9 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr
extension->gdextension.is_virtual = p_extension_funcs->is_virtual;
extension->gdextension.is_abstract = p_extension_funcs->is_abstract;
extension->gdextension.is_exposed = p_extension_funcs->is_exposed;
+#ifdef TOOLS_ENABLED
+ extension->gdextension.is_runtime = is_runtime;
+#endif
extension->gdextension.set = p_extension_funcs->set_func;
extension->gdextension.get = p_extension_funcs->get_func;
extension->gdextension.get_property_list = p_extension_funcs->get_property_list_func;
@@ -836,8 +878,9 @@ void GDExtension::initialize_gdextensions() {
#ifndef DISABLE_DEPRECATED
register_interface_function("classdb_register_extension_class", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class);
-#endif // DISABLE_DEPRECATED
register_interface_function("classdb_register_extension_class2", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class2);
+#endif // DISABLE_DEPRECATED
+ register_interface_function("classdb_register_extension_class3", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class3);
register_interface_function("classdb_register_extension_class_method", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_method);
register_interface_function("classdb_register_extension_class_virtual_method", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_virtual_method);
register_interface_function("classdb_register_extension_class_integer_constant", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_integer_constant);
@@ -910,6 +953,39 @@ Error GDExtensionResourceLoader::load_gdextension_resource(const String &p_path,
return ERR_INVALID_DATA;
}
+ // Optionally check maximum compatibility.
+ if (config->has_section_key("configuration", "compatibility_maximum")) {
+ uint32_t compatibility_maximum[3] = { 0, 0, 0 };
+ String compat_string = config->get_value("configuration", "compatibility_maximum");
+ Vector<int> parts = compat_string.split_ints(".");
+ for (int i = 0; i < 3; i++) {
+ if (i < parts.size() && parts[i] >= 0) {
+ compatibility_maximum[i] = parts[i];
+ } else {
+ // If a version part is missing, set the maximum to an arbitrary high value.
+ compatibility_maximum[i] = 9999;
+ }
+ }
+
+ compatible = true;
+ if (VERSION_MAJOR != compatibility_maximum[0]) {
+ compatible = VERSION_MAJOR < compatibility_maximum[0];
+ } else if (VERSION_MINOR != compatibility_maximum[1]) {
+ compatible = VERSION_MINOR < compatibility_maximum[1];
+ }
+#if VERSION_PATCH
+ // #if check to avoid -Wtype-limits warning when 0.
+ else {
+ compatible = VERSION_PATCH <= compatibility_maximum[2];
+ }
+#endif
+
+ if (!compatible) {
+ ERR_PRINT(vformat("GDExtension only compatible with Godot version %s or earlier: %s", compat_string, p_path));
+ return ERR_INVALID_DATA;
+ }
+ }
+
String library_path = GDExtension::find_extension_library(p_path, config, [](const String &p_feature) { return OS::get_singleton()->has_feature(p_feature); });
if (library_path.is_empty()) {
@@ -1056,7 +1132,10 @@ void GDExtension::prepare_reload() {
state.push_back(Pair<String, Variant>(P.name, value));
}
- E.value.instance_state[obj_id] = state;
+ E.value.instance_state[obj_id] = {
+ state, // List<Pair<String, Variant>> properties;
+ obj->is_extension_placeholder(), // bool is_placeholder;
+ };
}
}
}
@@ -1131,25 +1210,29 @@ void GDExtension::finish_reload() {
for (KeyValue<StringName, Extension> &E : extension_classes) {
// Loop over 'instance_state' rather than 'instance' because new instances
// may have been created when re-initializing the extension.
- for (const KeyValue<ObjectID, List<Pair<String, Variant>>> &S : E.value.instance_state) {
+ for (const KeyValue<ObjectID, Extension::InstanceState> &S : E.value.instance_state) {
Object *obj = ObjectDB::get_instance(S.key);
if (!obj) {
continue;
}
- obj->reset_internal_extension(&E.value.gdextension);
+ if (S.value.is_placeholder) {
+ obj->reset_internal_extension(ClassDB::get_placeholder_extension(E.value.gdextension.class_name));
+ } else {
+ obj->reset_internal_extension(&E.value.gdextension);
+ }
}
}
// Now that all the classes are back, restore the state.
for (KeyValue<StringName, Extension> &E : extension_classes) {
- for (const KeyValue<ObjectID, List<Pair<String, Variant>>> &S : E.value.instance_state) {
+ for (const KeyValue<ObjectID, Extension::InstanceState> &S : E.value.instance_state) {
Object *obj = ObjectDB::get_instance(S.key);
if (!obj) {
continue;
}
- for (const Pair<String, Variant> &state : S.value) {
+ for (const Pair<String, Variant> &state : S.value.properties) {
obj->set(state.first, state.second);
}
}
@@ -1157,7 +1240,7 @@ void GDExtension::finish_reload() {
// Finally, let the objects know that we are done reloading them.
for (KeyValue<StringName, Extension> &E : extension_classes) {
- for (const KeyValue<ObjectID, List<Pair<String, Variant>>> &S : E.value.instance_state) {
+ for (const KeyValue<ObjectID, Extension::InstanceState> &S : E.value.instance_state) {
Object *obj = ObjectDB::get_instance(S.key);
if (!obj) {
continue;
diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h
index dbb39acb2e..a2b948a38a 100644
--- a/core/extension/gdextension.h
+++ b/core/extension/gdextension.h
@@ -59,7 +59,12 @@ class GDExtension : public Resource {
bool is_reloading = false;
HashMap<StringName, GDExtensionMethodBind *> methods;
HashSet<ObjectID> instances;
- HashMap<ObjectID, List<Pair<String, Variant>>> instance_state;
+
+ struct InstanceState {
+ List<Pair<String, Variant>> properties;
+ bool is_placeholder = false;
+ };
+ HashMap<ObjectID, InstanceState> instance_state;
#endif
};
@@ -73,9 +78,10 @@ class GDExtension : public Resource {
#ifndef DISABLE_DEPRECATED
static void _register_extension_class(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo *p_extension_funcs);
-#endif // DISABLE_DEPRECATED
static void _register_extension_class2(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs);
- static void _register_extension_class_internal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs, const ClassCreationDeprecatedInfo *p_deprecated_funcs = nullptr);
+#endif // DISABLE_DEPRECATED
+ static void _register_extension_class3(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs);
+ static void _register_extension_class_internal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs, const ClassCreationDeprecatedInfo *p_deprecated_funcs = nullptr);
static void _register_extension_class_method(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassMethodInfo *p_method_info);
static void _register_extension_class_virtual_method(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassVirtualMethodInfo *p_method_info);
static void _register_extension_class_integer_constant(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_enum_name, GDExtensionConstStringNamePtr p_constant_name, GDExtensionInt p_constant_value, GDExtensionBool p_is_bitfield);
diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp
index c6d7779473..67ec09d764 100644
--- a/core/extension/gdextension_interface.cpp
+++ b/core/extension/gdextension_interface.cpp
@@ -1240,43 +1240,84 @@ static void gdextension_ref_set_object(GDExtensionRefPtr p_ref, GDExtensionObjec
#ifndef DISABLE_DEPRECATED
static GDExtensionScriptInstancePtr gdextension_script_instance_create(const GDExtensionScriptInstanceInfo *p_info, GDExtensionScriptInstanceDataPtr p_instance_data) {
- GDExtensionScriptInstanceInfo2 *info_2 = memnew(GDExtensionScriptInstanceInfo2);
- info_2->set_func = p_info->set_func;
- info_2->get_func = p_info->get_func;
- info_2->get_property_list_func = p_info->get_property_list_func;
- info_2->free_property_list_func = p_info->free_property_list_func;
- info_2->get_class_category_func = nullptr;
- info_2->property_can_revert_func = p_info->property_can_revert_func;
- info_2->property_get_revert_func = p_info->property_get_revert_func;
- info_2->get_owner_func = p_info->get_owner_func;
- info_2->get_property_state_func = p_info->get_property_state_func;
- info_2->get_method_list_func = p_info->get_method_list_func;
- info_2->free_method_list_func = p_info->free_method_list_func;
- info_2->get_property_type_func = p_info->get_property_type_func;
- info_2->validate_property_func = nullptr;
- info_2->has_method_func = p_info->has_method_func;
- info_2->call_func = p_info->call_func;
- info_2->notification_func = nullptr;
- info_2->to_string_func = p_info->to_string_func;
- info_2->refcount_incremented_func = p_info->refcount_incremented_func;
- info_2->refcount_decremented_func = p_info->refcount_decremented_func;
- info_2->get_script_func = p_info->get_script_func;
- info_2->is_placeholder_func = p_info->is_placeholder_func;
- info_2->set_fallback_func = p_info->set_fallback_func;
- info_2->get_fallback_func = p_info->get_fallback_func;
- info_2->get_language_func = p_info->get_language_func;
- info_2->free_func = p_info->free_func;
+ GDExtensionScriptInstanceInfo3 *info_3 = memnew(GDExtensionScriptInstanceInfo3);
+ info_3->set_func = p_info->set_func;
+ info_3->get_func = p_info->get_func;
+ info_3->get_property_list_func = p_info->get_property_list_func;
+ info_3->free_property_list_func = nullptr;
+ info_3->get_class_category_func = nullptr;
+ info_3->property_can_revert_func = p_info->property_can_revert_func;
+ info_3->property_get_revert_func = p_info->property_get_revert_func;
+ info_3->get_owner_func = p_info->get_owner_func;
+ info_3->get_property_state_func = p_info->get_property_state_func;
+ info_3->get_method_list_func = p_info->get_method_list_func;
+ info_3->free_method_list_func = nullptr;
+ info_3->get_property_type_func = p_info->get_property_type_func;
+ info_3->validate_property_func = nullptr;
+ info_3->has_method_func = p_info->has_method_func;
+ info_3->call_func = p_info->call_func;
+ info_3->notification_func = nullptr;
+ info_3->to_string_func = p_info->to_string_func;
+ info_3->refcount_incremented_func = p_info->refcount_incremented_func;
+ info_3->refcount_decremented_func = p_info->refcount_decremented_func;
+ info_3->get_script_func = p_info->get_script_func;
+ info_3->is_placeholder_func = p_info->is_placeholder_func;
+ info_3->set_fallback_func = p_info->set_fallback_func;
+ info_3->get_fallback_func = p_info->get_fallback_func;
+ info_3->get_language_func = p_info->get_language_func;
+ info_3->free_func = p_info->free_func;
ScriptInstanceExtension *script_instance_extension = memnew(ScriptInstanceExtension);
script_instance_extension->instance = p_instance_data;
- script_instance_extension->native_info = info_2;
+ script_instance_extension->native_info = info_3;
script_instance_extension->free_native_info = true;
- script_instance_extension->deprecated_native_info.notification_func = p_info->notification_func;
+ script_instance_extension->deprecated_native_info = memnew(ScriptInstanceExtension::DeprecatedNativeInfo);
+ script_instance_extension->deprecated_native_info->notification_func = p_info->notification_func;
+ script_instance_extension->deprecated_native_info->free_property_list_func = p_info->free_property_list_func;
+ script_instance_extension->deprecated_native_info->free_method_list_func = p_info->free_method_list_func;
return reinterpret_cast<GDExtensionScriptInstancePtr>(script_instance_extension);
}
-#endif // DISABLE_DEPRECATED
static GDExtensionScriptInstancePtr gdextension_script_instance_create2(const GDExtensionScriptInstanceInfo2 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data) {
+ GDExtensionScriptInstanceInfo3 *info_3 = memnew(GDExtensionScriptInstanceInfo3);
+ info_3->set_func = p_info->set_func;
+ info_3->get_func = p_info->get_func;
+ info_3->get_property_list_func = p_info->get_property_list_func;
+ info_3->free_property_list_func = nullptr;
+ info_3->get_class_category_func = nullptr;
+ info_3->property_can_revert_func = p_info->property_can_revert_func;
+ info_3->property_get_revert_func = p_info->property_get_revert_func;
+ info_3->get_owner_func = p_info->get_owner_func;
+ info_3->get_property_state_func = p_info->get_property_state_func;
+ info_3->get_method_list_func = p_info->get_method_list_func;
+ info_3->free_method_list_func = nullptr;
+ info_3->get_property_type_func = p_info->get_property_type_func;
+ info_3->validate_property_func = nullptr;
+ info_3->has_method_func = p_info->has_method_func;
+ info_3->call_func = p_info->call_func;
+ info_3->notification_func = p_info->notification_func;
+ info_3->to_string_func = p_info->to_string_func;
+ info_3->refcount_incremented_func = p_info->refcount_incremented_func;
+ info_3->refcount_decremented_func = p_info->refcount_decremented_func;
+ info_3->get_script_func = p_info->get_script_func;
+ info_3->is_placeholder_func = p_info->is_placeholder_func;
+ info_3->set_fallback_func = p_info->set_fallback_func;
+ info_3->get_fallback_func = p_info->get_fallback_func;
+ info_3->get_language_func = p_info->get_language_func;
+ info_3->free_func = p_info->free_func;
+
+ ScriptInstanceExtension *script_instance_extension = memnew(ScriptInstanceExtension);
+ script_instance_extension->instance = p_instance_data;
+ script_instance_extension->native_info = info_3;
+ script_instance_extension->free_native_info = true;
+ script_instance_extension->deprecated_native_info = memnew(ScriptInstanceExtension::DeprecatedNativeInfo);
+ script_instance_extension->deprecated_native_info->free_property_list_func = p_info->free_property_list_func;
+ script_instance_extension->deprecated_native_info->free_method_list_func = p_info->free_method_list_func;
+ return reinterpret_cast<GDExtensionScriptInstancePtr>(script_instance_extension);
+}
+#endif // DISABLE_DEPRECATED
+
+static GDExtensionScriptInstancePtr gdextension_script_instance_create3(const GDExtensionScriptInstanceInfo3 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data) {
ScriptInstanceExtension *script_instance_extension = memnew(ScriptInstanceExtension);
script_instance_extension->instance = p_instance_data;
script_instance_extension->native_info = p_info;
@@ -1379,7 +1420,7 @@ static GDExtensionMethodBindPtr gdextension_classdb_get_method_bind(GDExtensionC
static GDExtensionObjectPtr gdextension_classdb_construct_object(GDExtensionConstStringNamePtr p_classname) {
const StringName classname = *reinterpret_cast<const StringName *>(p_classname);
- return (GDExtensionObjectPtr)ClassDB::instantiate(classname);
+ return (GDExtensionObjectPtr)ClassDB::instantiate_no_placeholders(classname);
}
static void *gdextension_classdb_get_class_tag(GDExtensionConstStringNamePtr p_classname) {
@@ -1415,7 +1456,7 @@ static void gdextension_editor_help_load_xml_from_utf8_chars(const char *p_data)
#endif
}
-#define REGISTER_INTERFACE_FUNC(m_name) GDExtension::register_interface_function(#m_name, (GDExtensionInterfaceFunctionPtr)&gdextension_##m_name)
+#define REGISTER_INTERFACE_FUNC(m_name) GDExtension::register_interface_function(#m_name, (GDExtensionInterfaceFunctionPtr) & gdextension_##m_name)
void gdextension_setup_interface() {
REGISTER_INTERFACE_FUNC(get_godot_version);
@@ -1548,8 +1589,9 @@ void gdextension_setup_interface() {
REGISTER_INTERFACE_FUNC(ref_set_object);
#ifndef DISABLE_DEPRECATED
REGISTER_INTERFACE_FUNC(script_instance_create);
-#endif // DISABLE_DEPRECATED
REGISTER_INTERFACE_FUNC(script_instance_create2);
+#endif // DISABLE_DEPRECATED
+ REGISTER_INTERFACE_FUNC(script_instance_create3);
REGISTER_INTERFACE_FUNC(placeholder_script_instance_create);
REGISTER_INTERFACE_FUNC(placeholder_script_instance_update);
REGISTER_INTERFACE_FUNC(object_get_script_instance);
diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h
index 48a66c9fae..e7497a9d4c 100644
--- a/core/extension/gdextension_interface.h
+++ b/core/extension/gdextension_interface.h
@@ -290,7 +290,7 @@ 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; // Deprecated. Use GDExtensionClassCreationInfo2 instead.
+} GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo3 instead.
typedef struct {
GDExtensionBool is_virtual;
@@ -323,7 +323,41 @@ typedef struct {
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
GDExtensionClassGetRID get_rid_func;
void *class_userdata; // Per-class user data, later accessible in instance bindings.
-} GDExtensionClassCreationInfo2;
+} GDExtensionClassCreationInfo2; // Deprecated. Use GDExtensionClassCreationInfo3 instead.
+
+typedef struct {
+ GDExtensionBool is_virtual;
+ GDExtensionBool is_abstract;
+ GDExtensionBool is_exposed;
+ GDExtensionBool is_runtime;
+ 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.
+} GDExtensionClassCreationInfo3;
typedef void *GDExtensionClassLibraryPtr;
@@ -446,7 +480,8 @@ typedef void *GDExtensionScriptInstanceDataPtr; // Pointer to custom ScriptInsta
typedef GDExtensionBool (*GDExtensionScriptInstanceSet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value);
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 void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list); // Deprecated. Use GDExtensionScriptInstanceFreePropertyList2 instead.
+typedef void (*GDExtensionScriptInstanceFreePropertyList2)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count);
typedef GDExtensionBool (*GDExtensionScriptInstanceGetClassCategory)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionPropertyInfo *p_class_category);
typedef GDExtensionVariantType (*GDExtensionScriptInstanceGetPropertyType)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
@@ -460,7 +495,8 @@ typedef void (*GDExtensionScriptInstancePropertyStateAdd)(GDExtensionConstString
typedef void (*GDExtensionScriptInstanceGetPropertyState)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionScriptInstancePropertyStateAdd p_add_func, void *p_userdata);
typedef const GDExtensionMethodInfo *(*GDExtensionScriptInstanceGetMethodList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
-typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list);
+typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list); // Deprecated. Use GDExtensionScriptInstanceFreeMethodList2 instead.
+typedef void (*GDExtensionScriptInstanceFreeMethodList2)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list, uint32_t p_count);
typedef GDExtensionBool (*GDExtensionScriptInstanceHasMethod)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
@@ -520,7 +556,7 @@ typedef struct {
GDExtensionScriptInstanceFree free_func;
-} GDExtensionScriptInstanceInfo; // Deprecated. Use GDExtensionScriptInstanceInfo2 instead.
+} GDExtensionScriptInstanceInfo; // Deprecated. Use GDExtensionScriptInstanceInfo3 instead.
typedef struct {
GDExtensionScriptInstanceSet set_func;
@@ -561,7 +597,48 @@ typedef struct {
GDExtensionScriptInstanceFree free_func;
-} GDExtensionScriptInstanceInfo2;
+} GDExtensionScriptInstanceInfo2; // Deprecated. Use GDExtensionScriptInstanceInfo3 instead.
+
+typedef struct {
+ GDExtensionScriptInstanceSet set_func;
+ GDExtensionScriptInstanceGet get_func;
+ GDExtensionScriptInstanceGetPropertyList get_property_list_func;
+ GDExtensionScriptInstanceFreePropertyList2 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;
+ GDExtensionScriptInstanceFreeMethodList2 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;
+
+} GDExtensionScriptInstanceInfo3;
/* INITIALIZATION */
@@ -2240,6 +2317,9 @@ typedef void (*GDExtensionInterfaceObjectSetInstance)(GDExtensionObjectPtr p_o,
*
* Gets the class name of an Object.
*
+ * If the GDExtension wraps the Godot object in an abstraction specific to its class, this is the
+ * function that should be used to determine which wrapper to use.
+ *
* @param p_object A pointer to the Object.
* @param p_library A pointer the library received by the GDExtension's entry point function.
* @param r_class_name A pointer to a String to receive the class name.
@@ -2343,7 +2423,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.
+ * @deprecated in Godot 4.2. Use `script_instance_create3` instead.
*
* Creates a script instance that contains the given info and instance data.
*
@@ -2357,6 +2437,7 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)
/**
* @name script_instance_create2
* @since 4.2
+ * @deprecated in Godot 4.3. Use `script_instance_create3` instead.
*
* Creates a script instance that contains the given info and instance data.
*
@@ -2368,6 +2449,19 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate2)(const GDExtensionScriptInstanceInfo2 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
/**
+ * @name script_instance_create3
+ * @since 4.3
+ *
+ * Creates a script instance that contains the given info and instance data.
+ *
+ * @param p_info A pointer to a GDExtensionScriptInstanceInfo3 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 (*GDExtensionInterfaceScriptInstanceCreate3)(const GDExtensionScriptInstanceInfo3 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
+
+/**
* @name placeholder_script_instance_create
* @since 4.2
*
@@ -2486,7 +2580,7 @@ typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNa
/**
* @name classdb_register_extension_class
* @since 4.1
- * @deprecated in Godot 4.2. Use `classdb_register_extension_class2` instead.
+ * @deprecated in Godot 4.2. Use `classdb_register_extension_class3` instead.
*
* Registers an extension class in the ClassDB.
*
@@ -2502,6 +2596,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionCla
/**
* @name classdb_register_extension_class2
* @since 4.2
+ * @deprecated in Godot 4.3. Use `classdb_register_extension_class3` instead.
*
* Registers an extension class in the ClassDB.
*
@@ -2515,6 +2610,21 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionCla
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs);
/**
+ * @name classdb_register_extension_class3
+ * @since 4.3
+ *
+ * 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 (*GDExtensionInterfaceClassdbRegisterExtensionClass3)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs);
+
+/**
* @name classdb_register_extension_class_method
* @since 4.1
*
diff --git a/core/input/SCsub b/core/input/SCsub
index b12bf561de..da29637135 100644
--- a/core/input/SCsub
+++ b/core/input/SCsub
@@ -14,7 +14,7 @@ controller_databases = [
gensource = env.CommandNoCache(
"default_controller_mappings.gen.cpp",
controller_databases,
- env.Run(input_builders.make_default_controller_mappings, "Generating default controller mappings."),
+ env.Run(input_builders.make_default_controller_mappings),
)
env.add_source_files(env.core_sources, "*.cpp")
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 4117cc8c9c..3de0ed39ec 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -181,8 +181,9 @@ void Input::_bind_methods() {
ADD_SIGNAL(MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "device"), PropertyInfo(Variant::BOOL, "connected")));
}
+#ifdef TOOLS_ENABLED
void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
- String pf = p_function;
+ const String pf = p_function;
if ((p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" || pf == "is_action_just_pressed" || pf == "is_action_just_released" || pf == "get_action_strength" || pf == "get_action_raw_strength")) ||
(p_idx < 2 && pf == "get_axis") ||
@@ -201,6 +202,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
}
Object::get_argument_options(p_function, p_idx, r_options);
}
+#endif
void Input::VelocityTrack::update(const Vector2 &p_delta_p, const Vector2 &p_screen_delta_p) {
uint64_t tick = OS::get_singleton()->get_ticks_usec();
diff --git a/core/input/input.h b/core/input/input.h
index 367bb93188..d1f284e8f7 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -270,7 +270,10 @@ protected:
public:
void set_mouse_mode(MouseMode p_mode);
MouseMode get_mouse_mode() const;
+
+#ifdef TOOLS_ENABLED
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
+#endif
static Input *get_singleton();
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index 70041ecfd6..5d6de1ad9a 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -85,6 +85,35 @@ String InputMap::suggest_actions(const StringName &p_action) const {
return error_message;
}
+#ifdef TOOLS_ENABLED
+void InputMap::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+ const String pf = p_function;
+ bool first_argument_is_action = false;
+ if (p_idx == 0) {
+ first_argument_is_action = (pf == "has_action" || pf == "erase_action" ||
+ pf == "action_set_deadzone" || pf == "action_get_deadzone" ||
+ pf == "action_has_event" || pf == "action_add_event" || pf == "action_get_events" ||
+ pf == "action_erase_event" || pf == "action_erase_events");
+ }
+ if (first_argument_is_action || (p_idx == 1 && pf == "event_is_action")) {
+ // Cannot rely on `get_actions()`, otherwise the actions would be in the context of the Editor (no user-defined actions).
+ List<PropertyInfo> pinfo;
+ ProjectSettings::get_singleton()->get_property_list(&pinfo);
+
+ for (const PropertyInfo &pi : pinfo) {
+ if (!pi.name.begins_with("input/")) {
+ continue;
+ }
+
+ String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
+ r_options->push_back(name.quote());
+ }
+ }
+
+ Object::get_argument_options(p_function, p_idx, r_options);
+}
+#endif
+
void InputMap::add_action(const StringName &p_action, float p_deadzone) {
ERR_FAIL_COND_MSG(input_map.has(p_action), "InputMap already has action \"" + String(p_action) + "\".");
input_map[p_action] = Action();
diff --git a/core/input/input_map.h b/core/input/input_map.h
index 6407ea489e..3774a131e6 100644
--- a/core/input/input_map.h
+++ b/core/input/input_map.h
@@ -95,6 +95,10 @@ public:
String suggest_actions(const StringName &p_action) const;
+#ifdef TOOLS_ENABLED
+ virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
+#endif
+
String get_builtin_display_name(const String &p_name) const;
// Use an Ordered Map so insertion order is preserved. We want the elements to be 'grouped' somewhat.
const HashMap<String, List<Ref<InputEvent>>> &get_builtins();
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index daa57be76f..7e8d0b43cd 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -41,7 +41,12 @@
#include <stdio.h>
void Resource::emit_changed() {
- emit_signal(CoreStringNames::get_singleton()->changed);
+ if (ResourceLoader::is_within_load() && !Thread::is_main_thread()) {
+ // Let the connection happen on the main thread, later, since signals are not thread-safe.
+ call_deferred("emit_signal", CoreStringNames::get_singleton()->changed);
+ } else {
+ emit_signal(CoreStringNames::get_singleton()->changed);
+ }
}
void Resource::_resource_path_changed() {
@@ -152,12 +157,22 @@ bool Resource::editor_can_reload_from_file() {
}
void Resource::connect_changed(const Callable &p_callable, uint32_t p_flags) {
+ if (ResourceLoader::is_within_load() && !Thread::is_main_thread()) {
+ // Let the check and connection happen on the main thread, later, since signals are not thread-safe.
+ callable_mp(this, &Resource::connect_changed).call_deferred(p_callable, p_flags);
+ return;
+ }
if (!is_connected(CoreStringNames::get_singleton()->changed, p_callable) || p_flags & CONNECT_REFERENCE_COUNTED) {
connect(CoreStringNames::get_singleton()->changed, p_callable, p_flags);
}
}
void Resource::disconnect_changed(const Callable &p_callable) {
+ if (ResourceLoader::is_within_load() && !Thread::is_main_thread()) {
+ // Let the check and disconnection happen on the main thread, later, since signals are not thread-safe.
+ callable_mp(this, &Resource::disconnect_changed).call_deferred(p_callable);
+ return;
+ }
if (is_connected(CoreStringNames::get_singleton()->changed, p_callable)) {
disconnect(CoreStringNames::get_singleton()->changed, p_callable);
}
diff --git a/core/io/resource.h b/core/io/resource.h
index b885b773ac..f0f686af57 100644
--- a/core/io/resource.h
+++ b/core/io/resource.h
@@ -106,7 +106,7 @@ public:
virtual void set_path(const String &p_path, bool p_take_over = false);
String get_path() const;
- void set_path_cache(const String &p_path); // Set raw path without involving resource cache.
+ virtual void set_path_cache(const String &p_path); // Set raw path without involving resource cache.
_FORCE_INLINE_ bool is_built_in() const { return path_cache.is_empty() || path_cache.contains("::") || path_cache.begins_with("local://"); }
static String generate_scene_unique_id();
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 20c494516b..17cffb878e 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -430,7 +430,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
path = remaps[path];
}
- Ref<Resource> res = ResourceLoader::load(path, exttype);
+ Ref<Resource> res = ResourceLoader::load(path, exttype, cache_mode_for_external);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
@@ -683,7 +683,7 @@ Error ResourceLoaderBinary::load() {
}
external_resources.write[i].path = path; //remap happens here, not on load because on load it can actually be used for filesystem dock resource remap
- external_resources.write[i].load_token = ResourceLoader::_load_start(path, external_resources[i].type, use_sub_threads ? ResourceLoader::LOAD_THREAD_DISTRIBUTE : ResourceLoader::LOAD_THREAD_FROM_CURRENT, ResourceFormatLoader::CACHE_MODE_REUSE);
+ external_resources.write[i].load_token = ResourceLoader::_load_start(path, external_resources[i].type, use_sub_threads ? ResourceLoader::LOAD_THREAD_DISTRIBUTE : ResourceLoader::LOAD_THREAD_FROM_CURRENT, cache_mode_for_external);
if (!external_resources[i].load_token.is_valid()) {
if (!ResourceLoader::get_abort_on_missing_resources()) {
ResourceLoader::notify_dependency_error(local_path, path, external_resources[i].type);
@@ -772,10 +772,12 @@ Error ResourceLoaderBinary::load() {
}
res = Ref<Resource>(r);
- if (!path.is_empty() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
- r->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); //if got here because the resource with same path has different type, replace it
- } else if (!path.is_resource_file()) {
- r->set_path_cache(path);
+ if (!path.is_empty()) {
+ if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
+ r->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); // If got here because the resource with same path has different type, replace it.
+ } else {
+ r->set_path_cache(path);
+ }
}
r->set_scene_unique_id(id);
}
@@ -1187,7 +1189,22 @@ Ref<Resource> ResourceFormatLoaderBinary::load(const String &p_path, const Strin
ERR_FAIL_COND_V_MSG(err != OK, Ref<Resource>(), "Cannot open file '" + p_path + "'.");
ResourceLoaderBinary loader;
- loader.cache_mode = p_cache_mode;
+ switch (p_cache_mode) {
+ case CACHE_MODE_IGNORE:
+ case CACHE_MODE_REUSE:
+ case CACHE_MODE_REPLACE:
+ loader.cache_mode = p_cache_mode;
+ loader.cache_mode_for_external = CACHE_MODE_REUSE;
+ break;
+ case CACHE_MODE_IGNORE_DEEP:
+ loader.cache_mode = CACHE_MODE_IGNORE;
+ loader.cache_mode_for_external = p_cache_mode;
+ break;
+ case CACHE_MODE_REPLACE_DEEP:
+ loader.cache_mode = CACHE_MODE_REPLACE;
+ loader.cache_mode_for_external = p_cache_mode;
+ break;
+ }
loader.use_sub_threads = p_use_sub_threads;
loader.progress = r_progress;
String path = !p_original_path.is_empty() ? p_original_path : p_path;
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index e64485d404..e01c5fa467 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -85,6 +85,7 @@ class ResourceLoaderBinary {
Error error = OK;
ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE;
+ ResourceFormatLoader::CacheMode cache_mode_for_external = ResourceFormatLoader::CACHE_MODE_REUSE;
friend class ResourceFormatLoaderBinary;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 5344266a9c..ff563a35b2 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -188,6 +188,8 @@ void ResourceFormatLoader::_bind_methods() {
BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE);
BIND_ENUM_CONSTANT(CACHE_MODE_REUSE);
BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE);
+ BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE_DEEP);
+ BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE_DEEP);
GDVIRTUAL_BIND(_get_recognized_extensions);
GDVIRTUAL_BIND(_recognize_path, "path", "type");
@@ -339,9 +341,11 @@ void ResourceLoader::_thread_load_function(void *p_userdata) {
load_task.cond_var = nullptr;
}
+ bool ignoring = load_task.cache_mode == ResourceFormatLoader::CACHE_MODE_IGNORE || load_task.cache_mode == ResourceFormatLoader::CACHE_MODE_IGNORE_DEEP;
+ bool replacing = load_task.cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE || load_task.cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE_DEEP;
if (load_task.resource.is_valid()) {
- if (load_task.cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
- if (load_task.cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE) {
+ if (!ignoring) {
+ if (replacing) {
Ref<Resource> old_res = ResourceCache::get_ref(load_task.local_path);
if (old_res.is_valid() && old_res != load_task.resource) {
// If resource is already loaded, only replace its data, to avoid existing invalidating instances.
@@ -349,8 +353,8 @@ void ResourceLoader::_thread_load_function(void *p_userdata) {
load_task.resource = old_res;
}
}
- load_task.resource->set_path(load_task.local_path, load_task.cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE);
- } else if (!load_task.local_path.is_resource_file()) {
+ load_task.resource->set_path(load_task.local_path, replacing);
+ } else {
load_task.resource->set_path_cache(load_task.local_path);
}
@@ -370,7 +374,7 @@ void ResourceLoader::_thread_load_function(void *p_userdata) {
if (_loaded_callback) {
_loaded_callback(load_task.resource, load_task.local_path);
}
- } else if (load_task.cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
+ } else if (!ignoring) {
Ref<Resource> existing = ResourceCache::get_ref(load_task.local_path);
if (existing.is_valid()) {
load_task.resource = existing;
@@ -658,9 +662,6 @@ Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro
// resource loading that means that the task to wait for can be restarted here to break the
// cycle, with as much recursion into this process as needed.
// When the stack is eventually unrolled, the original load will have been notified to go on.
-#ifdef DEV_ENABLED
- print_verbose("ResourceLoader: Potential for deadlock detected in task dependency. Attempting to avoid it by re-issuing the load now.");
-#endif
// CACHE_MODE_IGNORE is needed because, otherwise, the new request would just see there's
// an ongoing load for that resource and wait for it again. This value forces a new load.
Ref<ResourceLoader::LoadToken> token = _load_start(load_task.local_path, load_task.type_hint, LOAD_THREAD_DISTRIBUTE, ResourceFormatLoader::CACHE_MODE_IGNORE);
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 1f79b83f11..5caf699d32 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -47,9 +47,11 @@ class ResourceFormatLoader : public RefCounted {
public:
enum CacheMode {
- CACHE_MODE_IGNORE, // Resource and subresources do not use path cache, no path is set into resource.
- CACHE_MODE_REUSE, // Resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available.
- CACHE_MODE_REPLACE, // Resource and subresource use path cache, but replace existing loaded resources when available with information from disk.
+ CACHE_MODE_IGNORE,
+ CACHE_MODE_REUSE,
+ CACHE_MODE_REPLACE,
+ CACHE_MODE_IGNORE_DEEP,
+ CACHE_MODE_REPLACE_DEEP,
};
protected:
diff --git a/core/math/aabb.h b/core/math/aabb.h
index cea845bf7c..7927c431eb 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -73,7 +73,7 @@ struct _NO_DISCARD_ AABB {
AABB intersection(const AABB &p_aabb) const; ///get box where two intersect, empty if no intersection occurs
bool intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip = nullptr, Vector3 *r_normal = nullptr) const;
bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip = nullptr, Vector3 *r_normal = nullptr) const;
- _FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const;
+ _FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t p_t0, real_t p_t1) const;
_FORCE_INLINE_ bool intersects_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) const;
_FORCE_INLINE_ bool inside_convex_shape(const Plane *p_planes, int p_plane_count) const;
@@ -401,7 +401,7 @@ inline real_t AABB::get_shortest_axis_size() const {
return max_size;
}
-bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const {
+bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t p_t0, real_t p_t1) const {
#ifdef MATH_CHECKS
if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
@@ -452,7 +452,7 @@ bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real
if (tzmax < tmax) {
tmax = tzmax;
}
- return ((tmin < t1) && (tmax > t0));
+ return ((tmin < p_t1) && (tmax > p_t0));
}
void AABB::grow_by(real_t p_amount) {
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 1ff6cdd588..3ebd13b9fe 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -685,7 +685,7 @@ void Basis::set_euler(const Vector3 &p_euler, EulerOrder p_order) {
*this = zmat * ymat * xmat;
} break;
default: {
- ERR_FAIL_MSG("Invalid order parameter for set_euler(vec3,order)");
+ ERR_FAIL_MSG("Invalid Euler order parameter.");
}
}
}
@@ -907,7 +907,7 @@ void Basis::_set_diagonal(const Vector3 &p_diag) {
rows[2][2] = p_diag.z;
}
-Basis Basis::lerp(const Basis &p_to, const real_t &p_weight) const {
+Basis Basis::lerp(const Basis &p_to, real_t p_weight) const {
Basis b;
b.rows[0] = rows[0].lerp(p_to.rows[0], p_weight);
b.rows[1] = rows[1].lerp(p_to.rows[1], p_weight);
@@ -916,7 +916,7 @@ Basis Basis::lerp(const Basis &p_to, const real_t &p_weight) const {
return b;
}
-Basis Basis::slerp(const Basis &p_to, const real_t &p_weight) const {
+Basis Basis::slerp(const Basis &p_to, real_t p_weight) const {
//consider scale
Quaternion from(*this);
Quaternion to(p_to);
diff --git a/core/math/basis.h b/core/math/basis.h
index e3094114e8..1fc08e95e1 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -41,11 +41,11 @@ struct _NO_DISCARD_ Basis {
Vector3(0, 0, 1)
};
- _FORCE_INLINE_ const Vector3 &operator[](int axis) const {
- return rows[axis];
+ _FORCE_INLINE_ const Vector3 &operator[](int p_axis) const {
+ return rows[p_axis];
}
- _FORCE_INLINE_ Vector3 &operator[](int axis) {
- return rows[axis];
+ _FORCE_INLINE_ Vector3 &operator[](int p_axis) {
+ return rows[p_axis];
}
void invert();
@@ -110,14 +110,14 @@ struct _NO_DISCARD_ Basis {
void set_quaternion_scale(const Quaternion &p_quaternion, const Vector3 &p_scale);
// transposed dot products
- _FORCE_INLINE_ real_t tdotx(const Vector3 &v) const {
- return rows[0][0] * v[0] + rows[1][0] * v[1] + rows[2][0] * v[2];
+ _FORCE_INLINE_ real_t tdotx(const Vector3 &p_v) const {
+ return rows[0][0] * p_v[0] + rows[1][0] * p_v[1] + rows[2][0] * p_v[2];
}
- _FORCE_INLINE_ real_t tdoty(const Vector3 &v) const {
- return rows[0][1] * v[0] + rows[1][1] * v[1] + rows[2][1] * v[2];
+ _FORCE_INLINE_ real_t tdoty(const Vector3 &p_v) const {
+ return rows[0][1] * p_v[0] + rows[1][1] * p_v[1] + rows[2][1] * p_v[2];
}
- _FORCE_INLINE_ real_t tdotz(const Vector3 &v) const {
- return rows[0][2] * v[0] + rows[1][2] * v[1] + rows[2][2] * v[2];
+ _FORCE_INLINE_ real_t tdotz(const Vector3 &p_v) const {
+ return rows[0][2] * p_v[0] + rows[1][2] * p_v[1] + rows[2][2] * p_v[2];
}
bool is_equal_approx(const Basis &p_basis) const;
@@ -134,10 +134,10 @@ struct _NO_DISCARD_ Basis {
_FORCE_INLINE_ Basis operator+(const Basis &p_matrix) const;
_FORCE_INLINE_ void operator-=(const Basis &p_matrix);
_FORCE_INLINE_ Basis operator-(const Basis &p_matrix) const;
- _FORCE_INLINE_ void operator*=(const real_t p_val);
- _FORCE_INLINE_ Basis operator*(const real_t p_val) const;
- _FORCE_INLINE_ void operator/=(const real_t p_val);
- _FORCE_INLINE_ Basis operator/(const real_t p_val) const;
+ _FORCE_INLINE_ void operator*=(real_t p_val);
+ _FORCE_INLINE_ Basis operator*(real_t p_val) const;
+ _FORCE_INLINE_ void operator/=(real_t p_val);
+ _FORCE_INLINE_ Basis operator/(real_t p_val) const;
bool is_orthogonal() const;
bool is_orthonormal() const;
@@ -145,24 +145,24 @@ struct _NO_DISCARD_ Basis {
bool is_diagonal() const;
bool is_rotation() const;
- Basis lerp(const Basis &p_to, const real_t &p_weight) const;
- Basis slerp(const Basis &p_to, const real_t &p_weight) const;
+ Basis lerp(const Basis &p_to, real_t p_weight) const;
+ Basis slerp(const Basis &p_to, real_t p_weight) const;
void rotate_sh(real_t *p_values);
operator String() const;
/* create / set */
- _FORCE_INLINE_ void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
- rows[0][0] = xx;
- rows[0][1] = xy;
- rows[0][2] = xz;
- rows[1][0] = yx;
- rows[1][1] = yy;
- rows[1][2] = yz;
- rows[2][0] = zx;
- rows[2][1] = zy;
- rows[2][2] = zz;
+ _FORCE_INLINE_ void set(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz) {
+ rows[0][0] = p_xx;
+ rows[0][1] = p_xy;
+ rows[0][2] = p_xz;
+ rows[1][0] = p_yx;
+ rows[1][1] = p_yy;
+ rows[1][2] = p_yz;
+ rows[2][0] = p_zx;
+ rows[2][1] = p_zy;
+ rows[2][2] = p_zz;
}
_FORCE_INLINE_ void set_columns(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z) {
set_column(0, p_x);
@@ -192,20 +192,20 @@ struct _NO_DISCARD_ Basis {
rows[2].zero();
}
- _FORCE_INLINE_ Basis transpose_xform(const Basis &m) const {
+ _FORCE_INLINE_ Basis transpose_xform(const Basis &p_m) const {
return Basis(
- rows[0].x * m[0].x + rows[1].x * m[1].x + rows[2].x * m[2].x,
- rows[0].x * m[0].y + rows[1].x * m[1].y + rows[2].x * m[2].y,
- rows[0].x * m[0].z + rows[1].x * m[1].z + rows[2].x * m[2].z,
- rows[0].y * m[0].x + rows[1].y * m[1].x + rows[2].y * m[2].x,
- rows[0].y * m[0].y + rows[1].y * m[1].y + rows[2].y * m[2].y,
- rows[0].y * m[0].z + rows[1].y * m[1].z + rows[2].y * m[2].z,
- rows[0].z * m[0].x + rows[1].z * m[1].x + rows[2].z * m[2].x,
- rows[0].z * m[0].y + rows[1].z * m[1].y + rows[2].z * m[2].y,
- rows[0].z * m[0].z + rows[1].z * m[1].z + rows[2].z * m[2].z);
+ rows[0].x * p_m[0].x + rows[1].x * p_m[1].x + rows[2].x * p_m[2].x,
+ rows[0].x * p_m[0].y + rows[1].x * p_m[1].y + rows[2].x * p_m[2].y,
+ rows[0].x * p_m[0].z + rows[1].x * p_m[1].z + rows[2].x * p_m[2].z,
+ rows[0].y * p_m[0].x + rows[1].y * p_m[1].x + rows[2].y * p_m[2].x,
+ rows[0].y * p_m[0].y + rows[1].y * p_m[1].y + rows[2].y * p_m[2].y,
+ rows[0].y * p_m[0].z + rows[1].y * p_m[1].z + rows[2].y * p_m[2].z,
+ rows[0].z * p_m[0].x + rows[1].z * p_m[1].x + rows[2].z * p_m[2].x,
+ rows[0].z * p_m[0].y + rows[1].z * p_m[1].y + rows[2].z * p_m[2].y,
+ rows[0].z * p_m[0].z + rows[1].z * p_m[1].z + rows[2].z * p_m[2].z);
}
- Basis(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
- set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
+ Basis(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz) {
+ set(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz);
}
void orthonormalize();
@@ -279,25 +279,25 @@ _FORCE_INLINE_ Basis Basis::operator-(const Basis &p_matrix) const {
return ret;
}
-_FORCE_INLINE_ void Basis::operator*=(const real_t p_val) {
+_FORCE_INLINE_ void Basis::operator*=(real_t p_val) {
rows[0] *= p_val;
rows[1] *= p_val;
rows[2] *= p_val;
}
-_FORCE_INLINE_ Basis Basis::operator*(const real_t p_val) const {
+_FORCE_INLINE_ Basis Basis::operator*(real_t p_val) const {
Basis ret(*this);
ret *= p_val;
return ret;
}
-_FORCE_INLINE_ void Basis::operator/=(const real_t p_val) {
+_FORCE_INLINE_ void Basis::operator/=(real_t p_val) {
rows[0] /= p_val;
rows[1] /= p_val;
rows[2] /= p_val;
}
-_FORCE_INLINE_ Basis Basis::operator/(const real_t p_val) const {
+_FORCE_INLINE_ Basis Basis::operator/(real_t p_val) const {
Basis ret(*this);
ret /= p_val;
return ret;
diff --git a/core/math/delaunay_2d.h b/core/math/delaunay_2d.h
index fc70724308..0bc67a92f6 100644
--- a/core/math/delaunay_2d.h
+++ b/core/math/delaunay_2d.h
@@ -64,7 +64,7 @@ public:
}
};
- static Triangle create_triangle(const Vector<Vector2> &p_vertices, const int &p_a, const int &p_b, const int &p_c) {
+ static Triangle create_triangle(const Vector<Vector2> &p_vertices, int p_a, int p_b, int p_c) {
Triangle triangle = Triangle(p_a, p_b, p_c);
// Get the values of the circumcircle and store them inside the triangle object.
diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp
index e2edf8b23e..4d55455166 100644
--- a/core/math/geometry_3d.cpp
+++ b/core/math/geometry_3d.cpp
@@ -393,7 +393,7 @@ static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, i
return;
}
-#define vert(m_idx) Vector3(((m_idx)&4) >> 2, ((m_idx)&2) >> 1, (m_idx)&1)
+#define vert(m_idx) Vector3(((m_idx) & 4) >> 2, ((m_idx) & 2) >> 1, (m_idx) & 1)
static const uint8_t indices[6][4] = {
{ 7, 6, 4, 5 },
diff --git a/core/math/projection.h b/core/math/projection.h
index b3a9cff002..a7adc9017e 100644
--- a/core/math/projection.h
+++ b/core/math/projection.h
@@ -55,12 +55,12 @@ struct _NO_DISCARD_ Projection {
Vector4 columns[4];
- _FORCE_INLINE_ const Vector4 &operator[](const int p_axis) const {
+ _FORCE_INLINE_ const Vector4 &operator[](int p_axis) const {
DEV_ASSERT((unsigned int)p_axis < 4);
return columns[p_axis];
}
- _FORCE_INLINE_ Vector4 &operator[](const int p_axis) {
+ _FORCE_INLINE_ Vector4 &operator[](int p_axis) {
DEV_ASSERT((unsigned int)p_axis < 4);
return columns[p_axis];
}
diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp
index cbaaa1371a..08eac14b76 100644
--- a/core/math/quaternion.cpp
+++ b/core/math/quaternion.cpp
@@ -110,7 +110,7 @@ Quaternion Quaternion::exp() const {
return Quaternion(src_v, theta);
}
-Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) const {
+Quaternion Quaternion::slerp(const Quaternion &p_to, real_t p_weight) const {
#ifdef MATH_CHECKS
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion " + p_to.operator String() + " must be normalized.");
@@ -151,7 +151,7 @@ Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) con
scale0 * w + scale1 * to1.w);
}
-Quaternion Quaternion::slerpni(const Quaternion &p_to, const real_t &p_weight) const {
+Quaternion Quaternion::slerpni(const Quaternion &p_to, real_t p_weight) const {
#ifdef MATH_CHECKS
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion " + p_to.operator String() + " must be normalized.");
@@ -175,7 +175,7 @@ Quaternion Quaternion::slerpni(const Quaternion &p_to, const real_t &p_weight) c
invFactor * from.w + newFactor * p_to.w);
}
-Quaternion Quaternion::spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const {
+Quaternion Quaternion::spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, real_t p_weight) const {
#ifdef MATH_CHECKS
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion " + p_b.operator String() + " must be normalized.");
@@ -225,8 +225,8 @@ Quaternion Quaternion::spherical_cubic_interpolate(const Quaternion &p_b, const
return q1.slerp(q2, p_weight);
}
-Quaternion Quaternion::spherical_cubic_interpolate_in_time(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight,
- const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const {
+Quaternion Quaternion::spherical_cubic_interpolate_in_time(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, real_t p_weight,
+ real_t p_b_t, real_t p_pre_a_t, real_t p_post_b_t) const {
#ifdef MATH_CHECKS
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion " + p_b.operator String() + " must be normalized.");
diff --git a/core/math/quaternion.h b/core/math/quaternion.h
index f8133df559..868a2916f5 100644
--- a/core/math/quaternion.h
+++ b/core/math/quaternion.h
@@ -46,11 +46,11 @@ struct _NO_DISCARD_ Quaternion {
real_t components[4] = { 0, 0, 0, 1.0 };
};
- _FORCE_INLINE_ real_t &operator[](int idx) {
- return components[idx];
+ _FORCE_INLINE_ real_t &operator[](int p_idx) {
+ return components[p_idx];
}
- _FORCE_INLINE_ const real_t &operator[](int idx) const {
- return components[idx];
+ _FORCE_INLINE_ const real_t &operator[](int p_idx) const {
+ return components[p_idx];
}
_FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Quaternion &p_quaternion) const;
@@ -68,10 +68,10 @@ struct _NO_DISCARD_ Quaternion {
Vector3 get_euler(EulerOrder p_order = EulerOrder::YXZ) const;
static Quaternion from_euler(const Vector3 &p_euler);
- Quaternion slerp(const Quaternion &p_to, const real_t &p_weight) const;
- Quaternion slerpni(const Quaternion &p_to, const real_t &p_weight) const;
- Quaternion spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const;
- Quaternion spherical_cubic_interpolate_in_time(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const;
+ Quaternion slerp(const Quaternion &p_to, real_t p_weight) const;
+ Quaternion slerpni(const Quaternion &p_to, real_t p_weight) const;
+ Quaternion spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, real_t p_weight) const;
+ Quaternion spherical_cubic_interpolate_in_time(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, real_t p_weight, real_t p_b_t, real_t p_pre_a_t, real_t p_post_b_t) const;
Vector3 get_axis() const;
real_t get_angle() const;
@@ -87,28 +87,28 @@ struct _NO_DISCARD_ Quaternion {
void operator*=(const Quaternion &p_q);
Quaternion operator*(const Quaternion &p_q) const;
- _FORCE_INLINE_ Vector3 xform(const Vector3 &v) const {
+ _FORCE_INLINE_ Vector3 xform(const Vector3 &p_v) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!is_normalized(), v, "The quaternion " + operator String() + " must be normalized.");
+ ERR_FAIL_COND_V_MSG(!is_normalized(), p_v, "The quaternion " + operator String() + " must be normalized.");
#endif
Vector3 u(x, y, z);
- Vector3 uv = u.cross(v);
- return v + ((uv * w) + u.cross(uv)) * ((real_t)2);
+ Vector3 uv = u.cross(p_v);
+ return p_v + ((uv * w) + u.cross(uv)) * ((real_t)2);
}
- _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &v) const {
- return inverse().xform(v);
+ _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_v) const {
+ return inverse().xform(p_v);
}
_FORCE_INLINE_ void operator+=(const Quaternion &p_q);
_FORCE_INLINE_ void operator-=(const Quaternion &p_q);
- _FORCE_INLINE_ void operator*=(const real_t &s);
- _FORCE_INLINE_ void operator/=(const real_t &s);
- _FORCE_INLINE_ Quaternion operator+(const Quaternion &q2) const;
- _FORCE_INLINE_ Quaternion operator-(const Quaternion &q2) const;
+ _FORCE_INLINE_ void operator*=(real_t p_s);
+ _FORCE_INLINE_ void operator/=(real_t p_s);
+ _FORCE_INLINE_ Quaternion operator+(const Quaternion &p_q2) const;
+ _FORCE_INLINE_ Quaternion operator-(const Quaternion &p_q2) const;
_FORCE_INLINE_ Quaternion operator-() const;
- _FORCE_INLINE_ Quaternion operator*(const real_t &s) const;
- _FORCE_INLINE_ Quaternion operator/(const real_t &s) const;
+ _FORCE_INLINE_ Quaternion operator*(real_t p_s) const;
+ _FORCE_INLINE_ Quaternion operator/(real_t p_s) const;
_FORCE_INLINE_ bool operator==(const Quaternion &p_quaternion) const;
_FORCE_INLINE_ bool operator!=(const Quaternion &p_quaternion) const;
@@ -140,9 +140,9 @@ struct _NO_DISCARD_ Quaternion {
w = p_q.w;
}
- Quaternion(const Vector3 &v0, const Vector3 &v1) { // Shortest arc.
- Vector3 c = v0.cross(v1);
- real_t d = v0.dot(v1);
+ Quaternion(const Vector3 &p_v0, const Vector3 &p_v1) { // Shortest arc.
+ Vector3 c = p_v0.cross(p_v1);
+ real_t d = p_v0.dot(p_v1);
if (d < -1.0f + (real_t)CMP_EPSILON) {
x = 0;
@@ -183,25 +183,25 @@ void Quaternion::operator-=(const Quaternion &p_q) {
w -= p_q.w;
}
-void Quaternion::operator*=(const real_t &s) {
- x *= s;
- y *= s;
- z *= s;
- w *= s;
+void Quaternion::operator*=(real_t p_s) {
+ x *= p_s;
+ y *= p_s;
+ z *= p_s;
+ w *= p_s;
}
-void Quaternion::operator/=(const real_t &s) {
- *this *= 1.0f / s;
+void Quaternion::operator/=(real_t p_s) {
+ *this *= 1.0f / p_s;
}
-Quaternion Quaternion::operator+(const Quaternion &q2) const {
+Quaternion Quaternion::operator+(const Quaternion &p_q2) const {
const Quaternion &q1 = *this;
- return Quaternion(q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w);
+ return Quaternion(q1.x + p_q2.x, q1.y + p_q2.y, q1.z + p_q2.z, q1.w + p_q2.w);
}
-Quaternion Quaternion::operator-(const Quaternion &q2) const {
+Quaternion Quaternion::operator-(const Quaternion &p_q2) const {
const Quaternion &q1 = *this;
- return Quaternion(q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w);
+ return Quaternion(q1.x - p_q2.x, q1.y - p_q2.y, q1.z - p_q2.z, q1.w - p_q2.w);
}
Quaternion Quaternion::operator-() const {
@@ -209,12 +209,12 @@ Quaternion Quaternion::operator-() const {
return Quaternion(-q2.x, -q2.y, -q2.z, -q2.w);
}
-Quaternion Quaternion::operator*(const real_t &s) const {
- return Quaternion(x * s, y * s, z * s, w * s);
+Quaternion Quaternion::operator*(real_t p_s) const {
+ return Quaternion(x * p_s, y * p_s, z * p_s, w * p_s);
}
-Quaternion Quaternion::operator/(const real_t &s) const {
- return *this * (1.0f / s);
+Quaternion Quaternion::operator/(real_t p_s) const {
+ return *this * (1.0f / p_s);
}
bool Quaternion::operator==(const Quaternion &p_quaternion) const {
@@ -225,7 +225,7 @@ bool Quaternion::operator!=(const Quaternion &p_quaternion) const {
return x != p_quaternion.x || y != p_quaternion.y || z != p_quaternion.z || w != p_quaternion.w;
}
-_FORCE_INLINE_ Quaternion operator*(const real_t &p_real, const Quaternion &p_quaternion) {
+_FORCE_INLINE_ Quaternion operator*(real_t p_real, const Quaternion &p_quaternion) {
return p_quaternion * p_real;
}
diff --git a/core/math/random_number_generator.cpp b/core/math/random_number_generator.cpp
index c3f36b32a5..226d748c52 100644
--- a/core/math/random_number_generator.cpp
+++ b/core/math/random_number_generator.cpp
@@ -42,6 +42,7 @@ void RandomNumberGenerator::_bind_methods() {
ClassDB::bind_method(D_METHOD("randfn", "mean", "deviation"), &RandomNumberGenerator::randfn, DEFVAL(0.0), DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("randf_range", "from", "to"), &RandomNumberGenerator::randf_range);
ClassDB::bind_method(D_METHOD("randi_range", "from", "to"), &RandomNumberGenerator::randi_range);
+ ClassDB::bind_method(D_METHOD("rand_weighted", "weights"), &RandomNumberGenerator::rand_weighted);
ClassDB::bind_method(D_METHOD("randomize"), &RandomNumberGenerator::randomize);
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h
index e1c353d439..7ec4cdffb0 100644
--- a/core/math/random_number_generator.h
+++ b/core/math/random_number_generator.h
@@ -57,6 +57,8 @@ public:
_FORCE_INLINE_ real_t randfn(real_t p_mean = 0.0, real_t p_deviation = 1.0) { return randbase.randfn(p_mean, p_deviation); }
_FORCE_INLINE_ int randi_range(int p_from, int p_to) { return randbase.random(p_from, p_to); }
+ _FORCE_INLINE_ int64_t rand_weighted(const Vector<float> &p_weights) { return randbase.rand_weighted(p_weights); }
+
RandomNumberGenerator() { randbase.randomize(); }
};
diff --git a/core/math/random_pcg.cpp b/core/math/random_pcg.cpp
index 45a9285ddd..e083820494 100644
--- a/core/math/random_pcg.cpp
+++ b/core/math/random_pcg.cpp
@@ -31,6 +31,7 @@
#include "random_pcg.h"
#include "core/os/os.h"
+#include "core/templates/vector.h"
RandomPCG::RandomPCG(uint64_t p_seed, uint64_t p_inc) :
pcg(),
@@ -42,6 +43,26 @@ void RandomPCG::randomize() {
seed(((uint64_t)OS::get_singleton()->get_unix_time() + OS::get_singleton()->get_ticks_usec()) * pcg.state + PCG_DEFAULT_INC_64);
}
+int64_t RandomPCG::rand_weighted(const Vector<float> &p_weights) {
+ ERR_FAIL_COND_V_MSG(p_weights.is_empty(), -1, "Weights array is empty.");
+ int64_t weights_size = p_weights.size();
+ const float *weights = p_weights.ptr();
+ float weights_sum = 0.0;
+ for (int64_t i = 0; i < weights_size; ++i) {
+ weights_sum += weights[i];
+ }
+
+ float remaining_distance = Math::randf() * weights_sum;
+ for (int64_t i = 0; i < weights_size; ++i) {
+ remaining_distance -= weights[i];
+ if (remaining_distance < 0) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
double RandomPCG::random(double p_from, double p_to) {
return randd() * (p_to - p_from) + p_from;
}
diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h
index cc22b23b70..fd0934b24a 100644
--- a/core/math/random_pcg.h
+++ b/core/math/random_pcg.h
@@ -59,6 +59,9 @@ static int __bsr_clz32(uint32_t x) {
#define LDEXPF(s, e) ldexp(s, e)
#endif
+template <class T>
+class Vector;
+
class RandomPCG {
pcg32_random_t pcg;
uint64_t current_seed = 0; // The seed the current generator state started from.
@@ -87,6 +90,8 @@ public:
return pcg32_boundedrand_r(&pcg, bounds);
}
+ int64_t rand_weighted(const Vector<float> &p_weights);
+
// Obtaining floating point numbers in [0, 1] range with "good enough" uniformity.
// These functions sample the output of rand() as the fraction part of an infinite binary number,
// with some tricks applied to reduce ops and branching:
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 5f403458fd..0f874d4857 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -51,7 +51,7 @@ struct _NO_DISCARD_ Rect2 {
_FORCE_INLINE_ Vector2 get_center() const { return position + (size * 0.5f); }
- inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const {
+ inline bool intersects(const Rect2 &p_rect, bool p_include_borders = false) const {
#ifdef MATH_CHECKS
if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index a22d075b64..f6525fe5ca 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -65,7 +65,7 @@ Transform2D Transform2D::affine_inverse() const {
return inv;
}
-void Transform2D::rotate(const real_t p_angle) {
+void Transform2D::rotate(real_t p_angle) {
*this = Transform2D(p_angle, Vector2()) * (*this);
}
@@ -74,7 +74,7 @@ real_t Transform2D::get_skew() const {
return Math::acos(columns[0].normalized().dot(SIGN(det) * columns[1].normalized())) - (real_t)Math_PI * 0.5f;
}
-void Transform2D::set_skew(const real_t p_angle) {
+void Transform2D::set_skew(real_t p_angle) {
real_t det = determinant();
columns[1] = SIGN(det) * columns[0].rotated(((real_t)Math_PI * 0.5f + p_angle)).normalized() * columns[1].length();
}
@@ -83,7 +83,7 @@ real_t Transform2D::get_rotation() const {
return Math::atan2(columns[0].y, columns[0].x);
}
-void Transform2D::set_rotation(const real_t p_rot) {
+void Transform2D::set_rotation(real_t p_rot) {
Size2 scale = get_scale();
real_t cr = Math::cos(p_rot);
real_t sr = Math::sin(p_rot);
@@ -94,7 +94,7 @@ void Transform2D::set_rotation(const real_t p_rot) {
set_scale(scale);
}
-Transform2D::Transform2D(const real_t p_rot, const Vector2 &p_pos) {
+Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) {
real_t cr = Math::cos(p_rot);
real_t sr = Math::sin(p_rot);
columns[0][0] = cr;
@@ -104,7 +104,7 @@ Transform2D::Transform2D(const real_t p_rot, const Vector2 &p_pos) {
columns[2] = p_pos;
}
-Transform2D::Transform2D(const real_t p_rot, const Size2 &p_scale, const real_t p_skew, const Vector2 &p_pos) {
+Transform2D::Transform2D(real_t p_rot, const Size2 &p_scale, real_t p_skew, const Vector2 &p_pos) {
columns[0][0] = Math::cos(p_rot) * p_scale.x;
columns[1][1] = Math::cos(p_rot + p_skew) * p_scale.y;
columns[1][0] = -Math::sin(p_rot + p_skew) * p_scale.y;
@@ -136,7 +136,7 @@ void Transform2D::scale_basis(const Size2 &p_scale) {
columns[1][1] *= p_scale.y;
}
-void Transform2D::translate_local(const real_t p_tx, const real_t p_ty) {
+void Transform2D::translate_local(real_t p_tx, real_t p_ty) {
translate_local(Vector2(p_tx, p_ty));
}
@@ -261,12 +261,12 @@ Transform2D Transform2D::translated_local(const Vector2 &p_offset) const {
return Transform2D(columns[0], columns[1], columns[2] + basis_xform(p_offset));
}
-Transform2D Transform2D::rotated(const real_t p_angle) const {
+Transform2D Transform2D::rotated(real_t p_angle) const {
// Equivalent to left multiplication
return Transform2D(p_angle, Vector2()) * (*this);
}
-Transform2D Transform2D::rotated_local(const real_t p_angle) const {
+Transform2D Transform2D::rotated_local(real_t p_angle) const {
// Equivalent to right multiplication
return (*this) * Transform2D(p_angle, Vector2()); // Could be optimized, because origin transform can be skipped.
}
@@ -275,7 +275,7 @@ real_t Transform2D::determinant() const {
return columns[0].x * columns[1].y - columns[0].y * columns[1].x;
}
-Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, const real_t p_weight) const {
+Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t p_weight) const {
return Transform2D(
Math::lerp_angle(get_rotation(), p_transform.get_rotation(), p_weight),
get_scale().lerp(p_transform.get_scale(), p_weight),
@@ -283,25 +283,25 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, const
get_origin().lerp(p_transform.get_origin(), p_weight));
}
-void Transform2D::operator*=(const real_t p_val) {
+void Transform2D::operator*=(real_t p_val) {
columns[0] *= p_val;
columns[1] *= p_val;
columns[2] *= p_val;
}
-Transform2D Transform2D::operator*(const real_t p_val) const {
+Transform2D Transform2D::operator*(real_t p_val) const {
Transform2D ret(*this);
ret *= p_val;
return ret;
}
-void Transform2D::operator/=(const real_t p_val) {
+void Transform2D::operator/=(real_t p_val) {
columns[0] /= p_val;
columns[1] /= p_val;
columns[2] /= p_val;
}
-Transform2D Transform2D::operator/(const real_t p_val) const {
+Transform2D Transform2D::operator/(real_t p_val) const {
Transform2D ret(*this);
ret /= p_val;
return ret;
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index 9ff925f66f..4ec2dc119c 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -52,8 +52,8 @@ struct _NO_DISCARD_ Transform2D {
Vector2 columns[3];
- _FORCE_INLINE_ real_t tdotx(const Vector2 &v) const { return columns[0][0] * v.x + columns[1][0] * v.y; }
- _FORCE_INLINE_ real_t tdoty(const Vector2 &v) const { return columns[0][1] * v.x + columns[1][1] * v.y; }
+ _FORCE_INLINE_ real_t tdotx(const Vector2 &p_v) const { return columns[0][0] * p_v.x + columns[1][0] * p_v.y; }
+ _FORCE_INLINE_ real_t tdoty(const Vector2 &p_v) const { return columns[0][1] * p_v.x + columns[1][1] * p_v.y; }
const Vector2 &operator[](int p_idx) const { return columns[p_idx]; }
Vector2 &operator[](int p_idx) { return columns[p_idx]; }
@@ -64,17 +64,17 @@ struct _NO_DISCARD_ Transform2D {
void affine_invert();
Transform2D affine_inverse() const;
- void set_rotation(const real_t p_rot);
+ void set_rotation(real_t p_rot);
real_t get_rotation() const;
real_t get_skew() const;
- void set_skew(const real_t p_angle);
- _FORCE_INLINE_ void set_rotation_and_scale(const real_t p_rot, const Size2 &p_scale);
- _FORCE_INLINE_ void set_rotation_scale_and_skew(const real_t p_rot, const Size2 &p_scale, const real_t p_skew);
- void rotate(const real_t p_angle);
+ void set_skew(real_t p_angle);
+ _FORCE_INLINE_ void set_rotation_and_scale(real_t p_rot, const Size2 &p_scale);
+ _FORCE_INLINE_ void set_rotation_scale_and_skew(real_t p_rot, const Size2 &p_scale, real_t p_skew);
+ void rotate(real_t p_angle);
void scale(const Size2 &p_scale);
void scale_basis(const Size2 &p_scale);
- void translate_local(const real_t p_tx, const real_t p_ty);
+ void translate_local(real_t p_tx, real_t p_ty);
void translate_local(const Vector2 &p_translation);
real_t determinant() const;
@@ -89,8 +89,8 @@ struct _NO_DISCARD_ Transform2D {
Transform2D scaled_local(const Size2 &p_scale) const;
Transform2D translated(const Vector2 &p_offset) const;
Transform2D translated_local(const Vector2 &p_offset) const;
- Transform2D rotated(const real_t p_angle) const;
- Transform2D rotated_local(const real_t p_angle) const;
+ Transform2D rotated(real_t p_angle) const;
+ Transform2D rotated_local(real_t p_angle) const;
Transform2D untranslated() const;
@@ -107,12 +107,12 @@ struct _NO_DISCARD_ Transform2D {
void operator*=(const Transform2D &p_transform);
Transform2D operator*(const Transform2D &p_transform) const;
- void operator*=(const real_t p_val);
- Transform2D operator*(const real_t p_val) const;
- void operator/=(const real_t p_val);
- Transform2D operator/(const real_t p_val) const;
+ void operator*=(real_t p_val);
+ Transform2D operator*(real_t p_val) const;
+ void operator/=(real_t p_val);
+ Transform2D operator/(real_t p_val) const;
- Transform2D interpolate_with(const Transform2D &p_transform, const real_t p_c) const;
+ Transform2D interpolate_with(const Transform2D &p_transform, real_t p_c) const;
_FORCE_INLINE_ Vector2 basis_xform(const Vector2 &p_vec) const;
_FORCE_INLINE_ Vector2 basis_xform_inv(const Vector2 &p_vec) const;
@@ -125,13 +125,13 @@ struct _NO_DISCARD_ Transform2D {
operator String() const;
- Transform2D(const real_t xx, const real_t xy, const real_t yx, const real_t yy, const real_t ox, const real_t oy) {
- columns[0][0] = xx;
- columns[0][1] = xy;
- columns[1][0] = yx;
- columns[1][1] = yy;
- columns[2][0] = ox;
- columns[2][1] = oy;
+ Transform2D(real_t p_xx, real_t p_xy, real_t p_yx, real_t p_yy, real_t p_ox, real_t p_oy) {
+ columns[0][0] = p_xx;
+ columns[0][1] = p_xy;
+ columns[1][0] = p_yx;
+ columns[1][1] = p_yy;
+ columns[2][0] = p_ox;
+ columns[2][1] = p_oy;
}
Transform2D(const Vector2 &p_x, const Vector2 &p_y, const Vector2 &p_origin) {
@@ -140,9 +140,9 @@ struct _NO_DISCARD_ Transform2D {
columns[2] = p_origin;
}
- Transform2D(const real_t p_rot, const Vector2 &p_pos);
+ Transform2D(real_t p_rot, const Vector2 &p_pos);
- Transform2D(const real_t p_rot, const Size2 &p_scale, const real_t p_skew, const Vector2 &p_pos);
+ Transform2D(real_t p_rot, const Size2 &p_scale, real_t p_skew, const Vector2 &p_pos);
Transform2D() {
columns[0][0] = 1.0;
@@ -190,14 +190,14 @@ Rect2 Transform2D::xform(const Rect2 &p_rect) const {
return new_rect;
}
-void Transform2D::set_rotation_and_scale(const real_t p_rot, const Size2 &p_scale) {
+void Transform2D::set_rotation_and_scale(real_t p_rot, const Size2 &p_scale) {
columns[0][0] = Math::cos(p_rot) * p_scale.x;
columns[1][1] = Math::cos(p_rot) * p_scale.y;
columns[1][0] = -Math::sin(p_rot) * p_scale.y;
columns[0][1] = Math::sin(p_rot) * p_scale.x;
}
-void Transform2D::set_rotation_scale_and_skew(const real_t p_rot, const Size2 &p_scale, const real_t p_skew) {
+void Transform2D::set_rotation_scale_and_skew(real_t p_rot, const Size2 &p_scale, real_t p_skew) {
columns[0][0] = Math::cos(p_rot) * p_scale.x;
columns[1][1] = Math::cos(p_rot + p_skew) * p_scale.y;
columns[1][0] = -Math::sin(p_rot + p_skew) * p_scale.y;
diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp
index 20713349d7..2c91a7604b 100644
--- a/core/math/transform_3d.cpp
+++ b/core/math/transform_3d.cpp
@@ -197,23 +197,23 @@ Transform3D Transform3D::operator*(const Transform3D &p_transform) const {
return t;
}
-void Transform3D::operator*=(const real_t p_val) {
+void Transform3D::operator*=(real_t p_val) {
origin *= p_val;
basis *= p_val;
}
-Transform3D Transform3D::operator*(const real_t p_val) const {
+Transform3D Transform3D::operator*(real_t p_val) const {
Transform3D ret(*this);
ret *= p_val;
return ret;
}
-void Transform3D::operator/=(const real_t p_val) {
+void Transform3D::operator/=(real_t p_val) {
basis /= p_val;
origin /= p_val;
}
-Transform3D Transform3D::operator/(const real_t p_val) const {
+Transform3D Transform3D::operator/(real_t p_val) const {
Transform3D ret(*this);
ret /= p_val;
return ret;
@@ -238,7 +238,7 @@ Transform3D::Transform3D(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &
basis.set_column(2, p_z);
}
-Transform3D::Transform3D(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz) {
- basis = Basis(xx, xy, xz, yx, yy, yz, zx, zy, zz);
- origin = Vector3(ox, oy, oz);
+Transform3D::Transform3D(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_ox, real_t p_oy, real_t p_oz) {
+ basis = Basis(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz);
+ origin = Vector3(p_ox, p_oy, p_oz);
}
diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h
index d1ec34d53f..7d89b86c75 100644
--- a/core/math/transform_3d.h
+++ b/core/math/transform_3d.h
@@ -102,10 +102,10 @@ struct _NO_DISCARD_ Transform3D {
void operator*=(const Transform3D &p_transform);
Transform3D operator*(const Transform3D &p_transform) const;
- void operator*=(const real_t p_val);
- Transform3D operator*(const real_t p_val) const;
- void operator/=(const real_t p_val);
- Transform3D operator/(const real_t p_val) const;
+ void operator*=(real_t p_val);
+ Transform3D operator*(real_t p_val) const;
+ void operator/=(real_t p_val);
+ Transform3D operator/(real_t p_val) const;
Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const;
@@ -115,11 +115,11 @@ struct _NO_DISCARD_ Transform3D {
basis.xform(v));
}
- void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t tx, real_t ty, real_t tz) {
- basis.set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
- origin.x = tx;
- origin.y = ty;
- origin.z = tz;
+ void set(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_tx, real_t p_ty, real_t p_tz) {
+ basis.set(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz);
+ origin.x = p_tx;
+ origin.y = p_ty;
+ origin.z = p_tz;
}
operator String() const;
@@ -127,7 +127,7 @@ struct _NO_DISCARD_ Transform3D {
Transform3D() {}
Transform3D(const Basis &p_basis, const Vector3 &p_origin = Vector3());
Transform3D(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin);
- Transform3D(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz);
+ Transform3D(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_ox, real_t p_oy, real_t p_oz);
};
_FORCE_INLINE_ Vector3 Transform3D::xform(const Vector3 &p_vector) const {
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index 74631d3e29..198fd85d20 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -37,7 +37,7 @@ real_t Vector2::angle() const {
return Math::atan2(y, x);
}
-Vector2 Vector2::from_angle(const real_t p_angle) {
+Vector2 Vector2::from_angle(real_t p_angle) {
return Vector2(Math::cos(p_angle), Math::sin(p_angle));
}
@@ -109,7 +109,7 @@ Vector2 Vector2::round() const {
return Vector2(Math::round(x), Math::round(y));
}
-Vector2 Vector2::rotated(const real_t p_by) const {
+Vector2 Vector2::rotated(real_t p_by) const {
real_t sine = Math::sin(p_by);
real_t cosi = Math::cos(p_by);
return Vector2(
@@ -117,7 +117,7 @@ Vector2 Vector2::rotated(const real_t p_by) const {
x * sine + y * cosi);
}
-Vector2 Vector2::posmod(const real_t p_mod) const {
+Vector2 Vector2::posmod(real_t p_mod) const {
return Vector2(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod));
}
@@ -141,7 +141,7 @@ Vector2 Vector2::snapped(const Vector2 &p_step) const {
Math::snapped(y, p_step.y));
}
-Vector2 Vector2::limit_length(const real_t p_len) const {
+Vector2 Vector2::limit_length(real_t p_len) const {
const real_t l = length();
Vector2 v = *this;
if (l > 0 && p_len < l) {
@@ -152,7 +152,7 @@ Vector2 Vector2::limit_length(const real_t p_len) const {
return v;
}
-Vector2 Vector2::move_toward(const Vector2 &p_to, const real_t p_delta) const {
+Vector2 Vector2::move_toward(const Vector2 &p_to, real_t p_delta) const {
Vector2 v = *this;
Vector2 vd = p_to - v;
real_t len = vd.length();
diff --git a/core/math/vector2.h b/core/math/vector2.h
index b9d7709acd..6ad003edd1 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -60,13 +60,13 @@ struct _NO_DISCARD_ Vector2 {
real_t coord[2] = { 0 };
};
- _FORCE_INLINE_ real_t &operator[](int p_idx) {
- DEV_ASSERT((unsigned int)p_idx < 2);
- return coord[p_idx];
+ _FORCE_INLINE_ real_t &operator[](int p_axis) {
+ DEV_ASSERT((unsigned int)p_axis < 2);
+ return coord[p_axis];
}
- _FORCE_INLINE_ const real_t &operator[](int p_idx) const {
- DEV_ASSERT((unsigned int)p_idx < 2);
- return coord[p_idx];
+ _FORCE_INLINE_ const real_t &operator[](int p_axis) const {
+ DEV_ASSERT((unsigned int)p_axis < 2);
+ return coord[p_axis];
}
_FORCE_INLINE_ Vector2::Axis min_axis_index() const {
@@ -83,7 +83,7 @@ struct _NO_DISCARD_ Vector2 {
real_t length() const;
real_t length_squared() const;
- Vector2 limit_length(const real_t p_len = 1.0) const;
+ Vector2 limit_length(real_t p_len = 1.0) const;
Vector2 min(const Vector2 &p_vector2) const {
return Vector2(MIN(x, p_vector2.x), MIN(y, p_vector2.y));
@@ -101,20 +101,20 @@ struct _NO_DISCARD_ Vector2 {
real_t dot(const Vector2 &p_other) const;
real_t cross(const Vector2 &p_other) const;
- Vector2 posmod(const real_t p_mod) const;
+ Vector2 posmod(real_t p_mod) const;
Vector2 posmodv(const Vector2 &p_modv) const;
Vector2 project(const Vector2 &p_to) const;
- Vector2 plane_project(const real_t p_d, const Vector2 &p_vec) const;
+ Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const;
- _FORCE_INLINE_ Vector2 lerp(const Vector2 &p_to, const real_t p_weight) const;
- _FORCE_INLINE_ Vector2 slerp(const Vector2 &p_to, const real_t p_weight) const;
- _FORCE_INLINE_ Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight) const;
- _FORCE_INLINE_ Vector2 cubic_interpolate_in_time(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const;
- _FORCE_INLINE_ Vector2 bezier_interpolate(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) const;
- _FORCE_INLINE_ Vector2 bezier_derivative(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) const;
+ _FORCE_INLINE_ Vector2 lerp(const Vector2 &p_to, real_t p_weight) const;
+ _FORCE_INLINE_ Vector2 slerp(const Vector2 &p_to, real_t p_weight) const;
+ _FORCE_INLINE_ Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_weight) const;
+ _FORCE_INLINE_ Vector2 cubic_interpolate_in_time(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_weight, real_t p_b_t, real_t p_pre_a_t, real_t p_post_b_t) const;
+ _FORCE_INLINE_ Vector2 bezier_interpolate(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, real_t p_t) const;
+ _FORCE_INLINE_ Vector2 bezier_derivative(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, real_t p_t) const;
- Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const;
+ Vector2 move_toward(const Vector2 &p_to, real_t p_delta) const;
Vector2 slide(const Vector2 &p_normal) const;
Vector2 bounce(const Vector2 &p_normal) const;
@@ -130,16 +130,16 @@ struct _NO_DISCARD_ Vector2 {
void operator-=(const Vector2 &p_v);
Vector2 operator*(const Vector2 &p_v1) const;
- Vector2 operator*(const real_t &rvalue) const;
- void operator*=(const real_t &rvalue);
- void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; }
+ Vector2 operator*(real_t p_rvalue) const;
+ void operator*=(real_t p_rvalue);
+ void operator*=(const Vector2 &p_rvalue) { *this = *this * p_rvalue; }
Vector2 operator/(const Vector2 &p_v1) const;
- Vector2 operator/(const real_t &rvalue) const;
+ Vector2 operator/(real_t p_rvalue) const;
- void operator/=(const real_t &rvalue);
- void operator/=(const Vector2 &rvalue) { *this = *this / rvalue; }
+ void operator/=(real_t p_rvalue);
+ void operator/=(const Vector2 &p_rvalue) { *this = *this / p_rvalue; }
Vector2 operator-() const;
@@ -152,13 +152,13 @@ struct _NO_DISCARD_ Vector2 {
bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); }
real_t angle() const;
- static Vector2 from_angle(const real_t p_angle);
+ static Vector2 from_angle(real_t p_angle);
_FORCE_INLINE_ Vector2 abs() const {
return Vector2(Math::abs(x), Math::abs(y));
}
- Vector2 rotated(const real_t p_by) const;
+ Vector2 rotated(real_t p_by) const;
Vector2 orthogonal() const {
return Vector2(y, -x);
}
@@ -175,13 +175,13 @@ struct _NO_DISCARD_ Vector2 {
operator Vector2i() const;
_FORCE_INLINE_ Vector2() {}
- _FORCE_INLINE_ Vector2(const real_t p_x, const real_t p_y) {
+ _FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) {
x = p_x;
y = p_y;
}
};
-_FORCE_INLINE_ Vector2 Vector2::plane_project(const real_t p_d, const Vector2 &p_vec) const {
+_FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const {
return p_vec - *this * (dot(p_vec) - p_d);
}
@@ -207,26 +207,26 @@ _FORCE_INLINE_ Vector2 Vector2::operator*(const Vector2 &p_v1) const {
return Vector2(x * p_v1.x, y * p_v1.y);
}
-_FORCE_INLINE_ Vector2 Vector2::operator*(const real_t &rvalue) const {
- return Vector2(x * rvalue, y * rvalue);
+_FORCE_INLINE_ Vector2 Vector2::operator*(real_t p_rvalue) const {
+ return Vector2(x * p_rvalue, y * p_rvalue);
}
-_FORCE_INLINE_ void Vector2::operator*=(const real_t &rvalue) {
- x *= rvalue;
- y *= rvalue;
+_FORCE_INLINE_ void Vector2::operator*=(real_t p_rvalue) {
+ x *= p_rvalue;
+ y *= p_rvalue;
}
_FORCE_INLINE_ Vector2 Vector2::operator/(const Vector2 &p_v1) const {
return Vector2(x / p_v1.x, y / p_v1.y);
}
-_FORCE_INLINE_ Vector2 Vector2::operator/(const real_t &rvalue) const {
- return Vector2(x / rvalue, y / rvalue);
+_FORCE_INLINE_ Vector2 Vector2::operator/(real_t p_rvalue) const {
+ return Vector2(x / p_rvalue, y / p_rvalue);
}
-_FORCE_INLINE_ void Vector2::operator/=(const real_t &rvalue) {
- x /= rvalue;
- y /= rvalue;
+_FORCE_INLINE_ void Vector2::operator/=(real_t p_rvalue) {
+ x /= p_rvalue;
+ y /= p_rvalue;
}
_FORCE_INLINE_ Vector2 Vector2::operator-() const {
@@ -241,14 +241,14 @@ _FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const {
return x != p_vec2.x || y != p_vec2.y;
}
-Vector2 Vector2::lerp(const Vector2 &p_to, const real_t p_weight) const {
+Vector2 Vector2::lerp(const Vector2 &p_to, real_t p_weight) const {
Vector2 res = *this;
res.x = Math::lerp(res.x, p_to.x, p_weight);
res.y = Math::lerp(res.y, p_to.y, p_weight);
return res;
}
-Vector2 Vector2::slerp(const Vector2 &p_to, const real_t p_weight) const {
+Vector2 Vector2::slerp(const Vector2 &p_to, real_t p_weight) const {
real_t start_length_sq = length_squared();
real_t end_length_sq = p_to.length_squared();
if (unlikely(start_length_sq == 0.0f || end_length_sq == 0.0f)) {
@@ -261,28 +261,28 @@ Vector2 Vector2::slerp(const Vector2 &p_to, const real_t p_weight) const {
return rotated(angle * p_weight) * (result_length / start_length);
}
-Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight) const {
+Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_weight) const {
Vector2 res = *this;
res.x = Math::cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight);
res.y = Math::cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight);
return res;
}
-Vector2 Vector2::cubic_interpolate_in_time(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const {
+Vector2 Vector2::cubic_interpolate_in_time(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_weight, real_t p_b_t, real_t p_pre_a_t, real_t p_post_b_t) const {
Vector2 res = *this;
res.x = Math::cubic_interpolate_in_time(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
res.y = Math::cubic_interpolate_in_time(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
return res;
}
-Vector2 Vector2::bezier_interpolate(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) const {
+Vector2 Vector2::bezier_interpolate(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, real_t p_t) const {
Vector2 res = *this;
res.x = Math::bezier_interpolate(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t);
res.y = Math::bezier_interpolate(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t);
return res;
}
-Vector2 Vector2::bezier_derivative(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) const {
+Vector2 Vector2::bezier_derivative(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, real_t p_t) const {
Vector2 res = *this;
res.x = Math::bezier_derivative(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t);
res.y = Math::bezier_derivative(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t);
@@ -298,19 +298,19 @@ Vector2 Vector2::direction_to(const Vector2 &p_to) const {
// Multiplication operators required to workaround issues with LLVM using implicit conversion
// to Vector2i instead for integers where it should not.
-_FORCE_INLINE_ Vector2 operator*(const float p_scalar, const Vector2 &p_vec) {
+_FORCE_INLINE_ Vector2 operator*(float p_scalar, const Vector2 &p_vec) {
return p_vec * p_scalar;
}
-_FORCE_INLINE_ Vector2 operator*(const double p_scalar, const Vector2 &p_vec) {
+_FORCE_INLINE_ Vector2 operator*(double p_scalar, const Vector2 &p_vec) {
return p_vec * p_scalar;
}
-_FORCE_INLINE_ Vector2 operator*(const int32_t p_scalar, const Vector2 &p_vec) {
+_FORCE_INLINE_ Vector2 operator*(int32_t p_scalar, const Vector2 &p_vec) {
return p_vec * p_scalar;
}
-_FORCE_INLINE_ Vector2 operator*(const int64_t p_scalar, const Vector2 &p_vec) {
+_FORCE_INLINE_ Vector2 operator*(int64_t p_scalar, const Vector2 &p_vec) {
return p_vec * p_scalar;
}
diff --git a/core/math/vector2i.cpp b/core/math/vector2i.cpp
index 9c7da668ff..ba79d439dd 100644
--- a/core/math/vector2i.cpp
+++ b/core/math/vector2i.cpp
@@ -75,39 +75,39 @@ Vector2i Vector2i::operator*(const Vector2i &p_v1) const {
return Vector2i(x * p_v1.x, y * p_v1.y);
}
-Vector2i Vector2i::operator*(const int32_t &rvalue) const {
- return Vector2i(x * rvalue, y * rvalue);
+Vector2i Vector2i::operator*(int32_t p_rvalue) const {
+ return Vector2i(x * p_rvalue, y * p_rvalue);
}
-void Vector2i::operator*=(const int32_t &rvalue) {
- x *= rvalue;
- y *= rvalue;
+void Vector2i::operator*=(int32_t p_rvalue) {
+ x *= p_rvalue;
+ y *= p_rvalue;
}
Vector2i Vector2i::operator/(const Vector2i &p_v1) const {
return Vector2i(x / p_v1.x, y / p_v1.y);
}
-Vector2i Vector2i::operator/(const int32_t &rvalue) const {
- return Vector2i(x / rvalue, y / rvalue);
+Vector2i Vector2i::operator/(int32_t p_rvalue) const {
+ return Vector2i(x / p_rvalue, y / p_rvalue);
}
-void Vector2i::operator/=(const int32_t &rvalue) {
- x /= rvalue;
- y /= rvalue;
+void Vector2i::operator/=(int32_t p_rvalue) {
+ x /= p_rvalue;
+ y /= p_rvalue;
}
Vector2i Vector2i::operator%(const Vector2i &p_v1) const {
return Vector2i(x % p_v1.x, y % p_v1.y);
}
-Vector2i Vector2i::operator%(const int32_t &rvalue) const {
- return Vector2i(x % rvalue, y % rvalue);
+Vector2i Vector2i::operator%(int32_t p_rvalue) const {
+ return Vector2i(x % p_rvalue, y % p_rvalue);
}
-void Vector2i::operator%=(const int32_t &rvalue) {
- x %= rvalue;
- y %= rvalue;
+void Vector2i::operator%=(int32_t p_rvalue) {
+ x %= p_rvalue;
+ y %= p_rvalue;
}
Vector2i Vector2i::operator-() const {
diff --git a/core/math/vector2i.h b/core/math/vector2i.h
index b2c75beb4d..aa29263a65 100644
--- a/core/math/vector2i.h
+++ b/core/math/vector2i.h
@@ -60,13 +60,13 @@ struct _NO_DISCARD_ Vector2i {
int32_t coord[2] = { 0 };
};
- _FORCE_INLINE_ int32_t &operator[](int p_idx) {
- DEV_ASSERT((unsigned int)p_idx < 2);
- return coord[p_idx];
+ _FORCE_INLINE_ int32_t &operator[](int p_axis) {
+ DEV_ASSERT((unsigned int)p_axis < 2);
+ return coord[p_axis];
}
- _FORCE_INLINE_ const int32_t &operator[](int p_idx) const {
- DEV_ASSERT((unsigned int)p_idx < 2);
- return coord[p_idx];
+ _FORCE_INLINE_ const int32_t &operator[](int p_axis) const {
+ DEV_ASSERT((unsigned int)p_axis < 2);
+ return coord[p_axis];
}
_FORCE_INLINE_ Vector2i::Axis min_axis_index() const {
@@ -99,16 +99,16 @@ struct _NO_DISCARD_ Vector2i {
void operator-=(const Vector2i &p_v);
Vector2i operator*(const Vector2i &p_v1) const;
- Vector2i operator*(const int32_t &rvalue) const;
- void operator*=(const int32_t &rvalue);
+ Vector2i operator*(int32_t p_rvalue) const;
+ void operator*=(int32_t p_rvalue);
Vector2i operator/(const Vector2i &p_v1) const;
- Vector2i operator/(const int32_t &rvalue) const;
- void operator/=(const int32_t &rvalue);
+ Vector2i operator/(int32_t p_rvalue) const;
+ void operator/=(int32_t p_rvalue);
Vector2i operator%(const Vector2i &p_v1) const;
- Vector2i operator%(const int32_t &rvalue) const;
- void operator%=(const int32_t &rvalue);
+ Vector2i operator%(int32_t p_rvalue) const;
+ void operator%=(int32_t p_rvalue);
Vector2i operator-() const;
bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
@@ -133,7 +133,7 @@ struct _NO_DISCARD_ Vector2i {
operator Vector2() const;
inline Vector2i() {}
- inline Vector2i(const int32_t p_x, const int32_t p_y) {
+ inline Vector2i(int32_t p_x, int32_t p_y) {
x = p_x;
y = p_y;
}
@@ -141,19 +141,19 @@ struct _NO_DISCARD_ Vector2i {
// Multiplication operators required to workaround issues with LLVM using implicit conversion.
-_FORCE_INLINE_ Vector2i operator*(const int32_t p_scalar, const Vector2i &p_vector) {
+_FORCE_INLINE_ Vector2i operator*(int32_t p_scalar, const Vector2i &p_vector) {
return p_vector * p_scalar;
}
-_FORCE_INLINE_ Vector2i operator*(const int64_t p_scalar, const Vector2i &p_vector) {
+_FORCE_INLINE_ Vector2i operator*(int64_t p_scalar, const Vector2i &p_vector) {
return p_vector * p_scalar;
}
-_FORCE_INLINE_ Vector2i operator*(const float p_scalar, const Vector2i &p_vector) {
+_FORCE_INLINE_ Vector2i operator*(float p_scalar, const Vector2i &p_vector) {
return p_vector * p_scalar;
}
-_FORCE_INLINE_ Vector2i operator*(const double p_scalar, const Vector2i &p_vector) {
+_FORCE_INLINE_ Vector2i operator*(double p_scalar, const Vector2i &p_vector) {
return p_vector * p_scalar;
}
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index c483d659a3..be494705ff 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -35,11 +35,11 @@
#include "core/math/vector3i.h"
#include "core/string/ustring.h"
-void Vector3::rotate(const Vector3 &p_axis, const real_t p_angle) {
+void Vector3::rotate(const Vector3 &p_axis, real_t p_angle) {
*this = Basis(p_axis, p_angle).xform(*this);
}
-Vector3 Vector3::rotated(const Vector3 &p_axis, const real_t p_angle) const {
+Vector3 Vector3::rotated(const Vector3 &p_axis, real_t p_angle) const {
Vector3 r = *this;
r.rotate(p_axis, p_angle);
return r;
@@ -52,19 +52,19 @@ Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const {
CLAMP(z, p_min.z, p_max.z));
}
-void Vector3::snap(const Vector3 p_step) {
+void Vector3::snap(const Vector3 &p_step) {
x = Math::snapped(x, p_step.x);
y = Math::snapped(y, p_step.y);
z = Math::snapped(z, p_step.z);
}
-Vector3 Vector3::snapped(const Vector3 p_step) const {
+Vector3 Vector3::snapped(const Vector3 &p_step) const {
Vector3 v = *this;
v.snap(p_step);
return v;
}
-Vector3 Vector3::limit_length(const real_t p_len) const {
+Vector3 Vector3::limit_length(real_t p_len) const {
const real_t l = length();
Vector3 v = *this;
if (l > 0 && p_len < l) {
@@ -75,7 +75,7 @@ Vector3 Vector3::limit_length(const real_t p_len) const {
return v;
}
-Vector3 Vector3::move_toward(const Vector3 &p_to, const real_t p_delta) const {
+Vector3 Vector3::move_toward(const Vector3 &p_to, real_t p_delta) const {
Vector3 v = *this;
Vector3 vd = p_to - v;
real_t len = vd.length();
@@ -107,19 +107,19 @@ Vector3 Vector3::octahedron_decode(const Vector2 &p_oct) {
return n.normalized();
}
-Vector2 Vector3::octahedron_tangent_encode(const float sign) const {
+Vector2 Vector3::octahedron_tangent_encode(float p_sign) const {
const float bias = 1.0f / 32767.0f;
Vector2 res = octahedron_encode();
res.y = MAX(res.y, bias);
res.y = res.y * 0.5f + 0.5f;
- res.y = sign >= 0.0f ? res.y : 1 - res.y;
+ res.y = p_sign >= 0.0f ? res.y : 1 - res.y;
return res;
}
-Vector3 Vector3::octahedron_tangent_decode(const Vector2 &p_oct, float *sign) {
+Vector3 Vector3::octahedron_tangent_decode(const Vector2 &p_oct, float *r_sign) {
Vector2 oct_compressed = p_oct;
oct_compressed.y = oct_compressed.y * 2 - 1;
- *sign = oct_compressed.y >= 0.0f ? 1.0f : -1.0f;
+ *r_sign = oct_compressed.y >= 0.0f ? 1.0f : -1.0f;
oct_compressed.y = Math::abs(oct_compressed.y);
Vector3 res = Vector3::octahedron_decode(oct_compressed);
return res;
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 5d4e2c7d87..f5d16984d9 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -58,12 +58,12 @@ struct _NO_DISCARD_ Vector3 {
real_t coord[3] = { 0 };
};
- _FORCE_INLINE_ const real_t &operator[](const int p_axis) const {
+ _FORCE_INLINE_ const real_t &operator[](int p_axis) const {
DEV_ASSERT((unsigned int)p_axis < 3);
return coord[p_axis];
}
- _FORCE_INLINE_ real_t &operator[](const int p_axis) {
+ _FORCE_INLINE_ real_t &operator[](int p_axis) {
DEV_ASSERT((unsigned int)p_axis < 3);
return coord[p_axis];
}
@@ -91,31 +91,31 @@ struct _NO_DISCARD_ Vector3 {
_FORCE_INLINE_ Vector3 normalized() const;
_FORCE_INLINE_ bool is_normalized() const;
_FORCE_INLINE_ Vector3 inverse() const;
- Vector3 limit_length(const real_t p_len = 1.0) const;
+ Vector3 limit_length(real_t p_len = 1.0) const;
_FORCE_INLINE_ void zero();
- void snap(const Vector3 p_val);
- Vector3 snapped(const Vector3 p_val) const;
+ void snap(const Vector3 &p_step);
+ Vector3 snapped(const Vector3 &p_step) const;
- void rotate(const Vector3 &p_axis, const real_t p_angle);
- Vector3 rotated(const Vector3 &p_axis, const real_t p_angle) const;
+ void rotate(const Vector3 &p_axis, real_t p_angle);
+ Vector3 rotated(const Vector3 &p_axis, real_t p_angle) const;
/* Static Methods between 2 vector3s */
- _FORCE_INLINE_ Vector3 lerp(const Vector3 &p_to, const real_t p_weight) const;
- _FORCE_INLINE_ Vector3 slerp(const Vector3 &p_to, const real_t p_weight) const;
- _FORCE_INLINE_ Vector3 cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) const;
- _FORCE_INLINE_ Vector3 cubic_interpolate_in_time(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const;
- _FORCE_INLINE_ Vector3 bezier_interpolate(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) const;
- _FORCE_INLINE_ Vector3 bezier_derivative(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) const;
+ _FORCE_INLINE_ Vector3 lerp(const Vector3 &p_to, real_t p_weight) const;
+ _FORCE_INLINE_ Vector3 slerp(const Vector3 &p_to, real_t p_weight) const;
+ _FORCE_INLINE_ Vector3 cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_weight) const;
+ _FORCE_INLINE_ Vector3 cubic_interpolate_in_time(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_weight, real_t p_b_t, real_t p_pre_a_t, real_t p_post_b_t) const;
+ _FORCE_INLINE_ Vector3 bezier_interpolate(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, real_t p_t) const;
+ _FORCE_INLINE_ Vector3 bezier_derivative(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, real_t p_t) const;
- Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const;
+ Vector3 move_toward(const Vector3 &p_to, real_t p_delta) const;
Vector2 octahedron_encode() const;
static Vector3 octahedron_decode(const Vector2 &p_oct);
- Vector2 octahedron_tangent_encode(const float sign) const;
- static Vector3 octahedron_tangent_decode(const Vector2 &p_oct, float *sign);
+ Vector2 octahedron_tangent_encode(float p_sign) const;
+ static Vector3 octahedron_tangent_decode(const Vector2 &p_oct, float *r_sign);
_FORCE_INLINE_ Vector3 cross(const Vector3 &p_with) const;
_FORCE_INLINE_ real_t dot(const Vector3 &p_with) const;
@@ -131,7 +131,7 @@ struct _NO_DISCARD_ Vector3 {
_FORCE_INLINE_ real_t distance_to(const Vector3 &p_to) const;
_FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_to) const;
- _FORCE_INLINE_ Vector3 posmod(const real_t p_mod) const;
+ _FORCE_INLINE_ Vector3 posmod(real_t p_mod) const;
_FORCE_INLINE_ Vector3 posmodv(const Vector3 &p_modv) const;
_FORCE_INLINE_ Vector3 project(const Vector3 &p_to) const;
@@ -158,10 +158,10 @@ struct _NO_DISCARD_ Vector3 {
_FORCE_INLINE_ Vector3 &operator/=(const Vector3 &p_v);
_FORCE_INLINE_ Vector3 operator/(const Vector3 &p_v) const;
- _FORCE_INLINE_ Vector3 &operator*=(const real_t p_scalar);
- _FORCE_INLINE_ Vector3 operator*(const real_t p_scalar) const;
- _FORCE_INLINE_ Vector3 &operator/=(const real_t p_scalar);
- _FORCE_INLINE_ Vector3 operator/(const real_t p_scalar) const;
+ _FORCE_INLINE_ Vector3 &operator*=(real_t p_scalar);
+ _FORCE_INLINE_ Vector3 operator*(real_t p_scalar) const;
+ _FORCE_INLINE_ Vector3 &operator/=(real_t p_scalar);
+ _FORCE_INLINE_ Vector3 operator/(real_t p_scalar) const;
_FORCE_INLINE_ Vector3 operator-() const;
@@ -176,7 +176,7 @@ struct _NO_DISCARD_ Vector3 {
operator Vector3i() const;
_FORCE_INLINE_ Vector3() {}
- _FORCE_INLINE_ Vector3(const real_t p_x, const real_t p_y, const real_t p_z) {
+ _FORCE_INLINE_ Vector3(real_t p_x, real_t p_y, real_t p_z) {
x = p_x;
y = p_y;
z = p_z;
@@ -216,7 +216,7 @@ Vector3 Vector3::round() const {
return Vector3(Math::round(x), Math::round(y), Math::round(z));
}
-Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const {
+Vector3 Vector3::lerp(const Vector3 &p_to, real_t p_weight) const {
Vector3 res = *this;
res.x = Math::lerp(res.x, p_to.x, p_weight);
res.y = Math::lerp(res.y, p_to.y, p_weight);
@@ -224,7 +224,7 @@ Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const {
return res;
}
-Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const {
+Vector3 Vector3::slerp(const Vector3 &p_to, real_t p_weight) const {
// This method seems more complicated than it really is, since we write out
// the internals of some methods for efficiency (mainly, checking length).
real_t start_length_sq = length_squared();
@@ -246,7 +246,7 @@ Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const {
return rotated(axis, angle * p_weight) * (result_length / start_length);
}
-Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) const {
+Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_weight) const {
Vector3 res = *this;
res.x = Math::cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight);
res.y = Math::cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight);
@@ -254,7 +254,7 @@ Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, c
return res;
}
-Vector3 Vector3::cubic_interpolate_in_time(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const {
+Vector3 Vector3::cubic_interpolate_in_time(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_weight, real_t p_b_t, real_t p_pre_a_t, real_t p_post_b_t) const {
Vector3 res = *this;
res.x = Math::cubic_interpolate_in_time(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
res.y = Math::cubic_interpolate_in_time(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
@@ -262,7 +262,7 @@ Vector3 Vector3::cubic_interpolate_in_time(const Vector3 &p_b, const Vector3 &p_
return res;
}
-Vector3 Vector3::bezier_interpolate(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) const {
+Vector3 Vector3::bezier_interpolate(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, real_t p_t) const {
Vector3 res = *this;
res.x = Math::bezier_interpolate(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t);
res.y = Math::bezier_interpolate(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t);
@@ -270,7 +270,7 @@ Vector3 Vector3::bezier_interpolate(const Vector3 &p_control_1, const Vector3 &p
return res;
}
-Vector3 Vector3::bezier_derivative(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) const {
+Vector3 Vector3::bezier_derivative(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, real_t p_t) const {
Vector3 res = *this;
res.x = Math::bezier_derivative(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t);
res.y = Math::bezier_derivative(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t);
@@ -286,7 +286,7 @@ real_t Vector3::distance_squared_to(const Vector3 &p_to) const {
return (p_to - *this).length_squared();
}
-Vector3 Vector3::posmod(const real_t p_mod) const {
+Vector3 Vector3::posmod(real_t p_mod) const {
return Vector3(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod), Math::fposmod(z, p_mod));
}
@@ -361,7 +361,7 @@ Vector3 Vector3::operator/(const Vector3 &p_v) const {
return Vector3(x / p_v.x, y / p_v.y, z / p_v.z);
}
-Vector3 &Vector3::operator*=(const real_t p_scalar) {
+Vector3 &Vector3::operator*=(real_t p_scalar) {
x *= p_scalar;
y *= p_scalar;
z *= p_scalar;
@@ -371,34 +371,34 @@ Vector3 &Vector3::operator*=(const real_t p_scalar) {
// Multiplication operators required to workaround issues with LLVM using implicit conversion
// to Vector3i instead for integers where it should not.
-_FORCE_INLINE_ Vector3 operator*(const float p_scalar, const Vector3 &p_vec) {
+_FORCE_INLINE_ Vector3 operator*(float p_scalar, const Vector3 &p_vec) {
return p_vec * p_scalar;
}
-_FORCE_INLINE_ Vector3 operator*(const double p_scalar, const Vector3 &p_vec) {
+_FORCE_INLINE_ Vector3 operator*(double p_scalar, const Vector3 &p_vec) {
return p_vec * p_scalar;
}
-_FORCE_INLINE_ Vector3 operator*(const int32_t p_scalar, const Vector3 &p_vec) {
+_FORCE_INLINE_ Vector3 operator*(int32_t p_scalar, const Vector3 &p_vec) {
return p_vec * p_scalar;
}
-_FORCE_INLINE_ Vector3 operator*(const int64_t p_scalar, const Vector3 &p_vec) {
+_FORCE_INLINE_ Vector3 operator*(int64_t p_scalar, const Vector3 &p_vec) {
return p_vec * p_scalar;
}
-Vector3 Vector3::operator*(const real_t p_scalar) const {
+Vector3 Vector3::operator*(real_t p_scalar) const {
return Vector3(x * p_scalar, y * p_scalar, z * p_scalar);
}
-Vector3 &Vector3::operator/=(const real_t p_scalar) {
+Vector3 &Vector3::operator/=(real_t p_scalar) {
x /= p_scalar;
y /= p_scalar;
z /= p_scalar;
return *this;
}
-Vector3 Vector3::operator/(const real_t p_scalar) const {
+Vector3 Vector3::operator/(real_t p_scalar) const {
return Vector3(x / p_scalar, y / p_scalar, z / p_scalar);
}
diff --git a/core/math/vector3i.h b/core/math/vector3i.h
index 5a5e9deda8..a9f298bff1 100644
--- a/core/math/vector3i.h
+++ b/core/math/vector3i.h
@@ -56,12 +56,12 @@ struct _NO_DISCARD_ Vector3i {
int32_t coord[3] = { 0 };
};
- _FORCE_INLINE_ const int32_t &operator[](const int p_axis) const {
+ _FORCE_INLINE_ const int32_t &operator[](int p_axis) const {
DEV_ASSERT((unsigned int)p_axis < 3);
return coord[p_axis];
}
- _FORCE_INLINE_ int32_t &operator[](const int p_axis) {
+ _FORCE_INLINE_ int32_t &operator[](int p_axis) {
DEV_ASSERT((unsigned int)p_axis < 3);
return coord[p_axis];
}
@@ -103,12 +103,12 @@ struct _NO_DISCARD_ Vector3i {
_FORCE_INLINE_ Vector3i &operator%=(const Vector3i &p_v);
_FORCE_INLINE_ Vector3i operator%(const Vector3i &p_v) const;
- _FORCE_INLINE_ Vector3i &operator*=(const int32_t p_scalar);
- _FORCE_INLINE_ Vector3i operator*(const int32_t p_scalar) const;
- _FORCE_INLINE_ Vector3i &operator/=(const int32_t p_scalar);
- _FORCE_INLINE_ Vector3i operator/(const int32_t p_scalar) const;
- _FORCE_INLINE_ Vector3i &operator%=(const int32_t p_scalar);
- _FORCE_INLINE_ Vector3i operator%(const int32_t p_scalar) const;
+ _FORCE_INLINE_ Vector3i &operator*=(int32_t p_scalar);
+ _FORCE_INLINE_ Vector3i operator*(int32_t p_scalar) const;
+ _FORCE_INLINE_ Vector3i &operator/=(int32_t p_scalar);
+ _FORCE_INLINE_ Vector3i operator/(int32_t p_scalar) const;
+ _FORCE_INLINE_ Vector3i &operator%=(int32_t p_scalar);
+ _FORCE_INLINE_ Vector3i operator%(int32_t p_scalar) const;
_FORCE_INLINE_ Vector3i operator-() const;
@@ -123,7 +123,7 @@ struct _NO_DISCARD_ Vector3i {
operator Vector3() const;
_FORCE_INLINE_ Vector3i() {}
- _FORCE_INLINE_ Vector3i(const int32_t p_x, const int32_t p_y, const int32_t p_z) {
+ _FORCE_INLINE_ Vector3i(int32_t p_x, int32_t p_y, int32_t p_z) {
x = p_x;
y = p_y;
z = p_z;
@@ -211,54 +211,54 @@ Vector3i Vector3i::operator%(const Vector3i &p_v) const {
return Vector3i(x % p_v.x, y % p_v.y, z % p_v.z);
}
-Vector3i &Vector3i::operator*=(const int32_t p_scalar) {
+Vector3i &Vector3i::operator*=(int32_t p_scalar) {
x *= p_scalar;
y *= p_scalar;
z *= p_scalar;
return *this;
}
-Vector3i Vector3i::operator*(const int32_t p_scalar) const {
+Vector3i Vector3i::operator*(int32_t p_scalar) const {
return Vector3i(x * p_scalar, y * p_scalar, z * p_scalar);
}
// Multiplication operators required to workaround issues with LLVM using implicit conversion.
-_FORCE_INLINE_ Vector3i operator*(const int32_t p_scalar, const Vector3i &p_vector) {
+_FORCE_INLINE_ Vector3i operator*(int32_t p_scalar, const Vector3i &p_vector) {
return p_vector * p_scalar;
}
-_FORCE_INLINE_ Vector3i operator*(const int64_t p_scalar, const Vector3i &p_vector) {
+_FORCE_INLINE_ Vector3i operator*(int64_t p_scalar, const Vector3i &p_vector) {
return p_vector * p_scalar;
}
-_FORCE_INLINE_ Vector3i operator*(const float p_scalar, const Vector3i &p_vector) {
+_FORCE_INLINE_ Vector3i operator*(float p_scalar, const Vector3i &p_vector) {
return p_vector * p_scalar;
}
-_FORCE_INLINE_ Vector3i operator*(const double p_scalar, const Vector3i &p_vector) {
+_FORCE_INLINE_ Vector3i operator*(double p_scalar, const Vector3i &p_vector) {
return p_vector * p_scalar;
}
-Vector3i &Vector3i::operator/=(const int32_t p_scalar) {
+Vector3i &Vector3i::operator/=(int32_t p_scalar) {
x /= p_scalar;
y /= p_scalar;
z /= p_scalar;
return *this;
}
-Vector3i Vector3i::operator/(const int32_t p_scalar) const {
+Vector3i Vector3i::operator/(int32_t p_scalar) const {
return Vector3i(x / p_scalar, y / p_scalar, z / p_scalar);
}
-Vector3i &Vector3i::operator%=(const int32_t p_scalar) {
+Vector3i &Vector3i::operator%=(int32_t p_scalar) {
x %= p_scalar;
y %= p_scalar;
z %= p_scalar;
return *this;
}
-Vector3i Vector3i::operator%(const int32_t p_scalar) const {
+Vector3i Vector3i::operator%(int32_t p_scalar) const {
return Vector3i(x % p_scalar, y % p_scalar, z % p_scalar);
}
diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp
index 5566b63714..e6f6dee42c 100644
--- a/core/math/vector4.cpp
+++ b/core/math/vector4.cpp
@@ -129,7 +129,7 @@ Vector4 Vector4::round() const {
return Vector4(Math::round(x), Math::round(y), Math::round(z), Math::round(w));
}
-Vector4 Vector4::lerp(const Vector4 &p_to, const real_t p_weight) const {
+Vector4 Vector4::lerp(const Vector4 &p_to, real_t p_weight) const {
Vector4 res = *this;
res.x = Math::lerp(res.x, p_to.x, p_weight);
res.y = Math::lerp(res.y, p_to.y, p_weight);
@@ -138,7 +138,7 @@ Vector4 Vector4::lerp(const Vector4 &p_to, const real_t p_weight) const {
return res;
}
-Vector4 Vector4::cubic_interpolate(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, const real_t p_weight) const {
+Vector4 Vector4::cubic_interpolate(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, real_t p_weight) const {
Vector4 res = *this;
res.x = Math::cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight);
res.y = Math::cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight);
@@ -147,7 +147,7 @@ Vector4 Vector4::cubic_interpolate(const Vector4 &p_b, const Vector4 &p_pre_a, c
return res;
}
-Vector4 Vector4::cubic_interpolate_in_time(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const {
+Vector4 Vector4::cubic_interpolate_in_time(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, real_t p_weight, real_t p_b_t, real_t p_pre_a_t, real_t p_post_b_t) const {
Vector4 res = *this;
res.x = Math::cubic_interpolate_in_time(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
res.y = Math::cubic_interpolate_in_time(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
@@ -156,7 +156,7 @@ Vector4 Vector4::cubic_interpolate_in_time(const Vector4 &p_b, const Vector4 &p_
return res;
}
-Vector4 Vector4::posmod(const real_t p_mod) const {
+Vector4 Vector4::posmod(real_t p_mod) const {
return Vector4(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod), Math::fposmod(z, p_mod), Math::fposmod(w, p_mod));
}
diff --git a/core/math/vector4.h b/core/math/vector4.h
index f16b040317..4dba3126cb 100644
--- a/core/math/vector4.h
+++ b/core/math/vector4.h
@@ -56,11 +56,11 @@ struct _NO_DISCARD_ Vector4 {
real_t components[4] = { 0, 0, 0, 0 };
};
- _FORCE_INLINE_ real_t &operator[](const int p_axis) {
+ _FORCE_INLINE_ real_t &operator[](int p_axis) {
DEV_ASSERT((unsigned int)p_axis < 4);
return components[p_axis];
}
- _FORCE_INLINE_ const real_t &operator[](const int p_axis) const {
+ _FORCE_INLINE_ const real_t &operator[](int p_axis) const {
DEV_ASSERT((unsigned int)p_axis < 4);
return components[p_axis];
}
@@ -94,11 +94,11 @@ struct _NO_DISCARD_ Vector4 {
Vector4 floor() const;
Vector4 ceil() const;
Vector4 round() const;
- Vector4 lerp(const Vector4 &p_to, const real_t p_weight) const;
- Vector4 cubic_interpolate(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, const real_t p_weight) const;
- Vector4 cubic_interpolate_in_time(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const;
+ Vector4 lerp(const Vector4 &p_to, real_t p_weight) const;
+ Vector4 cubic_interpolate(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, real_t p_weight) const;
+ Vector4 cubic_interpolate_in_time(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, real_t p_weight, real_t p_b_t, real_t p_pre_a_t, real_t p_post_b_t) const;
- Vector4 posmod(const real_t p_mod) const;
+ Vector4 posmod(real_t p_mod) const;
Vector4 posmodv(const Vector4 &p_modv) const;
void snap(const Vector4 &p_step);
Vector4 snapped(const Vector4 &p_step) const;
@@ -111,15 +111,15 @@ struct _NO_DISCARD_ Vector4 {
_FORCE_INLINE_ void operator-=(const Vector4 &p_vec4);
_FORCE_INLINE_ void operator*=(const Vector4 &p_vec4);
_FORCE_INLINE_ void operator/=(const Vector4 &p_vec4);
- _FORCE_INLINE_ void operator*=(const real_t &s);
- _FORCE_INLINE_ void operator/=(const real_t &s);
+ _FORCE_INLINE_ void operator*=(real_t p_s);
+ _FORCE_INLINE_ void operator/=(real_t p_s);
_FORCE_INLINE_ Vector4 operator+(const Vector4 &p_vec4) const;
_FORCE_INLINE_ Vector4 operator-(const Vector4 &p_vec4) const;
_FORCE_INLINE_ Vector4 operator*(const Vector4 &p_vec4) const;
_FORCE_INLINE_ Vector4 operator/(const Vector4 &p_vec4) const;
_FORCE_INLINE_ Vector4 operator-() const;
- _FORCE_INLINE_ Vector4 operator*(const real_t &s) const;
- _FORCE_INLINE_ Vector4 operator/(const real_t &s) const;
+ _FORCE_INLINE_ Vector4 operator*(real_t p_s) const;
+ _FORCE_INLINE_ Vector4 operator/(real_t p_s) const;
_FORCE_INLINE_ bool operator==(const Vector4 &p_vec4) const;
_FORCE_INLINE_ bool operator!=(const Vector4 &p_vec4) const;
@@ -189,15 +189,15 @@ void Vector4::operator/=(const Vector4 &p_vec4) {
z /= p_vec4.z;
w /= p_vec4.w;
}
-void Vector4::operator*=(const real_t &s) {
- x *= s;
- y *= s;
- z *= s;
- w *= s;
+void Vector4::operator*=(real_t p_s) {
+ x *= p_s;
+ y *= p_s;
+ z *= p_s;
+ w *= p_s;
}
-void Vector4::operator/=(const real_t &s) {
- *this *= 1.0f / s;
+void Vector4::operator/=(real_t p_s) {
+ *this *= 1.0f / p_s;
}
Vector4 Vector4::operator+(const Vector4 &p_vec4) const {
@@ -220,12 +220,12 @@ Vector4 Vector4::operator-() const {
return Vector4(-x, -y, -z, -w);
}
-Vector4 Vector4::operator*(const real_t &s) const {
- return Vector4(x * s, y * s, z * s, w * s);
+Vector4 Vector4::operator*(real_t p_s) const {
+ return Vector4(x * p_s, y * p_s, z * p_s, w * p_s);
}
-Vector4 Vector4::operator/(const real_t &s) const {
- return *this * (1.0f / s);
+Vector4 Vector4::operator/(real_t p_s) const {
+ return *this * (1.0f / p_s);
}
bool Vector4::operator==(const Vector4 &p_vec4) const {
@@ -288,19 +288,19 @@ bool Vector4::operator>=(const Vector4 &p_v) const {
return x > p_v.x;
}
-_FORCE_INLINE_ Vector4 operator*(const float p_scalar, const Vector4 &p_vec) {
+_FORCE_INLINE_ Vector4 operator*(float p_scalar, const Vector4 &p_vec) {
return p_vec * p_scalar;
}
-_FORCE_INLINE_ Vector4 operator*(const double p_scalar, const Vector4 &p_vec) {
+_FORCE_INLINE_ Vector4 operator*(double p_scalar, const Vector4 &p_vec) {
return p_vec * p_scalar;
}
-_FORCE_INLINE_ Vector4 operator*(const int32_t p_scalar, const Vector4 &p_vec) {
+_FORCE_INLINE_ Vector4 operator*(int32_t p_scalar, const Vector4 &p_vec) {
return p_vec * p_scalar;
}
-_FORCE_INLINE_ Vector4 operator*(const int64_t p_scalar, const Vector4 &p_vec) {
+_FORCE_INLINE_ Vector4 operator*(int64_t p_scalar, const Vector4 &p_vec) {
return p_vec * p_scalar;
}
diff --git a/core/math/vector4i.h b/core/math/vector4i.h
index 7d85d473d9..5a96d98d18 100644
--- a/core/math/vector4i.h
+++ b/core/math/vector4i.h
@@ -58,12 +58,12 @@ struct _NO_DISCARD_ Vector4i {
int32_t coord[4] = { 0 };
};
- _FORCE_INLINE_ const int32_t &operator[](const int p_axis) const {
+ _FORCE_INLINE_ const int32_t &operator[](int p_axis) const {
DEV_ASSERT((unsigned int)p_axis < 4);
return coord[p_axis];
}
- _FORCE_INLINE_ int32_t &operator[](const int p_axis) {
+ _FORCE_INLINE_ int32_t &operator[](int p_axis) {
DEV_ASSERT((unsigned int)p_axis < 4);
return coord[p_axis];
}
@@ -105,12 +105,12 @@ struct _NO_DISCARD_ Vector4i {
_FORCE_INLINE_ Vector4i &operator%=(const Vector4i &p_v);
_FORCE_INLINE_ Vector4i operator%(const Vector4i &p_v) const;
- _FORCE_INLINE_ Vector4i &operator*=(const int32_t p_scalar);
- _FORCE_INLINE_ Vector4i operator*(const int32_t p_scalar) const;
- _FORCE_INLINE_ Vector4i &operator/=(const int32_t p_scalar);
- _FORCE_INLINE_ Vector4i operator/(const int32_t p_scalar) const;
- _FORCE_INLINE_ Vector4i &operator%=(const int32_t p_scalar);
- _FORCE_INLINE_ Vector4i operator%(const int32_t p_scalar) const;
+ _FORCE_INLINE_ Vector4i &operator*=(int32_t p_scalar);
+ _FORCE_INLINE_ Vector4i operator*(int32_t p_scalar) const;
+ _FORCE_INLINE_ Vector4i &operator/=(int32_t p_scalar);
+ _FORCE_INLINE_ Vector4i operator/(int32_t p_scalar) const;
+ _FORCE_INLINE_ Vector4i &operator%=(int32_t p_scalar);
+ _FORCE_INLINE_ Vector4i operator%(int32_t p_scalar) const;
_FORCE_INLINE_ Vector4i operator-() const;
@@ -126,7 +126,7 @@ struct _NO_DISCARD_ Vector4i {
_FORCE_INLINE_ Vector4i() {}
Vector4i(const Vector4 &p_vec4);
- _FORCE_INLINE_ Vector4i(const int32_t p_x, const int32_t p_y, const int32_t p_z, const int32_t p_w) {
+ _FORCE_INLINE_ Vector4i(int32_t p_x, int32_t p_y, int32_t p_z, int32_t p_w) {
x = p_x;
y = p_y;
z = p_z;
@@ -220,7 +220,7 @@ Vector4i Vector4i::operator%(const Vector4i &p_v) const {
return Vector4i(x % p_v.x, y % p_v.y, z % p_v.z, w % p_v.w);
}
-Vector4i &Vector4i::operator*=(const int32_t p_scalar) {
+Vector4i &Vector4i::operator*=(int32_t p_scalar) {
x *= p_scalar;
y *= p_scalar;
z *= p_scalar;
@@ -228,29 +228,29 @@ Vector4i &Vector4i::operator*=(const int32_t p_scalar) {
return *this;
}
-Vector4i Vector4i::operator*(const int32_t p_scalar) const {
+Vector4i Vector4i::operator*(int32_t p_scalar) const {
return Vector4i(x * p_scalar, y * p_scalar, z * p_scalar, w * p_scalar);
}
// Multiplication operators required to workaround issues with LLVM using implicit conversion.
-_FORCE_INLINE_ Vector4i operator*(const int32_t p_scalar, const Vector4i &p_vector) {
+_FORCE_INLINE_ Vector4i operator*(int32_t p_scalar, const Vector4i &p_vector) {
return p_vector * p_scalar;
}
-_FORCE_INLINE_ Vector4i operator*(const int64_t p_scalar, const Vector4i &p_vector) {
+_FORCE_INLINE_ Vector4i operator*(int64_t p_scalar, const Vector4i &p_vector) {
return p_vector * p_scalar;
}
-_FORCE_INLINE_ Vector4i operator*(const float p_scalar, const Vector4i &p_vector) {
+_FORCE_INLINE_ Vector4i operator*(float p_scalar, const Vector4i &p_vector) {
return p_vector * p_scalar;
}
-_FORCE_INLINE_ Vector4i operator*(const double p_scalar, const Vector4i &p_vector) {
+_FORCE_INLINE_ Vector4i operator*(double p_scalar, const Vector4i &p_vector) {
return p_vector * p_scalar;
}
-Vector4i &Vector4i::operator/=(const int32_t p_scalar) {
+Vector4i &Vector4i::operator/=(int32_t p_scalar) {
x /= p_scalar;
y /= p_scalar;
z /= p_scalar;
@@ -258,11 +258,11 @@ Vector4i &Vector4i::operator/=(const int32_t p_scalar) {
return *this;
}
-Vector4i Vector4i::operator/(const int32_t p_scalar) const {
+Vector4i Vector4i::operator/(int32_t p_scalar) const {
return Vector4i(x / p_scalar, y / p_scalar, z / p_scalar, w / p_scalar);
}
-Vector4i &Vector4i::operator%=(const int32_t p_scalar) {
+Vector4i &Vector4i::operator%=(int32_t p_scalar) {
x %= p_scalar;
y %= p_scalar;
z %= p_scalar;
@@ -270,7 +270,7 @@ Vector4i &Vector4i::operator%=(const int32_t p_scalar) {
return *this;
}
-Vector4i Vector4i::operator%(const int32_t p_scalar) const {
+Vector4i Vector4i::operator%(int32_t p_scalar) const {
return Vector4i(x % p_scalar, y % p_scalar, z % p_scalar, w % p_scalar);
}
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index f2a9a68d08..231a8e4d68 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -70,6 +70,139 @@ HashMap<StringName, ClassDB::ClassInfo> ClassDB::classes;
HashMap<StringName, StringName> ClassDB::resource_base_extensions;
HashMap<StringName, StringName> ClassDB::compat_classes;
+#ifdef TOOLS_ENABLED
+HashMap<StringName, ObjectGDExtension> ClassDB::placeholder_extensions;
+
+class PlaceholderExtensionInstance {
+ StringName class_name;
+ HashMap<StringName, Variant> properties;
+
+public:
+ PlaceholderExtensionInstance(const StringName &p_class_name) {
+ class_name = p_class_name;
+ }
+
+ ~PlaceholderExtensionInstance() {}
+
+ void set(const StringName &p_name, const Variant &p_value) {
+ bool is_default_valid = false;
+ Variant default_value = ClassDB::class_get_default_property_value(class_name, p_name, &is_default_valid);
+
+ // If there's a default value, then we know it's a valid property.
+ if (is_default_valid) {
+ properties[p_name] = p_value;
+ }
+ }
+
+ Variant get(const StringName &p_name) {
+ const Variant *value = properties.getptr(p_name);
+ Variant ret;
+
+ if (value) {
+ ret = *value;
+ } else {
+ bool is_default_valid = false;
+ Variant default_value = ClassDB::class_get_default_property_value(class_name, p_name, &is_default_valid);
+ if (is_default_valid) {
+ ret = default_value;
+ }
+ }
+
+ return ret;
+ }
+
+ static GDExtensionBool placeholder_instance_set(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value) {
+ PlaceholderExtensionInstance *self = (PlaceholderExtensionInstance *)p_instance;
+ const StringName &name = *(StringName *)p_name;
+ const Variant &value = *(const Variant *)p_value;
+
+ self->set(name, value);
+
+ // We have to return true so Godot doesn't try to call the real setter function.
+ return true;
+ }
+
+ static GDExtensionBool placeholder_instance_get(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) {
+ PlaceholderExtensionInstance *self = (PlaceholderExtensionInstance *)p_instance;
+ const StringName &name = *(StringName *)p_name;
+ Variant *value = (Variant *)r_ret;
+
+ *value = self->get(name);
+
+ // We have to return true so Godot doesn't try to call the real getter function.
+ return true;
+ }
+
+ static const GDExtensionPropertyInfo *placeholder_instance_get_property_list(GDExtensionClassInstancePtr p_instance, uint32_t *r_count) {
+ *r_count = 0;
+ return nullptr;
+ }
+
+ static void placeholder_instance_free_property_list(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) {
+ }
+
+ static GDExtensionBool placeholder_instance_property_can_revert(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name) {
+ return false;
+ }
+
+ static GDExtensionBool placeholder_instance_property_get_revert(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) {
+ return false;
+ }
+
+ static GDExtensionBool placeholder_instance_validate_property(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property) {
+ return false;
+ }
+
+ static void placeholder_instance_notification(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) {
+ }
+
+ static void placeholder_instance_to_string(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr p_out) {
+ *r_is_valid = true;
+ }
+
+ static void placeholder_instance_reference(GDExtensionClassInstancePtr p_instance) {
+ }
+
+ static void placeholder_instance_unreference(GDExtensionClassInstancePtr p_instance) {
+ }
+
+ static uint64_t placeholder_instance_get_rid(GDExtensionClassInstancePtr p_instance) {
+ return 0;
+ }
+
+ static GDExtensionObjectPtr placeholder_class_create_instance(void *p_class_userdata) {
+ ClassDB::ClassInfo *ti = (ClassDB::ClassInfo *)p_class_userdata;
+
+ // Find the closest native parent.
+ ClassDB::ClassInfo *native_parent = ti->inherits_ptr;
+ while (native_parent->gdextension) {
+ native_parent = native_parent->inherits_ptr;
+ }
+ ERR_FAIL_NULL_V(native_parent->creation_func, nullptr);
+
+ // Construct a placeholder.
+ Object *obj = native_parent->creation_func();
+ obj->_extension = ClassDB::get_placeholder_extension(ti->name);
+ obj->_extension_instance = memnew(PlaceholderExtensionInstance(ti->name));
+ return obj;
+ }
+
+ static GDExtensionObjectPtr placeholder_class_recreate_instance(void *p_class_userdata, GDExtensionObjectPtr p_object) {
+ ClassDB::ClassInfo *ti = (ClassDB::ClassInfo *)p_class_userdata;
+ return memnew(PlaceholderExtensionInstance(ti->name));
+ }
+
+ static void placeholder_class_free_instance(void *p_class_userdata, GDExtensionClassInstancePtr p_instance) {
+ PlaceholderExtensionInstance *instance = (PlaceholderExtensionInstance *)p_instance;
+ memdelete(instance);
+ }
+
+ static GDExtensionClassCallVirtual placeholder_class_get_virtual(void *p_class_userdata, GDExtensionConstStringNamePtr p_name) {
+ return nullptr;
+ }
+};
+#endif
+
bool ClassDB::_is_parent_class(const StringName &p_class, const StringName &p_inherits) {
if (!classes.has(p_class)) {
return false;
@@ -346,7 +479,7 @@ StringName ClassDB::get_compatibility_class(const StringName &p_class) {
return StringName();
}
-Object *ClassDB::instantiate(const StringName &p_class) {
+Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class) {
ClassInfo *ti;
{
OBJTYPE_RLOCK;
@@ -367,18 +500,126 @@ Object *ClassDB::instantiate(const StringName &p_class) {
}
#endif
if (ti->gdextension && ti->gdextension->create_instance) {
- Object *obj = (Object *)ti->gdextension->create_instance(ti->gdextension->class_userdata);
+ ObjectGDExtension *extension = ti->gdextension;
#ifdef TOOLS_ENABLED
- if (ti->gdextension->track_instance) {
- ti->gdextension->track_instance(ti->gdextension->tracking_userdata, obj);
+ if (!p_require_real_class && ti->is_runtime && Engine::get_singleton()->is_editor_hint()) {
+ extension = get_placeholder_extension(ti->name);
+ }
+#endif
+ Object *obj = (Object *)extension->create_instance(extension->class_userdata);
+
+#ifdef TOOLS_ENABLED
+ if (extension->track_instance) {
+ extension->track_instance(extension->tracking_userdata, obj);
}
#endif
return obj;
} else {
+#ifdef TOOLS_ENABLED
+ if (!p_require_real_class && ti->is_runtime && Engine::get_singleton()->is_editor_hint()) {
+ if (!ti->inherits_ptr || !ti->inherits_ptr->creation_func) {
+ ERR_PRINT_ONCE(vformat("Cannot make a placeholder instance of runtime class %s because its parent cannot be constructed.", ti->name));
+ } else {
+ ObjectGDExtension *extension = get_placeholder_extension(ti->name);
+ return (Object *)extension->create_instance(extension->class_userdata);
+ }
+ }
+#endif
+
return ti->creation_func();
}
}
+Object *ClassDB::instantiate(const StringName &p_class) {
+ return _instantiate_internal(p_class);
+}
+
+Object *ClassDB::instantiate_no_placeholders(const StringName &p_class) {
+ return _instantiate_internal(p_class, true);
+}
+
+#ifdef TOOLS_ENABLED
+ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class) {
+ ObjectGDExtension *placeholder_extension = placeholder_extensions.getptr(p_class);
+ if (placeholder_extension) {
+ return placeholder_extension;
+ }
+
+ ClassInfo *ti;
+ {
+ OBJTYPE_RLOCK;
+ ti = classes.getptr(p_class);
+ if (!ti || ti->disabled || !ti->creation_func || (ti->gdextension && !ti->gdextension->create_instance)) {
+ if (compat_classes.has(p_class)) {
+ ti = classes.getptr(compat_classes[p_class]);
+ }
+ }
+ ERR_FAIL_NULL_V_MSG(ti, nullptr, "Cannot get class '" + String(p_class) + "'.");
+ ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, "Class '" + String(p_class) + "' is disabled.");
+ }
+
+ // Make a "fake" extension to act as a placeholder.
+ placeholder_extensions[p_class] = ObjectGDExtension();
+ placeholder_extension = placeholder_extensions.getptr(p_class);
+
+ placeholder_extension->is_runtime = true;
+ placeholder_extension->is_placeholder = true;
+
+ if (ti->gdextension) {
+ placeholder_extension->library = ti->gdextension->library;
+ placeholder_extension->parent = ti->gdextension->parent;
+ placeholder_extension->children = ti->gdextension->children;
+ placeholder_extension->parent_class_name = ti->gdextension->parent_class_name;
+ placeholder_extension->class_name = ti->gdextension->class_name;
+ placeholder_extension->editor_class = ti->gdextension->editor_class;
+ placeholder_extension->reloadable = ti->gdextension->reloadable;
+ placeholder_extension->is_virtual = ti->gdextension->is_virtual;
+ placeholder_extension->is_abstract = ti->gdextension->is_abstract;
+ placeholder_extension->is_exposed = ti->gdextension->is_exposed;
+
+ placeholder_extension->tracking_userdata = ti->gdextension->tracking_userdata;
+ placeholder_extension->track_instance = ti->gdextension->track_instance;
+ placeholder_extension->untrack_instance = ti->gdextension->untrack_instance;
+ } else {
+ placeholder_extension->library = nullptr;
+ placeholder_extension->parent = nullptr;
+ placeholder_extension->parent_class_name = ti->inherits;
+ placeholder_extension->class_name = ti->name;
+ placeholder_extension->editor_class = ti->api == API_EDITOR;
+ placeholder_extension->reloadable = false;
+ placeholder_extension->is_virtual = ti->is_virtual;
+ placeholder_extension->is_abstract = false;
+ placeholder_extension->is_exposed = ti->exposed;
+ }
+
+ placeholder_extension->set = &PlaceholderExtensionInstance::placeholder_instance_set;
+ placeholder_extension->get = &PlaceholderExtensionInstance::placeholder_instance_get;
+ placeholder_extension->get_property_list = &PlaceholderExtensionInstance::placeholder_instance_get_property_list;
+ placeholder_extension->free_property_list = &PlaceholderExtensionInstance::placeholder_instance_free_property_list;
+ placeholder_extension->property_can_revert = &PlaceholderExtensionInstance::placeholder_instance_property_can_revert;
+ placeholder_extension->property_get_revert = &PlaceholderExtensionInstance::placeholder_instance_property_get_revert;
+ placeholder_extension->validate_property = &PlaceholderExtensionInstance::placeholder_instance_validate_property;
+#ifndef DISABLE_DEPRECATED
+ placeholder_extension->notification = nullptr;
+#endif // DISABLE_DEPRECATED
+ placeholder_extension->notification2 = &PlaceholderExtensionInstance::placeholder_instance_notification;
+ placeholder_extension->to_string = &PlaceholderExtensionInstance::placeholder_instance_to_string;
+ placeholder_extension->reference = &PlaceholderExtensionInstance::placeholder_instance_reference;
+ placeholder_extension->unreference = &PlaceholderExtensionInstance::placeholder_instance_unreference;
+ placeholder_extension->get_rid = &PlaceholderExtensionInstance::placeholder_instance_get_rid;
+
+ placeholder_extension->class_userdata = ti;
+ placeholder_extension->create_instance = &PlaceholderExtensionInstance::placeholder_class_create_instance;
+ placeholder_extension->free_instance = &PlaceholderExtensionInstance::placeholder_class_free_instance;
+ placeholder_extension->get_virtual = &PlaceholderExtensionInstance::placeholder_class_get_virtual;
+ placeholder_extension->get_virtual_call_data = nullptr;
+ placeholder_extension->call_virtual_with_data = nullptr;
+ placeholder_extension->recreate_instance = &PlaceholderExtensionInstance::placeholder_class_recreate_instance;
+
+ return placeholder_extension;
+}
+#endif
+
void ClassDB::set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance) {
ERR_FAIL_NULL(p_object);
ClassInfo *ti;
@@ -1716,7 +1957,7 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con
c = Engine::get_singleton()->get_singleton_object(p_class);
cleanup_c = false;
} else if (ClassDB::can_instantiate(p_class) && !ClassDB::is_virtual(p_class)) { // Keep this condition in sync with doc_tools.cpp get_documentation_default_value.
- c = ClassDB::instantiate(p_class);
+ c = ClassDB::instantiate_no_placeholders(p_class);
cleanup_c = true;
}
@@ -1813,6 +2054,9 @@ void ClassDB::register_extension_class(ObjectGDExtension *p_extension) {
}
}
c.reloadable = p_extension->reloadable;
+#ifdef TOOLS_ENABLED
+ c.is_runtime = p_extension->is_runtime;
+#endif
classes[p_extension->class_name] = c;
}
@@ -1826,6 +2070,11 @@ void ClassDB::unregister_extension_class(const StringName &p_class, bool p_free_
}
}
classes.erase(p_class);
+ default_values_cached.erase(p_class);
+ default_values.erase(p_class);
+#ifdef TOOLS_ENABLED
+ placeholder_extensions.erase(p_class);
+#endif
}
HashMap<StringName, ClassDB::NativeStruct> ClassDB::native_structs;
diff --git a/core/object/class_db.h b/core/object/class_db.h
index c910b30d11..7f117b4a9b 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -133,6 +133,7 @@ public:
bool exposed = false;
bool reloadable = false;
bool is_virtual = false;
+ bool is_runtime = false;
Object *(*creation_func)() = nullptr;
ClassInfo() {}
@@ -149,6 +150,10 @@ public:
static HashMap<StringName, StringName> resource_base_extensions;
static HashMap<StringName, StringName> compat_classes;
+#ifdef TOOLS_ENABLED
+ static HashMap<StringName, ObjectGDExtension> placeholder_extensions;
+#endif
+
#ifdef DEBUG_METHODS_ENABLED
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, bool p_compatibility, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount);
#else
@@ -178,6 +183,8 @@ private:
static MethodBind *_bind_vararg_method(MethodBind *p_bind, const StringName &p_name, const Vector<Variant> &p_default_args, bool p_compatibility);
static void _bind_method_custom(const StringName &p_class, MethodBind *p_method, bool p_compatibility);
+ static Object *_instantiate_internal(const StringName &p_class, bool p_require_real_class = false);
+
public:
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
template <class T>
@@ -228,6 +235,23 @@ public:
T::register_custom_data_to_otdb();
}
+ template <class T>
+ static void register_runtime_class() {
+ GLOBAL_LOCK_FUNCTION;
+ static_assert(types_are_same_v<typename T::self_type, T>, "Class not declared properly, please use GDCLASS.");
+ T::initialize_class();
+ ClassInfo *t = classes.getptr(T::get_class_static());
+ ERR_FAIL_NULL(t);
+ ERR_FAIL_COND_MSG(t->inherits_ptr && !t->inherits_ptr->creation_func, vformat("Cannot register runtime class '%s' that descends from an abstract parent class.", T::get_class_static()));
+ t->creation_func = &creator<T>;
+ t->exposed = true;
+ t->is_virtual = false;
+ t->is_runtime = true;
+ t->class_ptr = T::get_class_ptr_static();
+ t->api = current_api;
+ T::register_custom_data_to_otdb();
+ }
+
static void register_extension_class(ObjectGDExtension *p_extension);
static void unregister_extension_class(const StringName &p_class, bool p_free_method_binds = true);
@@ -253,6 +277,7 @@ public:
static void get_class_list(List<StringName> *p_classes);
#ifdef TOOLS_ENABLED
static void get_extensions_class_list(List<StringName> *p_classes);
+ static ObjectGDExtension *get_placeholder_extension(const StringName &p_class);
#endif
static void get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
static void get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
@@ -264,6 +289,7 @@ public:
static bool can_instantiate(const StringName &p_class);
static bool is_virtual(const StringName &p_class);
static Object *instantiate(const StringName &p_class);
+ static Object *instantiate_no_placeholders(const StringName &p_class);
static void set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance);
static APIType get_api_type(const StringName &p_class);
@@ -510,6 +536,11 @@ _FORCE_INLINE_ Vector<Error> errarray(P... p_args) {
::ClassDB::register_internal_class<m_class>(); \
}
+#define GDREGISTER_RUNTIME_CLASS(m_class) \
+ if (m_class::_class_is_enabled) { \
+ ::ClassDB::register_runtime_class<m_class>(); \
+ }
+
#define GDREGISTER_NATIVE_STRUCT(m_class, m_code) ClassDB::register_native_struct(#m_class, m_code, sizeof(m_class))
#include "core/disabled_classes.gen.h"
diff --git a/core/object/method_bind.h b/core/object/method_bind.h
index d67fd003c8..88b867a1ca 100644
--- a/core/object/method_bind.h
+++ b/core/object/method_bind.h
@@ -225,6 +225,9 @@ class MethodBindVarArgT : public MethodBindVarArgBase<MethodBindVarArgT<T>, T, v
public:
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == MethodBind::get_instance_class(), Variant(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
(static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>::method)(p_args, p_arg_count, r_error);
return {};
}
@@ -261,6 +264,9 @@ public:
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == MethodBind::get_instance_class(), Variant(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
return (static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>::method)(p_args, p_arg_count, r_error);
}
@@ -329,6 +335,9 @@ public:
#endif
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), Variant(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_variant_args_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
#else
@@ -338,6 +347,9 @@ public:
}
virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_validated_object_instance_args(static_cast<T *>(p_object), method, p_args);
#else
@@ -346,6 +358,9 @@ public:
}
virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_ptr_args<T, P...>(static_cast<T *>(p_object), method, p_args);
#else
@@ -404,6 +419,9 @@ public:
#endif
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), Variant(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_variant_argsc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
#else
@@ -413,6 +431,9 @@ public:
}
virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_validated_object_instance_argsc(static_cast<T *>(p_object), method, p_args);
#else
@@ -421,6 +442,9 @@ public:
}
virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_ptr_argsc<T, P...>(static_cast<T *>(p_object), method, p_args);
#else
@@ -490,6 +514,9 @@ public:
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
Variant ret;
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), ret, vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_variant_args_ret_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
#else
@@ -499,6 +526,9 @@ public:
}
virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_validated_object_instance_args_ret(static_cast<T *>(p_object), method, p_args, r_ret);
#else
@@ -507,6 +537,9 @@ public:
}
virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_ptr_args_ret<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
#else
@@ -577,6 +610,9 @@ public:
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
Variant ret;
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), ret, vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_variant_args_retc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
#else
@@ -586,6 +622,9 @@ public:
}
virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_validated_object_instance_args_retc(static_cast<T *>(p_object), method, p_args, r_ret);
#else
@@ -594,6 +633,9 @@ public:
}
virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
+#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
+#endif
#ifdef TYPED_METHOD_BIND
call_with_ptr_args_retc<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
#else
diff --git a/core/object/object.compat.inc b/core/object/object.compat.inc
new file mode 100644
index 0000000000..bf1e99fc9b
--- /dev/null
+++ b/core/object/object.compat.inc
@@ -0,0 +1,40 @@
+/**************************************************************************/
+/* object.compat.inc */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef DISABLE_DEPRECATED
+
+#include "core/object/class_db.h"
+
+void Object::_bind_compatibility_methods() {
+ ClassDB::bind_compatibility_method(D_METHOD("tr", "message", "context"), &Object::tr, DEFVAL(""));
+ ClassDB::bind_compatibility_method(D_METHOD("tr_n", "message", "plural_message", "n", "context"), &Object::tr_n, DEFVAL(""));
+}
+
+#endif
diff --git a/core/object/object.cpp b/core/object/object.cpp
index cc33d0ab8a..b34182cdaa 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -29,6 +29,7 @@
/**************************************************************************/
#include "object.h"
+#include "object.compat.inc"
#include "core/core_string_names.h"
#include "core/extension/gdextension_manager.h"
@@ -492,14 +493,22 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
ClassDB::get_property_list(current_extension->class_name, p_list, true, this);
if (current_extension->get_property_list) {
- uint32_t pcount;
- const GDExtensionPropertyInfo *pinfo = current_extension->get_property_list(_extension_instance, &pcount);
- for (uint32_t i = 0; i < pcount; i++) {
- p_list->push_back(PropertyInfo(pinfo[i]));
- }
- if (current_extension->free_property_list) {
- current_extension->free_property_list(_extension_instance, pinfo);
+#ifdef TOOLS_ENABLED
+ // If this is a placeholder, we can't call into the GDExtension on the parent class,
+ // because we don't have a real instance of the class to give it.
+ if (likely(!_extension->is_placeholder)) {
+#endif
+ uint32_t pcount;
+ const GDExtensionPropertyInfo *pinfo = current_extension->get_property_list(_extension_instance, &pcount);
+ for (uint32_t i = 0; i < pcount; i++) {
+ p_list->push_back(PropertyInfo(pinfo[i]));
+ }
+ if (current_extension->free_property_list) {
+ current_extension->free_property_list(_extension_instance, pinfo);
+ }
+#ifdef TOOLS_ENABLED
}
+#endif
}
current_extension = current_extension->parent;
@@ -1464,6 +1473,7 @@ void Object::initialize_class() {
}
ClassDB::_add_class<Object>();
_bind_methods();
+ _bind_compatibility_methods();
initialized = true;
}
@@ -1473,10 +1483,15 @@ String Object::tr(const StringName &p_message, const StringName &p_context) cons
}
if (Engine::get_singleton()->is_editor_hint()) {
+ String tr_msg = TranslationServer::get_singleton()->extractable_translate(p_message, p_context);
+ if (!tr_msg.is_empty()) {
+ return tr_msg;
+ }
+
return TranslationServer::get_singleton()->tool_translate(p_message, p_context);
- } else {
- return TranslationServer::get_singleton()->translate(p_message, p_context);
}
+
+ return TranslationServer::get_singleton()->translate(p_message, p_context);
}
String Object::tr_n(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
@@ -1489,10 +1504,15 @@ String Object::tr_n(const StringName &p_message, const StringName &p_message_plu
}
if (Engine::get_singleton()->is_editor_hint()) {
+ String tr_msg = TranslationServer::get_singleton()->extractable_translate_plural(p_message, p_message_plural, p_n, p_context);
+ if (!tr_msg.is_empty()) {
+ return tr_msg;
+ }
+
return TranslationServer::get_singleton()->tool_translate_plural(p_message, p_message_plural, p_n, p_context);
- } else {
- return TranslationServer::get_singleton()->translate_plural(p_message, p_message_plural, p_n, p_context);
}
+
+ return TranslationServer::get_singleton()->translate_plural(p_message, p_message_plural, p_n, p_context);
}
void Object::_clear_internal_resource_paths(const Variant &p_var) {
@@ -1639,8 +1659,8 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_message_translation", "enable"), &Object::set_message_translation);
ClassDB::bind_method(D_METHOD("can_translate_messages"), &Object::can_translate_messages);
- ClassDB::bind_method(D_METHOD("tr", "message", "context"), &Object::tr, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("tr_n", "message", "plural_message", "n", "context"), &Object::tr_n, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("tr", "message", "context"), &Object::tr, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("tr_n", "message", "plural_message", "n", "context"), &Object::tr_n, DEFVAL(StringName()));
ClassDB::bind_method(D_METHOD("is_queued_for_deletion"), &Object::is_queued_for_deletion);
ClassDB::bind_method(D_METHOD("cancel_free"), &Object::cancel_free);
@@ -1792,6 +1812,16 @@ uint32_t Object::get_edited_version() const {
#endif
StringName Object::get_class_name_for_extension(const GDExtension *p_library) const {
+#ifdef TOOLS_ENABLED
+ // If this is the library this extension comes from and it's a placeholder, we
+ // have to return the closest native parent's class name, so that it doesn't try to
+ // use this like the real object.
+ if (unlikely(_extension && _extension->library == p_library && _extension->is_placeholder)) {
+ const StringName *class_name = _get_class_namev();
+ return *class_name;
+ }
+#endif
+
// Only return the class name per the extension if it matches the given p_library.
if (_extension && _extension->library == p_library) {
return _extension->class_name;
@@ -1919,13 +1949,15 @@ void Object::clear_internal_extension() {
// Clear the instance bindings.
_instance_binding_mutex.lock();
- if (_instance_bindings[0].free_callback) {
- _instance_bindings[0].free_callback(_instance_bindings[0].token, this, _instance_bindings[0].binding);
+ if (_instance_bindings) {
+ if (_instance_bindings[0].free_callback) {
+ _instance_bindings[0].free_callback(_instance_bindings[0].token, this, _instance_bindings[0].binding);
+ }
+ _instance_bindings[0].binding = nullptr;
+ _instance_bindings[0].token = nullptr;
+ _instance_bindings[0].free_callback = nullptr;
+ _instance_bindings[0].reference_callback = nullptr;
}
- _instance_bindings[0].binding = nullptr;
- _instance_bindings[0].token = nullptr;
- _instance_bindings[0].free_callback = nullptr;
- _instance_bindings[0].reference_callback = nullptr;
_instance_binding_mutex.unlock();
// Clear the virtual methods.
@@ -2064,15 +2096,17 @@ void ObjectDB::debug_objects(DebugFunc p_func) {
spin_lock.unlock();
}
+#ifdef TOOLS_ENABLED
void Object::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+ const String pf = p_function;
if (p_idx == 0) {
- if (p_function == "connect" || p_function == "is_connected" || p_function == "disconnect" || p_function == "emit_signal" || p_function == "has_signal") {
+ if (pf == "connect" || pf == "is_connected" || pf == "disconnect" || pf == "emit_signal" || pf == "has_signal") {
List<MethodInfo> signals;
get_signal_list(&signals);
for (const MethodInfo &E : signals) {
r_options->push_back(E.name.quote());
}
- } else if (p_function == "call" || p_function == "call_deferred" || p_function == "callv" || p_function == "has_method") {
+ } else if (pf == "call" || pf == "call_deferred" || pf == "callv" || pf == "has_method") {
List<MethodInfo> methods;
get_method_list(&methods);
for (const MethodInfo &E : methods) {
@@ -2081,7 +2115,7 @@ void Object::get_argument_options(const StringName &p_function, int p_idx, List<
}
r_options->push_back(E.name.quote());
}
- } else if (p_function == "set" || p_function == "set_deferred" || p_function == "get") {
+ } else if (pf == "set" || pf == "set_deferred" || pf == "get") {
List<PropertyInfo> properties;
get_property_list(&properties);
for (const PropertyInfo &E : properties) {
@@ -2089,13 +2123,13 @@ void Object::get_argument_options(const StringName &p_function, int p_idx, List<
r_options->push_back(E.name.quote());
}
}
- } else if (p_function == "set_meta" || p_function == "get_meta" || p_function == "has_meta" || p_function == "remove_meta") {
+ } else if (pf == "set_meta" || pf == "get_meta" || pf == "has_meta" || pf == "remove_meta") {
for (const KeyValue<StringName, Variant> &K : metadata) {
r_options->push_back(String(K.key).quote());
}
}
} else if (p_idx == 2) {
- if (p_function == "connect") {
+ if (pf == "connect") {
// Ideally, the constants should be inferred by the parameter.
// But a parameter's PropertyInfo does not store the enum they come from, so this will do for now.
List<StringName> constants;
@@ -2106,6 +2140,7 @@ void Object::get_argument_options(const StringName &p_function, int p_idx, List<
}
}
}
+#endif
SpinLock ObjectDB::spin_lock;
uint32_t ObjectDB::slot_count = 0;
diff --git a/core/object/object.h b/core/object/object.h
index 27f28b4aae..f97691841f 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -317,6 +317,10 @@ struct ObjectGDExtension {
bool is_virtual = false;
bool is_abstract = false;
bool is_exposed = true;
+#ifdef TOOLS_ENABLED
+ bool is_runtime = false;
+ bool is_placeholder = false;
+#endif
GDExtensionClassSet set;
GDExtensionClassGet get;
GDExtensionClassGetPropertyList get_property_list;
@@ -354,8 +358,8 @@ struct ObjectGDExtension {
#ifdef TOOLS_ENABLED
void *tracking_userdata = nullptr;
- void (*track_instance)(void *p_userdata, void *p_instance);
- void (*untrack_instance)(void *p_userdata, void *p_instance);
+ void (*track_instance)(void *p_userdata, void *p_instance) = nullptr;
+ void (*untrack_instance)(void *p_userdata, void *p_instance) = nullptr;
#endif
};
@@ -698,7 +702,11 @@ protected:
virtual void _notificationv(int p_notification, bool p_reversed) {}
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ static void _bind_compatibility_methods();
+#else
static void _bind_compatibility_methods() {}
+#endif
bool _set(const StringName &p_name, const Variant &p_property) { return false; };
bool _get(const StringName &p_name, Variant &r_property) const { return false; };
void _get_property_list(List<PropertyInfo> *p_list) const {};
@@ -755,6 +763,7 @@ protected:
void _clear_internal_resource_paths(const Variant &p_var);
friend class ClassDB;
+ friend class PlaceholderExtensionInstance;
bool _disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force = false);
@@ -947,8 +956,6 @@ public:
Variant::Type get_static_property_type(const StringName &p_property, bool *r_valid = nullptr) const;
Variant::Type get_static_property_type_indexed(const Vector<StringName> &p_path, bool *r_valid = nullptr) const;
- virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
-
// Translate message (internationalization).
String tr(const StringName &p_message, const StringName &p_context = "") const;
String tr_n(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
@@ -960,6 +967,7 @@ public:
_FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; }
#ifdef TOOLS_ENABLED
+ virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
void editor_set_section_unfold(const String &p_section, bool p_unfolded);
bool editor_is_section_unfolded(const String &p_section);
const HashSet<String> &editor_get_section_folding() const { return editor_section_folding; }
@@ -977,6 +985,7 @@ public:
#ifdef TOOLS_ENABLED
void clear_internal_extension();
void reset_internal_extension(ObjectGDExtension *p_extension);
+ bool is_extension_placeholder() const { return _extension && _extension->is_placeholder; }
#endif
void clear_internal_resource_paths();
diff --git a/core/object/script_instance.h b/core/object/script_instance.h
index df978a25ea..45d51534fc 100644
--- a/core/object/script_instance.h
+++ b/core/object/script_instance.h
@@ -76,7 +76,7 @@ public:
}
//this is used by script languages that keep a reference counter of their own
- //you can make make Ref<> not die when it reaches zero, so deleting the reference
+ //you can make Ref<> not die when it reaches zero, so deleting the reference
//depends entirely from the script
virtual void refcount_incremented() {}
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp
index 3b9b1f9094..d358a8d2a0 100644
--- a/core/object/script_language.cpp
+++ b/core/object/script_language.cpp
@@ -535,6 +535,13 @@ TypedArray<int> ScriptLanguage::CodeCompletionOption::get_option_cached_characte
return charac;
}
+void ScriptLanguage::_bind_methods() {
+ BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_AUTO);
+ BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_PASCAL_CASE);
+ BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_SNAKE_CASE);
+ BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_KEBAB_CASE);
+}
+
bool PlaceHolderScriptInstance::set(const StringName &p_name, const Variant &p_value) {
if (script->is_placeholder_fallback_enabled()) {
return false;
diff --git a/core/object/script_language.h b/core/object/script_language.h
index 4217bc9f96..95e9d2b4af 100644
--- a/core/object/script_language.h
+++ b/core/object/script_language.h
@@ -193,6 +193,10 @@ public:
class ScriptLanguage : public Object {
GDCLASS(ScriptLanguage, Object)
+
+protected:
+ static void _bind_methods();
+
public:
virtual String get_name() const = 0;
@@ -224,6 +228,13 @@ public:
TEMPLATE_PROJECT
};
+ enum ScriptNameCasing {
+ SCRIPT_NAME_CASING_AUTO,
+ SCRIPT_NAME_CASING_PASCAL_CASE,
+ SCRIPT_NAME_CASING_SNAKE_CASE,
+ SCRIPT_NAME_CASING_KEBAB_CASE,
+ };
+
struct ScriptTemplate {
String inherit = "Object";
String name;
@@ -260,6 +271,7 @@ public:
virtual bool can_make_function() const { return true; }
virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; }
virtual bool overrides_external_editor() { return false; }
+ virtual ScriptNameCasing preferred_file_name_casing() const { return SCRIPT_NAME_CASING_SNAKE_CASE; }
// Keep enums in sync with:
// scene/gui/code_edit.h - CodeEdit::CodeCompletionKind
@@ -405,6 +417,8 @@ public:
virtual ~ScriptLanguage() {}
};
+VARIANT_ENUM_CAST(ScriptLanguage::ScriptNameCasing);
+
extern uint8_t script_encryption_key[32];
class PlaceHolderScriptInstance : public ScriptInstance {
diff --git a/core/object/script_language_extension.cpp b/core/object/script_language_extension.cpp
index 3a9b171f28..ec99c7cf4e 100644
--- a/core/object/script_language_extension.cpp
+++ b/core/object/script_language_extension.cpp
@@ -112,6 +112,7 @@ void ScriptLanguageExtension::_bind_methods() {
GDVIRTUAL_BIND(_can_make_function);
GDVIRTUAL_BIND(_open_in_external_editor, "script", "line", "column");
GDVIRTUAL_BIND(_overrides_external_editor);
+ GDVIRTUAL_BIND(_preferred_file_name_casing);
GDVIRTUAL_BIND(_complete_code, "code", "path", "owner");
GDVIRTUAL_BIND(_lookup_code, "code", "symbol", "path", "owner");
diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h
index b7222a159a..18105ec8cd 100644
--- a/core/object/script_language_extension.h
+++ b/core/object/script_language_extension.h
@@ -376,6 +376,7 @@ public:
EXBIND0RC(bool, can_make_function)
EXBIND3R(Error, open_in_external_editor, const Ref<Script> &, int, int)
EXBIND0R(bool, overrides_external_editor)
+ EXBIND0RC(ScriptNameCasing, preferred_file_name_casing)
GDVIRTUAL3RC(Dictionary, _complete_code, const String &, const String &, Object *)
@@ -655,11 +656,17 @@ VARIANT_ENUM_CAST(ScriptLanguageExtension::CodeCompletionLocation)
class ScriptInstanceExtension : public ScriptInstance {
public:
- const GDExtensionScriptInstanceInfo2 *native_info;
+ const GDExtensionScriptInstanceInfo3 *native_info;
+
+#ifndef DISABLE_DEPRECATED
bool free_native_info = false;
- struct {
+ struct DeprecatedNativeInfo {
GDExtensionScriptInstanceNotification notification_func = nullptr;
- } deprecated_native_info;
+ GDExtensionScriptInstanceFreePropertyList free_property_list_func = nullptr;
+ GDExtensionScriptInstanceFreeMethodList free_method_list_func = nullptr;
+ };
+ DeprecatedNativeInfo *deprecated_native_info = nullptr;
+#endif // DISABLE_DEPRECATED
GDExtensionScriptInstanceDataPtr instance = nullptr;
@@ -706,7 +713,11 @@ public:
p_list->push_back(PropertyInfo(pinfo[i]));
}
if (native_info->free_property_list_func) {
- native_info->free_property_list_func(instance, pinfo);
+ native_info->free_property_list_func(instance, pinfo, pcount);
+#ifndef DISABLE_DEPRECATED
+ } else if (deprecated_native_info && deprecated_native_info->free_property_list_func) {
+ deprecated_native_info->free_property_list_func(instance, pinfo);
+#endif // DISABLE_DEPRECATED
}
}
}
@@ -781,7 +792,11 @@ public:
p_list->push_back(MethodInfo(minfo[i]));
}
if (native_info->free_method_list_func) {
- native_info->free_method_list_func(instance, minfo);
+ native_info->free_method_list_func(instance, minfo, mcount);
+#ifndef DISABLE_DEPRECATED
+ } else if (deprecated_native_info && deprecated_native_info->free_method_list_func) {
+ deprecated_native_info->free_method_list_func(instance, minfo);
+#endif // DISABLE_DEPRECATED
}
}
}
@@ -808,8 +823,8 @@ public:
if (native_info->notification_func) {
native_info->notification_func(instance, p_notification, p_reversed);
#ifndef DISABLE_DEPRECATED
- } else if (deprecated_native_info.notification_func) {
- deprecated_native_info.notification_func(instance, p_notification);
+ } else if (deprecated_native_info && deprecated_native_info->notification_func) {
+ deprecated_native_info->notification_func(instance, p_notification);
#endif // DISABLE_DEPRECATED
}
}
@@ -885,9 +900,14 @@ public:
if (native_info->free_func) {
native_info->free_func(instance);
}
+#ifndef DISABLE_DEPRECATED
if (free_native_info) {
- memfree(const_cast<GDExtensionScriptInstanceInfo2 *>(native_info));
+ memfree(const_cast<GDExtensionScriptInstanceInfo3 *>(native_info));
}
+ if (deprecated_native_info) {
+ memfree(deprecated_native_info);
+ }
+#endif // DISABLE_DEPRECATED
}
#if defined(__GNUC__) && !defined(__clang__)
diff --git a/core/object/worker_thread_pool.cpp b/core/object/worker_thread_pool.cpp
index e2ab473b01..ef3d315e4b 100644
--- a/core/object/worker_thread_pool.cpp
+++ b/core/object/worker_thread_pool.cpp
@@ -551,7 +551,7 @@ void WorkerThreadPool::wait_for_group_task_completion(GroupID p_group) {
Group **groupp = groups.getptr(p_group);
task_mutex.unlock();
if (!groupp) {
- ERR_FAIL_MSG("Invalid Group ID");
+ ERR_FAIL_MSG("Invalid Group ID.");
}
{
diff --git a/core/os/midi_driver.cpp b/core/os/midi_driver.cpp
index 037851661b..6870c84b49 100644
--- a/core/os/midi_driver.cpp
+++ b/core/os/midi_driver.cpp
@@ -42,9 +42,10 @@ void MIDIDriver::set_singleton() {
singleton = this;
}
-void MIDIDriver::receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_t length) {
+void MIDIDriver::receive_input_packet(int device_index, uint64_t timestamp, uint8_t *data, uint32_t length) {
Ref<InputEventMIDI> event;
event.instantiate();
+ event->set_device(device_index);
uint32_t param_position = 1;
if (length >= 1) {
diff --git a/core/os/midi_driver.h b/core/os/midi_driver.h
index 6ad21c319e..cad3d8189e 100644
--- a/core/os/midi_driver.h
+++ b/core/os/midi_driver.h
@@ -51,7 +51,7 @@ public:
virtual PackedStringArray get_connected_inputs();
- static void receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_t length);
+ static void receive_input_packet(int device_index, uint64_t timestamp, uint8_t *data, uint32_t length);
MIDIDriver();
virtual ~MIDIDriver() {}
diff --git a/core/string/char_range.inc b/core/string/char_range.inc
index 5dffe4f20d..b7d6bbdb61 100644
--- a/core/string/char_range.inc
+++ b/core/string/char_range.inc
@@ -1,5 +1,5 @@
/**************************************************************************/
-/* color_names.inc */
+/* char_range.inc */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -689,7 +689,6 @@ inline constexpr CharRange xid_start[] = {
{ 0x2ceb0, 0x2ebe0 },
{ 0x2f800, 0x2fa1d },
{ 0x30000, 0x3134a },
- { 0x0, 0x0 },
};
inline constexpr CharRange xid_continue[] = {
@@ -1450,7 +1449,1316 @@ inline constexpr CharRange xid_continue[] = {
{ 0x2f800, 0x2fa1d },
{ 0x30000, 0x3134a },
{ 0xe0100, 0xe01ef },
- { 0x0, 0x0 },
+};
+
+inline constexpr CharRange uppercase_letter[] = {
+ { 0x41, 0x5a },
+ { 0xc0, 0xd6 },
+ { 0xd8, 0xde },
+ { 0x100, 0x100 },
+ { 0x102, 0x102 },
+ { 0x104, 0x104 },
+ { 0x106, 0x106 },
+ { 0x108, 0x108 },
+ { 0x10a, 0x10a },
+ { 0x10c, 0x10c },
+ { 0x10e, 0x10e },
+ { 0x110, 0x110 },
+ { 0x112, 0x112 },
+ { 0x114, 0x114 },
+ { 0x116, 0x116 },
+ { 0x118, 0x118 },
+ { 0x11a, 0x11a },
+ { 0x11c, 0x11c },
+ { 0x11e, 0x11e },
+ { 0x120, 0x120 },
+ { 0x122, 0x122 },
+ { 0x124, 0x124 },
+ { 0x126, 0x126 },
+ { 0x128, 0x128 },
+ { 0x12a, 0x12a },
+ { 0x12c, 0x12c },
+ { 0x12e, 0x12e },
+ { 0x130, 0x130 },
+ { 0x132, 0x132 },
+ { 0x134, 0x134 },
+ { 0x136, 0x136 },
+ { 0x139, 0x139 },
+ { 0x13b, 0x13b },
+ { 0x13d, 0x13d },
+ { 0x13f, 0x13f },
+ { 0x141, 0x141 },
+ { 0x143, 0x143 },
+ { 0x145, 0x145 },
+ { 0x147, 0x147 },
+ { 0x14a, 0x14a },
+ { 0x14c, 0x14c },
+ { 0x14e, 0x14e },
+ { 0x150, 0x150 },
+ { 0x152, 0x152 },
+ { 0x154, 0x154 },
+ { 0x156, 0x156 },
+ { 0x158, 0x158 },
+ { 0x15a, 0x15a },
+ { 0x15c, 0x15c },
+ { 0x15e, 0x15e },
+ { 0x160, 0x160 },
+ { 0x162, 0x162 },
+ { 0x164, 0x164 },
+ { 0x166, 0x166 },
+ { 0x168, 0x168 },
+ { 0x16a, 0x16a },
+ { 0x16c, 0x16c },
+ { 0x16e, 0x16e },
+ { 0x170, 0x170 },
+ { 0x172, 0x172 },
+ { 0x174, 0x174 },
+ { 0x176, 0x176 },
+ { 0x178, 0x179 },
+ { 0x17b, 0x17b },
+ { 0x17d, 0x17d },
+ { 0x181, 0x182 },
+ { 0x184, 0x184 },
+ { 0x186, 0x187 },
+ { 0x189, 0x18b },
+ { 0x18e, 0x191 },
+ { 0x193, 0x194 },
+ { 0x196, 0x198 },
+ { 0x19c, 0x19d },
+ { 0x19f, 0x1a0 },
+ { 0x1a2, 0x1a2 },
+ { 0x1a4, 0x1a4 },
+ { 0x1a6, 0x1a7 },
+ { 0x1a9, 0x1a9 },
+ { 0x1ac, 0x1ac },
+ { 0x1ae, 0x1af },
+ { 0x1b1, 0x1b3 },
+ { 0x1b5, 0x1b5 },
+ { 0x1b7, 0x1b8 },
+ { 0x1bc, 0x1bc },
+ { 0x1c4, 0x1c4 },
+ { 0x1c7, 0x1c7 },
+ { 0x1ca, 0x1ca },
+ { 0x1cd, 0x1cd },
+ { 0x1cf, 0x1cf },
+ { 0x1d1, 0x1d1 },
+ { 0x1d3, 0x1d3 },
+ { 0x1d5, 0x1d5 },
+ { 0x1d7, 0x1d7 },
+ { 0x1d9, 0x1d9 },
+ { 0x1db, 0x1db },
+ { 0x1de, 0x1de },
+ { 0x1e0, 0x1e0 },
+ { 0x1e2, 0x1e2 },
+ { 0x1e4, 0x1e4 },
+ { 0x1e6, 0x1e6 },
+ { 0x1e8, 0x1e8 },
+ { 0x1ea, 0x1ea },
+ { 0x1ec, 0x1ec },
+ { 0x1ee, 0x1ee },
+ { 0x1f1, 0x1f1 },
+ { 0x1f4, 0x1f4 },
+ { 0x1f6, 0x1f8 },
+ { 0x1fa, 0x1fa },
+ { 0x1fc, 0x1fc },
+ { 0x1fe, 0x1fe },
+ { 0x200, 0x200 },
+ { 0x202, 0x202 },
+ { 0x204, 0x204 },
+ { 0x206, 0x206 },
+ { 0x208, 0x208 },
+ { 0x20a, 0x20a },
+ { 0x20c, 0x20c },
+ { 0x20e, 0x20e },
+ { 0x210, 0x210 },
+ { 0x212, 0x212 },
+ { 0x214, 0x214 },
+ { 0x216, 0x216 },
+ { 0x218, 0x218 },
+ { 0x21a, 0x21a },
+ { 0x21c, 0x21c },
+ { 0x21e, 0x21e },
+ { 0x220, 0x220 },
+ { 0x222, 0x222 },
+ { 0x224, 0x224 },
+ { 0x226, 0x226 },
+ { 0x228, 0x228 },
+ { 0x22a, 0x22a },
+ { 0x22c, 0x22c },
+ { 0x22e, 0x22e },
+ { 0x230, 0x230 },
+ { 0x232, 0x232 },
+ { 0x23a, 0x23b },
+ { 0x23d, 0x23e },
+ { 0x241, 0x241 },
+ { 0x243, 0x246 },
+ { 0x248, 0x248 },
+ { 0x24a, 0x24a },
+ { 0x24c, 0x24c },
+ { 0x24e, 0x24e },
+ { 0x370, 0x370 },
+ { 0x372, 0x372 },
+ { 0x376, 0x376 },
+ { 0x37f, 0x37f },
+ { 0x386, 0x386 },
+ { 0x388, 0x38a },
+ { 0x38c, 0x38c },
+ { 0x38e, 0x38f },
+ { 0x391, 0x3a1 },
+ { 0x3a3, 0x3ab },
+ { 0x3cf, 0x3cf },
+ { 0x3d2, 0x3d4 },
+ { 0x3d8, 0x3d8 },
+ { 0x3da, 0x3da },
+ { 0x3dc, 0x3dc },
+ { 0x3de, 0x3de },
+ { 0x3e0, 0x3e0 },
+ { 0x3e2, 0x3e2 },
+ { 0x3e4, 0x3e4 },
+ { 0x3e6, 0x3e6 },
+ { 0x3e8, 0x3e8 },
+ { 0x3ea, 0x3ea },
+ { 0x3ec, 0x3ec },
+ { 0x3ee, 0x3ee },
+ { 0x3f4, 0x3f4 },
+ { 0x3f7, 0x3f7 },
+ { 0x3f9, 0x3fa },
+ { 0x3fd, 0x42f },
+ { 0x460, 0x460 },
+ { 0x462, 0x462 },
+ { 0x464, 0x464 },
+ { 0x466, 0x466 },
+ { 0x468, 0x468 },
+ { 0x46a, 0x46a },
+ { 0x46c, 0x46c },
+ { 0x46e, 0x46e },
+ { 0x470, 0x470 },
+ { 0x472, 0x472 },
+ { 0x474, 0x474 },
+ { 0x476, 0x476 },
+ { 0x478, 0x478 },
+ { 0x47a, 0x47a },
+ { 0x47c, 0x47c },
+ { 0x47e, 0x47e },
+ { 0x480, 0x480 },
+ { 0x48a, 0x48a },
+ { 0x48c, 0x48c },
+ { 0x48e, 0x48e },
+ { 0x490, 0x490 },
+ { 0x492, 0x492 },
+ { 0x494, 0x494 },
+ { 0x496, 0x496 },
+ { 0x498, 0x498 },
+ { 0x49a, 0x49a },
+ { 0x49c, 0x49c },
+ { 0x49e, 0x49e },
+ { 0x4a0, 0x4a0 },
+ { 0x4a2, 0x4a2 },
+ { 0x4a4, 0x4a4 },
+ { 0x4a6, 0x4a6 },
+ { 0x4a8, 0x4a8 },
+ { 0x4aa, 0x4aa },
+ { 0x4ac, 0x4ac },
+ { 0x4ae, 0x4ae },
+ { 0x4b0, 0x4b0 },
+ { 0x4b2, 0x4b2 },
+ { 0x4b4, 0x4b4 },
+ { 0x4b6, 0x4b6 },
+ { 0x4b8, 0x4b8 },
+ { 0x4ba, 0x4ba },
+ { 0x4bc, 0x4bc },
+ { 0x4be, 0x4be },
+ { 0x4c0, 0x4c1 },
+ { 0x4c3, 0x4c3 },
+ { 0x4c5, 0x4c5 },
+ { 0x4c7, 0x4c7 },
+ { 0x4c9, 0x4c9 },
+ { 0x4cb, 0x4cb },
+ { 0x4cd, 0x4cd },
+ { 0x4d0, 0x4d0 },
+ { 0x4d2, 0x4d2 },
+ { 0x4d4, 0x4d4 },
+ { 0x4d6, 0x4d6 },
+ { 0x4d8, 0x4d8 },
+ { 0x4da, 0x4da },
+ { 0x4dc, 0x4dc },
+ { 0x4de, 0x4de },
+ { 0x4e0, 0x4e0 },
+ { 0x4e2, 0x4e2 },
+ { 0x4e4, 0x4e4 },
+ { 0x4e6, 0x4e6 },
+ { 0x4e8, 0x4e8 },
+ { 0x4ea, 0x4ea },
+ { 0x4ec, 0x4ec },
+ { 0x4ee, 0x4ee },
+ { 0x4f0, 0x4f0 },
+ { 0x4f2, 0x4f2 },
+ { 0x4f4, 0x4f4 },
+ { 0x4f6, 0x4f6 },
+ { 0x4f8, 0x4f8 },
+ { 0x4fa, 0x4fa },
+ { 0x4fc, 0x4fc },
+ { 0x4fe, 0x4fe },
+ { 0x500, 0x500 },
+ { 0x502, 0x502 },
+ { 0x504, 0x504 },
+ { 0x506, 0x506 },
+ { 0x508, 0x508 },
+ { 0x50a, 0x50a },
+ { 0x50c, 0x50c },
+ { 0x50e, 0x50e },
+ { 0x510, 0x510 },
+ { 0x512, 0x512 },
+ { 0x514, 0x514 },
+ { 0x516, 0x516 },
+ { 0x518, 0x518 },
+ { 0x51a, 0x51a },
+ { 0x51c, 0x51c },
+ { 0x51e, 0x51e },
+ { 0x520, 0x520 },
+ { 0x522, 0x522 },
+ { 0x524, 0x524 },
+ { 0x526, 0x526 },
+ { 0x528, 0x528 },
+ { 0x52a, 0x52a },
+ { 0x52c, 0x52c },
+ { 0x52e, 0x52e },
+ { 0x531, 0x556 },
+ { 0x10a0, 0x10c5 },
+ { 0x10c7, 0x10c7 },
+ { 0x10cd, 0x10cd },
+ { 0x13a0, 0x13f5 },
+ { 0x1c90, 0x1cba },
+ { 0x1cbd, 0x1cbf },
+ { 0x1e00, 0x1e00 },
+ { 0x1e02, 0x1e02 },
+ { 0x1e04, 0x1e04 },
+ { 0x1e06, 0x1e06 },
+ { 0x1e08, 0x1e08 },
+ { 0x1e0a, 0x1e0a },
+ { 0x1e0c, 0x1e0c },
+ { 0x1e0e, 0x1e0e },
+ { 0x1e10, 0x1e10 },
+ { 0x1e12, 0x1e12 },
+ { 0x1e14, 0x1e14 },
+ { 0x1e16, 0x1e16 },
+ { 0x1e18, 0x1e18 },
+ { 0x1e1a, 0x1e1a },
+ { 0x1e1c, 0x1e1c },
+ { 0x1e1e, 0x1e1e },
+ { 0x1e20, 0x1e20 },
+ { 0x1e22, 0x1e22 },
+ { 0x1e24, 0x1e24 },
+ { 0x1e26, 0x1e26 },
+ { 0x1e28, 0x1e28 },
+ { 0x1e2a, 0x1e2a },
+ { 0x1e2c, 0x1e2c },
+ { 0x1e2e, 0x1e2e },
+ { 0x1e30, 0x1e30 },
+ { 0x1e32, 0x1e32 },
+ { 0x1e34, 0x1e34 },
+ { 0x1e36, 0x1e36 },
+ { 0x1e38, 0x1e38 },
+ { 0x1e3a, 0x1e3a },
+ { 0x1e3c, 0x1e3c },
+ { 0x1e3e, 0x1e3e },
+ { 0x1e40, 0x1e40 },
+ { 0x1e42, 0x1e42 },
+ { 0x1e44, 0x1e44 },
+ { 0x1e46, 0x1e46 },
+ { 0x1e48, 0x1e48 },
+ { 0x1e4a, 0x1e4a },
+ { 0x1e4c, 0x1e4c },
+ { 0x1e4e, 0x1e4e },
+ { 0x1e50, 0x1e50 },
+ { 0x1e52, 0x1e52 },
+ { 0x1e54, 0x1e54 },
+ { 0x1e56, 0x1e56 },
+ { 0x1e58, 0x1e58 },
+ { 0x1e5a, 0x1e5a },
+ { 0x1e5c, 0x1e5c },
+ { 0x1e5e, 0x1e5e },
+ { 0x1e60, 0x1e60 },
+ { 0x1e62, 0x1e62 },
+ { 0x1e64, 0x1e64 },
+ { 0x1e66, 0x1e66 },
+ { 0x1e68, 0x1e68 },
+ { 0x1e6a, 0x1e6a },
+ { 0x1e6c, 0x1e6c },
+ { 0x1e6e, 0x1e6e },
+ { 0x1e70, 0x1e70 },
+ { 0x1e72, 0x1e72 },
+ { 0x1e74, 0x1e74 },
+ { 0x1e76, 0x1e76 },
+ { 0x1e78, 0x1e78 },
+ { 0x1e7a, 0x1e7a },
+ { 0x1e7c, 0x1e7c },
+ { 0x1e7e, 0x1e7e },
+ { 0x1e80, 0x1e80 },
+ { 0x1e82, 0x1e82 },
+ { 0x1e84, 0x1e84 },
+ { 0x1e86, 0x1e86 },
+ { 0x1e88, 0x1e88 },
+ { 0x1e8a, 0x1e8a },
+ { 0x1e8c, 0x1e8c },
+ { 0x1e8e, 0x1e8e },
+ { 0x1e90, 0x1e90 },
+ { 0x1e92, 0x1e92 },
+ { 0x1e94, 0x1e94 },
+ { 0x1e9e, 0x1e9e },
+ { 0x1ea0, 0x1ea0 },
+ { 0x1ea2, 0x1ea2 },
+ { 0x1ea4, 0x1ea4 },
+ { 0x1ea6, 0x1ea6 },
+ { 0x1ea8, 0x1ea8 },
+ { 0x1eaa, 0x1eaa },
+ { 0x1eac, 0x1eac },
+ { 0x1eae, 0x1eae },
+ { 0x1eb0, 0x1eb0 },
+ { 0x1eb2, 0x1eb2 },
+ { 0x1eb4, 0x1eb4 },
+ { 0x1eb6, 0x1eb6 },
+ { 0x1eb8, 0x1eb8 },
+ { 0x1eba, 0x1eba },
+ { 0x1ebc, 0x1ebc },
+ { 0x1ebe, 0x1ebe },
+ { 0x1ec0, 0x1ec0 },
+ { 0x1ec2, 0x1ec2 },
+ { 0x1ec4, 0x1ec4 },
+ { 0x1ec6, 0x1ec6 },
+ { 0x1ec8, 0x1ec8 },
+ { 0x1eca, 0x1eca },
+ { 0x1ecc, 0x1ecc },
+ { 0x1ece, 0x1ece },
+ { 0x1ed0, 0x1ed0 },
+ { 0x1ed2, 0x1ed2 },
+ { 0x1ed4, 0x1ed4 },
+ { 0x1ed6, 0x1ed6 },
+ { 0x1ed8, 0x1ed8 },
+ { 0x1eda, 0x1eda },
+ { 0x1edc, 0x1edc },
+ { 0x1ede, 0x1ede },
+ { 0x1ee0, 0x1ee0 },
+ { 0x1ee2, 0x1ee2 },
+ { 0x1ee4, 0x1ee4 },
+ { 0x1ee6, 0x1ee6 },
+ { 0x1ee8, 0x1ee8 },
+ { 0x1eea, 0x1eea },
+ { 0x1eec, 0x1eec },
+ { 0x1eee, 0x1eee },
+ { 0x1ef0, 0x1ef0 },
+ { 0x1ef2, 0x1ef2 },
+ { 0x1ef4, 0x1ef4 },
+ { 0x1ef6, 0x1ef6 },
+ { 0x1ef8, 0x1ef8 },
+ { 0x1efa, 0x1efa },
+ { 0x1efc, 0x1efc },
+ { 0x1efe, 0x1efe },
+ { 0x1f08, 0x1f0f },
+ { 0x1f18, 0x1f1d },
+ { 0x1f28, 0x1f2f },
+ { 0x1f38, 0x1f3f },
+ { 0x1f48, 0x1f4d },
+ { 0x1f59, 0x1f59 },
+ { 0x1f5b, 0x1f5b },
+ { 0x1f5d, 0x1f5d },
+ { 0x1f5f, 0x1f5f },
+ { 0x1f68, 0x1f6f },
+ { 0x1fb8, 0x1fbb },
+ { 0x1fc8, 0x1fcb },
+ { 0x1fd8, 0x1fdb },
+ { 0x1fe8, 0x1fec },
+ { 0x1ff8, 0x1ffb },
+ { 0x2102, 0x2102 },
+ { 0x2107, 0x2107 },
+ { 0x210b, 0x210d },
+ { 0x2110, 0x2112 },
+ { 0x2115, 0x2115 },
+ { 0x2119, 0x211d },
+ { 0x2124, 0x2124 },
+ { 0x2126, 0x2126 },
+ { 0x2128, 0x2128 },
+ { 0x212a, 0x212d },
+ { 0x2130, 0x2133 },
+ { 0x213e, 0x213f },
+ { 0x2145, 0x2145 },
+ { 0x2183, 0x2183 },
+ { 0x2c00, 0x2c2f },
+ { 0x2c60, 0x2c60 },
+ { 0x2c62, 0x2c64 },
+ { 0x2c67, 0x2c67 },
+ { 0x2c69, 0x2c69 },
+ { 0x2c6b, 0x2c6b },
+ { 0x2c6d, 0x2c70 },
+ { 0x2c72, 0x2c72 },
+ { 0x2c75, 0x2c75 },
+ { 0x2c7e, 0x2c80 },
+ { 0x2c82, 0x2c82 },
+ { 0x2c84, 0x2c84 },
+ { 0x2c86, 0x2c86 },
+ { 0x2c88, 0x2c88 },
+ { 0x2c8a, 0x2c8a },
+ { 0x2c8c, 0x2c8c },
+ { 0x2c8e, 0x2c8e },
+ { 0x2c90, 0x2c90 },
+ { 0x2c92, 0x2c92 },
+ { 0x2c94, 0x2c94 },
+ { 0x2c96, 0x2c96 },
+ { 0x2c98, 0x2c98 },
+ { 0x2c9a, 0x2c9a },
+ { 0x2c9c, 0x2c9c },
+ { 0x2c9e, 0x2c9e },
+ { 0x2ca0, 0x2ca0 },
+ { 0x2ca2, 0x2ca2 },
+ { 0x2ca4, 0x2ca4 },
+ { 0x2ca6, 0x2ca6 },
+ { 0x2ca8, 0x2ca8 },
+ { 0x2caa, 0x2caa },
+ { 0x2cac, 0x2cac },
+ { 0x2cae, 0x2cae },
+ { 0x2cb0, 0x2cb0 },
+ { 0x2cb2, 0x2cb2 },
+ { 0x2cb4, 0x2cb4 },
+ { 0x2cb6, 0x2cb6 },
+ { 0x2cb8, 0x2cb8 },
+ { 0x2cba, 0x2cba },
+ { 0x2cbc, 0x2cbc },
+ { 0x2cbe, 0x2cbe },
+ { 0x2cc0, 0x2cc0 },
+ { 0x2cc2, 0x2cc2 },
+ { 0x2cc4, 0x2cc4 },
+ { 0x2cc6, 0x2cc6 },
+ { 0x2cc8, 0x2cc8 },
+ { 0x2cca, 0x2cca },
+ { 0x2ccc, 0x2ccc },
+ { 0x2cce, 0x2cce },
+ { 0x2cd0, 0x2cd0 },
+ { 0x2cd2, 0x2cd2 },
+ { 0x2cd4, 0x2cd4 },
+ { 0x2cd6, 0x2cd6 },
+ { 0x2cd8, 0x2cd8 },
+ { 0x2cda, 0x2cda },
+ { 0x2cdc, 0x2cdc },
+ { 0x2cde, 0x2cde },
+ { 0x2ce0, 0x2ce0 },
+ { 0x2ce2, 0x2ce2 },
+ { 0x2ceb, 0x2ceb },
+ { 0x2ced, 0x2ced },
+ { 0x2cf2, 0x2cf2 },
+ { 0xa640, 0xa640 },
+ { 0xa642, 0xa642 },
+ { 0xa644, 0xa644 },
+ { 0xa646, 0xa646 },
+ { 0xa648, 0xa648 },
+ { 0xa64a, 0xa64a },
+ { 0xa64c, 0xa64c },
+ { 0xa64e, 0xa64e },
+ { 0xa650, 0xa650 },
+ { 0xa652, 0xa652 },
+ { 0xa654, 0xa654 },
+ { 0xa656, 0xa656 },
+ { 0xa658, 0xa658 },
+ { 0xa65a, 0xa65a },
+ { 0xa65c, 0xa65c },
+ { 0xa65e, 0xa65e },
+ { 0xa660, 0xa660 },
+ { 0xa662, 0xa662 },
+ { 0xa664, 0xa664 },
+ { 0xa666, 0xa666 },
+ { 0xa668, 0xa668 },
+ { 0xa66a, 0xa66a },
+ { 0xa66c, 0xa66c },
+ { 0xa680, 0xa680 },
+ { 0xa682, 0xa682 },
+ { 0xa684, 0xa684 },
+ { 0xa686, 0xa686 },
+ { 0xa688, 0xa688 },
+ { 0xa68a, 0xa68a },
+ { 0xa68c, 0xa68c },
+ { 0xa68e, 0xa68e },
+ { 0xa690, 0xa690 },
+ { 0xa692, 0xa692 },
+ { 0xa694, 0xa694 },
+ { 0xa696, 0xa696 },
+ { 0xa698, 0xa698 },
+ { 0xa69a, 0xa69a },
+ { 0xa722, 0xa722 },
+ { 0xa724, 0xa724 },
+ { 0xa726, 0xa726 },
+ { 0xa728, 0xa728 },
+ { 0xa72a, 0xa72a },
+ { 0xa72c, 0xa72c },
+ { 0xa72e, 0xa72e },
+ { 0xa732, 0xa732 },
+ { 0xa734, 0xa734 },
+ { 0xa736, 0xa736 },
+ { 0xa738, 0xa738 },
+ { 0xa73a, 0xa73a },
+ { 0xa73c, 0xa73c },
+ { 0xa73e, 0xa73e },
+ { 0xa740, 0xa740 },
+ { 0xa742, 0xa742 },
+ { 0xa744, 0xa744 },
+ { 0xa746, 0xa746 },
+ { 0xa748, 0xa748 },
+ { 0xa74a, 0xa74a },
+ { 0xa74c, 0xa74c },
+ { 0xa74e, 0xa74e },
+ { 0xa750, 0xa750 },
+ { 0xa752, 0xa752 },
+ { 0xa754, 0xa754 },
+ { 0xa756, 0xa756 },
+ { 0xa758, 0xa758 },
+ { 0xa75a, 0xa75a },
+ { 0xa75c, 0xa75c },
+ { 0xa75e, 0xa75e },
+ { 0xa760, 0xa760 },
+ { 0xa762, 0xa762 },
+ { 0xa764, 0xa764 },
+ { 0xa766, 0xa766 },
+ { 0xa768, 0xa768 },
+ { 0xa76a, 0xa76a },
+ { 0xa76c, 0xa76c },
+ { 0xa76e, 0xa76e },
+ { 0xa779, 0xa779 },
+ { 0xa77b, 0xa77b },
+ { 0xa77d, 0xa77e },
+ { 0xa780, 0xa780 },
+ { 0xa782, 0xa782 },
+ { 0xa784, 0xa784 },
+ { 0xa786, 0xa786 },
+ { 0xa78b, 0xa78b },
+ { 0xa78d, 0xa78d },
+ { 0xa790, 0xa790 },
+ { 0xa792, 0xa792 },
+ { 0xa796, 0xa796 },
+ { 0xa798, 0xa798 },
+ { 0xa79a, 0xa79a },
+ { 0xa79c, 0xa79c },
+ { 0xa79e, 0xa79e },
+ { 0xa7a0, 0xa7a0 },
+ { 0xa7a2, 0xa7a2 },
+ { 0xa7a4, 0xa7a4 },
+ { 0xa7a6, 0xa7a6 },
+ { 0xa7a8, 0xa7a8 },
+ { 0xa7aa, 0xa7ae },
+ { 0xa7b0, 0xa7b4 },
+ { 0xa7b6, 0xa7b6 },
+ { 0xa7b8, 0xa7b8 },
+ { 0xa7ba, 0xa7ba },
+ { 0xa7bc, 0xa7bc },
+ { 0xa7be, 0xa7be },
+ { 0xa7c0, 0xa7c0 },
+ { 0xa7c2, 0xa7c2 },
+ { 0xa7c4, 0xa7c7 },
+ { 0xa7c9, 0xa7c9 },
+ { 0xa7d0, 0xa7d0 },
+ { 0xa7d6, 0xa7d6 },
+ { 0xa7d8, 0xa7d8 },
+ { 0xa7f5, 0xa7f5 },
+ { 0xff21, 0xff3a },
+ { 0x10400, 0x10427 },
+ { 0x104b0, 0x104d3 },
+ { 0x10570, 0x1057a },
+ { 0x1057c, 0x1058a },
+ { 0x1058c, 0x10592 },
+ { 0x10594, 0x10595 },
+ { 0x10c80, 0x10cb2 },
+ { 0x118a0, 0x118bf },
+ { 0x16e40, 0x16e5f },
+ { 0x1d400, 0x1d419 },
+ { 0x1d434, 0x1d44d },
+ { 0x1d468, 0x1d481 },
+ { 0x1d49c, 0x1d49c },
+ { 0x1d49e, 0x1d49f },
+ { 0x1d4a2, 0x1d4a2 },
+ { 0x1d4a5, 0x1d4a6 },
+ { 0x1d4a9, 0x1d4ac },
+ { 0x1d4ae, 0x1d4b5 },
+ { 0x1d4d0, 0x1d4e9 },
+ { 0x1d504, 0x1d505 },
+ { 0x1d507, 0x1d50a },
+ { 0x1d50d, 0x1d514 },
+ { 0x1d516, 0x1d51c },
+ { 0x1d538, 0x1d539 },
+ { 0x1d53b, 0x1d53e },
+ { 0x1d540, 0x1d544 },
+ { 0x1d546, 0x1d546 },
+ { 0x1d54a, 0x1d550 },
+ { 0x1d56c, 0x1d585 },
+ { 0x1d5a0, 0x1d5b9 },
+ { 0x1d5d4, 0x1d5ed },
+ { 0x1d608, 0x1d621 },
+ { 0x1d63c, 0x1d655 },
+ { 0x1d670, 0x1d689 },
+ { 0x1d6a8, 0x1d6c0 },
+ { 0x1d6e2, 0x1d6fa },
+ { 0x1d71c, 0x1d734 },
+ { 0x1d756, 0x1d76e },
+ { 0x1d790, 0x1d7a8 },
+ { 0x1d7ca, 0x1d7ca },
+ { 0x1e900, 0x1e921 },
+};
+
+inline constexpr CharRange lowercase_letter[] = {
+ { 0x61, 0x7a },
+ { 0xb5, 0xb5 },
+ { 0xdf, 0xf6 },
+ { 0xf8, 0xff },
+ { 0x101, 0x101 },
+ { 0x103, 0x103 },
+ { 0x105, 0x105 },
+ { 0x107, 0x107 },
+ { 0x109, 0x109 },
+ { 0x10b, 0x10b },
+ { 0x10d, 0x10d },
+ { 0x10f, 0x10f },
+ { 0x111, 0x111 },
+ { 0x113, 0x113 },
+ { 0x115, 0x115 },
+ { 0x117, 0x117 },
+ { 0x119, 0x119 },
+ { 0x11b, 0x11b },
+ { 0x11d, 0x11d },
+ { 0x11f, 0x11f },
+ { 0x121, 0x121 },
+ { 0x123, 0x123 },
+ { 0x125, 0x125 },
+ { 0x127, 0x127 },
+ { 0x129, 0x129 },
+ { 0x12b, 0x12b },
+ { 0x12d, 0x12d },
+ { 0x12f, 0x12f },
+ { 0x131, 0x131 },
+ { 0x133, 0x133 },
+ { 0x135, 0x135 },
+ { 0x137, 0x138 },
+ { 0x13a, 0x13a },
+ { 0x13c, 0x13c },
+ { 0x13e, 0x13e },
+ { 0x140, 0x140 },
+ { 0x142, 0x142 },
+ { 0x144, 0x144 },
+ { 0x146, 0x146 },
+ { 0x148, 0x149 },
+ { 0x14b, 0x14b },
+ { 0x14d, 0x14d },
+ { 0x14f, 0x14f },
+ { 0x151, 0x151 },
+ { 0x153, 0x153 },
+ { 0x155, 0x155 },
+ { 0x157, 0x157 },
+ { 0x159, 0x159 },
+ { 0x15b, 0x15b },
+ { 0x15d, 0x15d },
+ { 0x15f, 0x15f },
+ { 0x161, 0x161 },
+ { 0x163, 0x163 },
+ { 0x165, 0x165 },
+ { 0x167, 0x167 },
+ { 0x169, 0x169 },
+ { 0x16b, 0x16b },
+ { 0x16d, 0x16d },
+ { 0x16f, 0x16f },
+ { 0x171, 0x171 },
+ { 0x173, 0x173 },
+ { 0x175, 0x175 },
+ { 0x177, 0x177 },
+ { 0x17a, 0x17a },
+ { 0x17c, 0x17c },
+ { 0x17e, 0x180 },
+ { 0x183, 0x183 },
+ { 0x185, 0x185 },
+ { 0x188, 0x188 },
+ { 0x18c, 0x18d },
+ { 0x192, 0x192 },
+ { 0x195, 0x195 },
+ { 0x199, 0x19b },
+ { 0x19e, 0x19e },
+ { 0x1a1, 0x1a1 },
+ { 0x1a3, 0x1a3 },
+ { 0x1a5, 0x1a5 },
+ { 0x1a8, 0x1a8 },
+ { 0x1aa, 0x1ab },
+ { 0x1ad, 0x1ad },
+ { 0x1b0, 0x1b0 },
+ { 0x1b4, 0x1b4 },
+ { 0x1b6, 0x1b6 },
+ { 0x1b9, 0x1ba },
+ { 0x1bd, 0x1bf },
+ { 0x1c6, 0x1c6 },
+ { 0x1c9, 0x1c9 },
+ { 0x1cc, 0x1cc },
+ { 0x1ce, 0x1ce },
+ { 0x1d0, 0x1d0 },
+ { 0x1d2, 0x1d2 },
+ { 0x1d4, 0x1d4 },
+ { 0x1d6, 0x1d6 },
+ { 0x1d8, 0x1d8 },
+ { 0x1da, 0x1da },
+ { 0x1dc, 0x1dd },
+ { 0x1df, 0x1df },
+ { 0x1e1, 0x1e1 },
+ { 0x1e3, 0x1e3 },
+ { 0x1e5, 0x1e5 },
+ { 0x1e7, 0x1e7 },
+ { 0x1e9, 0x1e9 },
+ { 0x1eb, 0x1eb },
+ { 0x1ed, 0x1ed },
+ { 0x1ef, 0x1f0 },
+ { 0x1f3, 0x1f3 },
+ { 0x1f5, 0x1f5 },
+ { 0x1f9, 0x1f9 },
+ { 0x1fb, 0x1fb },
+ { 0x1fd, 0x1fd },
+ { 0x1ff, 0x1ff },
+ { 0x201, 0x201 },
+ { 0x203, 0x203 },
+ { 0x205, 0x205 },
+ { 0x207, 0x207 },
+ { 0x209, 0x209 },
+ { 0x20b, 0x20b },
+ { 0x20d, 0x20d },
+ { 0x20f, 0x20f },
+ { 0x211, 0x211 },
+ { 0x213, 0x213 },
+ { 0x215, 0x215 },
+ { 0x217, 0x217 },
+ { 0x219, 0x219 },
+ { 0x21b, 0x21b },
+ { 0x21d, 0x21d },
+ { 0x21f, 0x21f },
+ { 0x221, 0x221 },
+ { 0x223, 0x223 },
+ { 0x225, 0x225 },
+ { 0x227, 0x227 },
+ { 0x229, 0x229 },
+ { 0x22b, 0x22b },
+ { 0x22d, 0x22d },
+ { 0x22f, 0x22f },
+ { 0x231, 0x231 },
+ { 0x233, 0x239 },
+ { 0x23c, 0x23c },
+ { 0x23f, 0x240 },
+ { 0x242, 0x242 },
+ { 0x247, 0x247 },
+ { 0x249, 0x249 },
+ { 0x24b, 0x24b },
+ { 0x24d, 0x24d },
+ { 0x24f, 0x293 },
+ { 0x295, 0x2af },
+ { 0x371, 0x371 },
+ { 0x373, 0x373 },
+ { 0x377, 0x377 },
+ { 0x37b, 0x37d },
+ { 0x390, 0x390 },
+ { 0x3ac, 0x3ce },
+ { 0x3d0, 0x3d1 },
+ { 0x3d5, 0x3d7 },
+ { 0x3d9, 0x3d9 },
+ { 0x3db, 0x3db },
+ { 0x3dd, 0x3dd },
+ { 0x3df, 0x3df },
+ { 0x3e1, 0x3e1 },
+ { 0x3e3, 0x3e3 },
+ { 0x3e5, 0x3e5 },
+ { 0x3e7, 0x3e7 },
+ { 0x3e9, 0x3e9 },
+ { 0x3eb, 0x3eb },
+ { 0x3ed, 0x3ed },
+ { 0x3ef, 0x3f3 },
+ { 0x3f5, 0x3f5 },
+ { 0x3f8, 0x3f8 },
+ { 0x3fb, 0x3fc },
+ { 0x430, 0x45f },
+ { 0x461, 0x461 },
+ { 0x463, 0x463 },
+ { 0x465, 0x465 },
+ { 0x467, 0x467 },
+ { 0x469, 0x469 },
+ { 0x46b, 0x46b },
+ { 0x46d, 0x46d },
+ { 0x46f, 0x46f },
+ { 0x471, 0x471 },
+ { 0x473, 0x473 },
+ { 0x475, 0x475 },
+ { 0x477, 0x477 },
+ { 0x479, 0x479 },
+ { 0x47b, 0x47b },
+ { 0x47d, 0x47d },
+ { 0x47f, 0x47f },
+ { 0x481, 0x481 },
+ { 0x48b, 0x48b },
+ { 0x48d, 0x48d },
+ { 0x48f, 0x48f },
+ { 0x491, 0x491 },
+ { 0x493, 0x493 },
+ { 0x495, 0x495 },
+ { 0x497, 0x497 },
+ { 0x499, 0x499 },
+ { 0x49b, 0x49b },
+ { 0x49d, 0x49d },
+ { 0x49f, 0x49f },
+ { 0x4a1, 0x4a1 },
+ { 0x4a3, 0x4a3 },
+ { 0x4a5, 0x4a5 },
+ { 0x4a7, 0x4a7 },
+ { 0x4a9, 0x4a9 },
+ { 0x4ab, 0x4ab },
+ { 0x4ad, 0x4ad },
+ { 0x4af, 0x4af },
+ { 0x4b1, 0x4b1 },
+ { 0x4b3, 0x4b3 },
+ { 0x4b5, 0x4b5 },
+ { 0x4b7, 0x4b7 },
+ { 0x4b9, 0x4b9 },
+ { 0x4bb, 0x4bb },
+ { 0x4bd, 0x4bd },
+ { 0x4bf, 0x4bf },
+ { 0x4c2, 0x4c2 },
+ { 0x4c4, 0x4c4 },
+ { 0x4c6, 0x4c6 },
+ { 0x4c8, 0x4c8 },
+ { 0x4ca, 0x4ca },
+ { 0x4cc, 0x4cc },
+ { 0x4ce, 0x4cf },
+ { 0x4d1, 0x4d1 },
+ { 0x4d3, 0x4d3 },
+ { 0x4d5, 0x4d5 },
+ { 0x4d7, 0x4d7 },
+ { 0x4d9, 0x4d9 },
+ { 0x4db, 0x4db },
+ { 0x4dd, 0x4dd },
+ { 0x4df, 0x4df },
+ { 0x4e1, 0x4e1 },
+ { 0x4e3, 0x4e3 },
+ { 0x4e5, 0x4e5 },
+ { 0x4e7, 0x4e7 },
+ { 0x4e9, 0x4e9 },
+ { 0x4eb, 0x4eb },
+ { 0x4ed, 0x4ed },
+ { 0x4ef, 0x4ef },
+ { 0x4f1, 0x4f1 },
+ { 0x4f3, 0x4f3 },
+ { 0x4f5, 0x4f5 },
+ { 0x4f7, 0x4f7 },
+ { 0x4f9, 0x4f9 },
+ { 0x4fb, 0x4fb },
+ { 0x4fd, 0x4fd },
+ { 0x4ff, 0x4ff },
+ { 0x501, 0x501 },
+ { 0x503, 0x503 },
+ { 0x505, 0x505 },
+ { 0x507, 0x507 },
+ { 0x509, 0x509 },
+ { 0x50b, 0x50b },
+ { 0x50d, 0x50d },
+ { 0x50f, 0x50f },
+ { 0x511, 0x511 },
+ { 0x513, 0x513 },
+ { 0x515, 0x515 },
+ { 0x517, 0x517 },
+ { 0x519, 0x519 },
+ { 0x51b, 0x51b },
+ { 0x51d, 0x51d },
+ { 0x51f, 0x51f },
+ { 0x521, 0x521 },
+ { 0x523, 0x523 },
+ { 0x525, 0x525 },
+ { 0x527, 0x527 },
+ { 0x529, 0x529 },
+ { 0x52b, 0x52b },
+ { 0x52d, 0x52d },
+ { 0x52f, 0x52f },
+ { 0x560, 0x588 },
+ { 0x10d0, 0x10fa },
+ { 0x10fd, 0x10ff },
+ { 0x13f8, 0x13fd },
+ { 0x1c80, 0x1c88 },
+ { 0x1d00, 0x1d2b },
+ { 0x1d6b, 0x1d77 },
+ { 0x1d79, 0x1d9a },
+ { 0x1e01, 0x1e01 },
+ { 0x1e03, 0x1e03 },
+ { 0x1e05, 0x1e05 },
+ { 0x1e07, 0x1e07 },
+ { 0x1e09, 0x1e09 },
+ { 0x1e0b, 0x1e0b },
+ { 0x1e0d, 0x1e0d },
+ { 0x1e0f, 0x1e0f },
+ { 0x1e11, 0x1e11 },
+ { 0x1e13, 0x1e13 },
+ { 0x1e15, 0x1e15 },
+ { 0x1e17, 0x1e17 },
+ { 0x1e19, 0x1e19 },
+ { 0x1e1b, 0x1e1b },
+ { 0x1e1d, 0x1e1d },
+ { 0x1e1f, 0x1e1f },
+ { 0x1e21, 0x1e21 },
+ { 0x1e23, 0x1e23 },
+ { 0x1e25, 0x1e25 },
+ { 0x1e27, 0x1e27 },
+ { 0x1e29, 0x1e29 },
+ { 0x1e2b, 0x1e2b },
+ { 0x1e2d, 0x1e2d },
+ { 0x1e2f, 0x1e2f },
+ { 0x1e31, 0x1e31 },
+ { 0x1e33, 0x1e33 },
+ { 0x1e35, 0x1e35 },
+ { 0x1e37, 0x1e37 },
+ { 0x1e39, 0x1e39 },
+ { 0x1e3b, 0x1e3b },
+ { 0x1e3d, 0x1e3d },
+ { 0x1e3f, 0x1e3f },
+ { 0x1e41, 0x1e41 },
+ { 0x1e43, 0x1e43 },
+ { 0x1e45, 0x1e45 },
+ { 0x1e47, 0x1e47 },
+ { 0x1e49, 0x1e49 },
+ { 0x1e4b, 0x1e4b },
+ { 0x1e4d, 0x1e4d },
+ { 0x1e4f, 0x1e4f },
+ { 0x1e51, 0x1e51 },
+ { 0x1e53, 0x1e53 },
+ { 0x1e55, 0x1e55 },
+ { 0x1e57, 0x1e57 },
+ { 0x1e59, 0x1e59 },
+ { 0x1e5b, 0x1e5b },
+ { 0x1e5d, 0x1e5d },
+ { 0x1e5f, 0x1e5f },
+ { 0x1e61, 0x1e61 },
+ { 0x1e63, 0x1e63 },
+ { 0x1e65, 0x1e65 },
+ { 0x1e67, 0x1e67 },
+ { 0x1e69, 0x1e69 },
+ { 0x1e6b, 0x1e6b },
+ { 0x1e6d, 0x1e6d },
+ { 0x1e6f, 0x1e6f },
+ { 0x1e71, 0x1e71 },
+ { 0x1e73, 0x1e73 },
+ { 0x1e75, 0x1e75 },
+ { 0x1e77, 0x1e77 },
+ { 0x1e79, 0x1e79 },
+ { 0x1e7b, 0x1e7b },
+ { 0x1e7d, 0x1e7d },
+ { 0x1e7f, 0x1e7f },
+ { 0x1e81, 0x1e81 },
+ { 0x1e83, 0x1e83 },
+ { 0x1e85, 0x1e85 },
+ { 0x1e87, 0x1e87 },
+ { 0x1e89, 0x1e89 },
+ { 0x1e8b, 0x1e8b },
+ { 0x1e8d, 0x1e8d },
+ { 0x1e8f, 0x1e8f },
+ { 0x1e91, 0x1e91 },
+ { 0x1e93, 0x1e93 },
+ { 0x1e95, 0x1e9d },
+ { 0x1e9f, 0x1e9f },
+ { 0x1ea1, 0x1ea1 },
+ { 0x1ea3, 0x1ea3 },
+ { 0x1ea5, 0x1ea5 },
+ { 0x1ea7, 0x1ea7 },
+ { 0x1ea9, 0x1ea9 },
+ { 0x1eab, 0x1eab },
+ { 0x1ead, 0x1ead },
+ { 0x1eaf, 0x1eaf },
+ { 0x1eb1, 0x1eb1 },
+ { 0x1eb3, 0x1eb3 },
+ { 0x1eb5, 0x1eb5 },
+ { 0x1eb7, 0x1eb7 },
+ { 0x1eb9, 0x1eb9 },
+ { 0x1ebb, 0x1ebb },
+ { 0x1ebd, 0x1ebd },
+ { 0x1ebf, 0x1ebf },
+ { 0x1ec1, 0x1ec1 },
+ { 0x1ec3, 0x1ec3 },
+ { 0x1ec5, 0x1ec5 },
+ { 0x1ec7, 0x1ec7 },
+ { 0x1ec9, 0x1ec9 },
+ { 0x1ecb, 0x1ecb },
+ { 0x1ecd, 0x1ecd },
+ { 0x1ecf, 0x1ecf },
+ { 0x1ed1, 0x1ed1 },
+ { 0x1ed3, 0x1ed3 },
+ { 0x1ed5, 0x1ed5 },
+ { 0x1ed7, 0x1ed7 },
+ { 0x1ed9, 0x1ed9 },
+ { 0x1edb, 0x1edb },
+ { 0x1edd, 0x1edd },
+ { 0x1edf, 0x1edf },
+ { 0x1ee1, 0x1ee1 },
+ { 0x1ee3, 0x1ee3 },
+ { 0x1ee5, 0x1ee5 },
+ { 0x1ee7, 0x1ee7 },
+ { 0x1ee9, 0x1ee9 },
+ { 0x1eeb, 0x1eeb },
+ { 0x1eed, 0x1eed },
+ { 0x1eef, 0x1eef },
+ { 0x1ef1, 0x1ef1 },
+ { 0x1ef3, 0x1ef3 },
+ { 0x1ef5, 0x1ef5 },
+ { 0x1ef7, 0x1ef7 },
+ { 0x1ef9, 0x1ef9 },
+ { 0x1efb, 0x1efb },
+ { 0x1efd, 0x1efd },
+ { 0x1eff, 0x1f07 },
+ { 0x1f10, 0x1f15 },
+ { 0x1f20, 0x1f27 },
+ { 0x1f30, 0x1f37 },
+ { 0x1f40, 0x1f45 },
+ { 0x1f50, 0x1f57 },
+ { 0x1f60, 0x1f67 },
+ { 0x1f70, 0x1f7d },
+ { 0x1f80, 0x1f87 },
+ { 0x1f90, 0x1f97 },
+ { 0x1fa0, 0x1fa7 },
+ { 0x1fb0, 0x1fb4 },
+ { 0x1fb6, 0x1fb7 },
+ { 0x1fbe, 0x1fbe },
+ { 0x1fc2, 0x1fc4 },
+ { 0x1fc6, 0x1fc7 },
+ { 0x1fd0, 0x1fd3 },
+ { 0x1fd6, 0x1fd7 },
+ { 0x1fe0, 0x1fe7 },
+ { 0x1ff2, 0x1ff4 },
+ { 0x1ff6, 0x1ff7 },
+ { 0x210a, 0x210a },
+ { 0x210e, 0x210f },
+ { 0x2113, 0x2113 },
+ { 0x212f, 0x212f },
+ { 0x2134, 0x2134 },
+ { 0x2139, 0x2139 },
+ { 0x213c, 0x213d },
+ { 0x2146, 0x2149 },
+ { 0x214e, 0x214e },
+ { 0x2184, 0x2184 },
+ { 0x2c30, 0x2c5f },
+ { 0x2c61, 0x2c61 },
+ { 0x2c65, 0x2c66 },
+ { 0x2c68, 0x2c68 },
+ { 0x2c6a, 0x2c6a },
+ { 0x2c6c, 0x2c6c },
+ { 0x2c71, 0x2c71 },
+ { 0x2c73, 0x2c74 },
+ { 0x2c76, 0x2c7b },
+ { 0x2c81, 0x2c81 },
+ { 0x2c83, 0x2c83 },
+ { 0x2c85, 0x2c85 },
+ { 0x2c87, 0x2c87 },
+ { 0x2c89, 0x2c89 },
+ { 0x2c8b, 0x2c8b },
+ { 0x2c8d, 0x2c8d },
+ { 0x2c8f, 0x2c8f },
+ { 0x2c91, 0x2c91 },
+ { 0x2c93, 0x2c93 },
+ { 0x2c95, 0x2c95 },
+ { 0x2c97, 0x2c97 },
+ { 0x2c99, 0x2c99 },
+ { 0x2c9b, 0x2c9b },
+ { 0x2c9d, 0x2c9d },
+ { 0x2c9f, 0x2c9f },
+ { 0x2ca1, 0x2ca1 },
+ { 0x2ca3, 0x2ca3 },
+ { 0x2ca5, 0x2ca5 },
+ { 0x2ca7, 0x2ca7 },
+ { 0x2ca9, 0x2ca9 },
+ { 0x2cab, 0x2cab },
+ { 0x2cad, 0x2cad },
+ { 0x2caf, 0x2caf },
+ { 0x2cb1, 0x2cb1 },
+ { 0x2cb3, 0x2cb3 },
+ { 0x2cb5, 0x2cb5 },
+ { 0x2cb7, 0x2cb7 },
+ { 0x2cb9, 0x2cb9 },
+ { 0x2cbb, 0x2cbb },
+ { 0x2cbd, 0x2cbd },
+ { 0x2cbf, 0x2cbf },
+ { 0x2cc1, 0x2cc1 },
+ { 0x2cc3, 0x2cc3 },
+ { 0x2cc5, 0x2cc5 },
+ { 0x2cc7, 0x2cc7 },
+ { 0x2cc9, 0x2cc9 },
+ { 0x2ccb, 0x2ccb },
+ { 0x2ccd, 0x2ccd },
+ { 0x2ccf, 0x2ccf },
+ { 0x2cd1, 0x2cd1 },
+ { 0x2cd3, 0x2cd3 },
+ { 0x2cd5, 0x2cd5 },
+ { 0x2cd7, 0x2cd7 },
+ { 0x2cd9, 0x2cd9 },
+ { 0x2cdb, 0x2cdb },
+ { 0x2cdd, 0x2cdd },
+ { 0x2cdf, 0x2cdf },
+ { 0x2ce1, 0x2ce1 },
+ { 0x2ce3, 0x2ce4 },
+ { 0x2cec, 0x2cec },
+ { 0x2cee, 0x2cee },
+ { 0x2cf3, 0x2cf3 },
+ { 0x2d00, 0x2d25 },
+ { 0x2d27, 0x2d27 },
+ { 0x2d2d, 0x2d2d },
+ { 0xa641, 0xa641 },
+ { 0xa643, 0xa643 },
+ { 0xa645, 0xa645 },
+ { 0xa647, 0xa647 },
+ { 0xa649, 0xa649 },
+ { 0xa64b, 0xa64b },
+ { 0xa64d, 0xa64d },
+ { 0xa64f, 0xa64f },
+ { 0xa651, 0xa651 },
+ { 0xa653, 0xa653 },
+ { 0xa655, 0xa655 },
+ { 0xa657, 0xa657 },
+ { 0xa659, 0xa659 },
+ { 0xa65b, 0xa65b },
+ { 0xa65d, 0xa65d },
+ { 0xa65f, 0xa65f },
+ { 0xa661, 0xa661 },
+ { 0xa663, 0xa663 },
+ { 0xa665, 0xa665 },
+ { 0xa667, 0xa667 },
+ { 0xa669, 0xa669 },
+ { 0xa66b, 0xa66b },
+ { 0xa66d, 0xa66d },
+ { 0xa681, 0xa681 },
+ { 0xa683, 0xa683 },
+ { 0xa685, 0xa685 },
+ { 0xa687, 0xa687 },
+ { 0xa689, 0xa689 },
+ { 0xa68b, 0xa68b },
+ { 0xa68d, 0xa68d },
+ { 0xa68f, 0xa68f },
+ { 0xa691, 0xa691 },
+ { 0xa693, 0xa693 },
+ { 0xa695, 0xa695 },
+ { 0xa697, 0xa697 },
+ { 0xa699, 0xa699 },
+ { 0xa69b, 0xa69b },
+ { 0xa723, 0xa723 },
+ { 0xa725, 0xa725 },
+ { 0xa727, 0xa727 },
+ { 0xa729, 0xa729 },
+ { 0xa72b, 0xa72b },
+ { 0xa72d, 0xa72d },
+ { 0xa72f, 0xa731 },
+ { 0xa733, 0xa733 },
+ { 0xa735, 0xa735 },
+ { 0xa737, 0xa737 },
+ { 0xa739, 0xa739 },
+ { 0xa73b, 0xa73b },
+ { 0xa73d, 0xa73d },
+ { 0xa73f, 0xa73f },
+ { 0xa741, 0xa741 },
+ { 0xa743, 0xa743 },
+ { 0xa745, 0xa745 },
+ { 0xa747, 0xa747 },
+ { 0xa749, 0xa749 },
+ { 0xa74b, 0xa74b },
+ { 0xa74d, 0xa74d },
+ { 0xa74f, 0xa74f },
+ { 0xa751, 0xa751 },
+ { 0xa753, 0xa753 },
+ { 0xa755, 0xa755 },
+ { 0xa757, 0xa757 },
+ { 0xa759, 0xa759 },
+ { 0xa75b, 0xa75b },
+ { 0xa75d, 0xa75d },
+ { 0xa75f, 0xa75f },
+ { 0xa761, 0xa761 },
+ { 0xa763, 0xa763 },
+ { 0xa765, 0xa765 },
+ { 0xa767, 0xa767 },
+ { 0xa769, 0xa769 },
+ { 0xa76b, 0xa76b },
+ { 0xa76d, 0xa76d },
+ { 0xa76f, 0xa76f },
+ { 0xa771, 0xa778 },
+ { 0xa77a, 0xa77a },
+ { 0xa77c, 0xa77c },
+ { 0xa77f, 0xa77f },
+ { 0xa781, 0xa781 },
+ { 0xa783, 0xa783 },
+ { 0xa785, 0xa785 },
+ { 0xa787, 0xa787 },
+ { 0xa78c, 0xa78c },
+ { 0xa78e, 0xa78e },
+ { 0xa791, 0xa791 },
+ { 0xa793, 0xa795 },
+ { 0xa797, 0xa797 },
+ { 0xa799, 0xa799 },
+ { 0xa79b, 0xa79b },
+ { 0xa79d, 0xa79d },
+ { 0xa79f, 0xa79f },
+ { 0xa7a1, 0xa7a1 },
+ { 0xa7a3, 0xa7a3 },
+ { 0xa7a5, 0xa7a5 },
+ { 0xa7a7, 0xa7a7 },
+ { 0xa7a9, 0xa7a9 },
+ { 0xa7af, 0xa7af },
+ { 0xa7b5, 0xa7b5 },
+ { 0xa7b7, 0xa7b7 },
+ { 0xa7b9, 0xa7b9 },
+ { 0xa7bb, 0xa7bb },
+ { 0xa7bd, 0xa7bd },
+ { 0xa7bf, 0xa7bf },
+ { 0xa7c1, 0xa7c1 },
+ { 0xa7c3, 0xa7c3 },
+ { 0xa7c8, 0xa7c8 },
+ { 0xa7ca, 0xa7ca },
+ { 0xa7d1, 0xa7d1 },
+ { 0xa7d3, 0xa7d3 },
+ { 0xa7d5, 0xa7d5 },
+ { 0xa7d7, 0xa7d7 },
+ { 0xa7d9, 0xa7d9 },
+ { 0xa7f6, 0xa7f6 },
+ { 0xa7fa, 0xa7fa },
+ { 0xab30, 0xab5a },
+ { 0xab60, 0xab68 },
+ { 0xab70, 0xabbf },
+ { 0xfb00, 0xfb06 },
+ { 0xfb13, 0xfb17 },
+ { 0xff41, 0xff5a },
+ { 0x10428, 0x1044f },
+ { 0x104d8, 0x104fb },
+ { 0x10597, 0x105a1 },
+ { 0x105a3, 0x105b1 },
+ { 0x105b3, 0x105b9 },
+ { 0x105bb, 0x105bc },
+ { 0x10cc0, 0x10cf2 },
+ { 0x118c0, 0x118df },
+ { 0x16e60, 0x16e7f },
+ { 0x1d41a, 0x1d433 },
+ { 0x1d44e, 0x1d454 },
+ { 0x1d456, 0x1d467 },
+ { 0x1d482, 0x1d49b },
+ { 0x1d4b6, 0x1d4b9 },
+ { 0x1d4bb, 0x1d4bb },
+ { 0x1d4bd, 0x1d4c3 },
+ { 0x1d4c5, 0x1d4cf },
+ { 0x1d4ea, 0x1d503 },
+ { 0x1d51e, 0x1d537 },
+ { 0x1d552, 0x1d56b },
+ { 0x1d586, 0x1d59f },
+ { 0x1d5ba, 0x1d5d3 },
+ { 0x1d5ee, 0x1d607 },
+ { 0x1d622, 0x1d63b },
+ { 0x1d656, 0x1d66f },
+ { 0x1d68a, 0x1d6a5 },
+ { 0x1d6c2, 0x1d6da },
+ { 0x1d6dc, 0x1d6e1 },
+ { 0x1d6fc, 0x1d714 },
+ { 0x1d716, 0x1d71b },
+ { 0x1d736, 0x1d74e },
+ { 0x1d750, 0x1d755 },
+ { 0x1d770, 0x1d788 },
+ { 0x1d78a, 0x1d78f },
+ { 0x1d7aa, 0x1d7c2 },
+ { 0x1d7c4, 0x1d7c9 },
+ { 0x1d7cb, 0x1d7cb },
+ { 0x1df00, 0x1df09 },
+ { 0x1df0b, 0x1df1e },
+ { 0x1df25, 0x1df2a },
+ { 0x1e922, 0x1e943 },
};
#endif // CHAR_RANGE_INC
diff --git a/core/string/char_utils.h b/core/string/char_utils.h
index 4ff8fb7320..aa9bc198ca 100644
--- a/core/string/char_utils.h
+++ b/core/string/char_utils.h
@@ -35,24 +35,43 @@
#include "char_range.inc"
+#define BSEARCH_CHAR_RANGE(m_array) \
+ int low = 0; \
+ int high = sizeof(m_array) / sizeof(m_array[0]) - 1; \
+ int middle; \
+ \
+ while (low <= high) { \
+ middle = (low + high) / 2; \
+ \
+ if (c < m_array[middle].start) { \
+ high = middle - 1; \
+ } else if (c > m_array[middle].end) { \
+ low = middle + 1; \
+ } else { \
+ return true; \
+ } \
+ } \
+ \
+ return false
+
static _FORCE_INLINE_ bool is_unicode_identifier_start(char32_t c) {
- for (int i = 0; xid_start[i].start != 0; i++) {
- if (c >= xid_start[i].start && c <= xid_start[i].end) {
- return true;
- }
- }
- return false;
+ BSEARCH_CHAR_RANGE(xid_start);
}
static _FORCE_INLINE_ bool is_unicode_identifier_continue(char32_t c) {
- for (int i = 0; xid_continue[i].start != 0; i++) {
- if (c >= xid_continue[i].start && c <= xid_continue[i].end) {
- return true;
- }
- }
- return false;
+ BSEARCH_CHAR_RANGE(xid_continue);
+}
+
+static _FORCE_INLINE_ bool is_unicode_upper_case(char32_t c) {
+ BSEARCH_CHAR_RANGE(uppercase_letter);
}
+static _FORCE_INLINE_ bool is_unicode_lower_case(char32_t c) {
+ BSEARCH_CHAR_RANGE(lowercase_letter);
+}
+
+#undef BSEARCH_CHAR_RANGE
+
static _FORCE_INLINE_ bool is_ascii_upper_case(char32_t c) {
return (c >= 'A' && c <= 'Z');
}
diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp
index 32e4564c5e..8ae2efb787 100644
--- a/core/string/node_path.cpp
+++ b/core/string/node_path.cpp
@@ -92,6 +92,14 @@ StringName NodePath::get_subname(int p_idx) const {
return data->subpath[p_idx];
}
+int NodePath::get_total_name_count() const {
+ if (!data) {
+ return 0;
+ }
+
+ return data->path.size() + data->subpath.size();
+}
+
void NodePath::unref() {
if (data && data->refcount.unref()) {
memdelete(data);
@@ -229,6 +237,27 @@ StringName NodePath::get_concatenated_subnames() const {
return data->concatenated_subpath;
}
+NodePath NodePath::slice(int p_begin, int p_end) const {
+ const int name_count = get_name_count();
+ const int total_count = get_total_name_count();
+
+ int begin = CLAMP(p_begin, -total_count, total_count);
+ if (begin < 0) {
+ begin += total_count;
+ }
+ int end = CLAMP(p_end, -total_count, total_count);
+ if (end < 0) {
+ end += total_count;
+ }
+ const int sub_begin = MAX(begin - name_count - 1, 0);
+ const int sub_end = MAX(end - name_count, 0);
+
+ const Vector<StringName> names = get_names().slice(begin, end);
+ const Vector<StringName> sub_names = get_subnames().slice(sub_begin, sub_end);
+ const bool absolute = is_absolute() && (begin == 0);
+ return NodePath(names, sub_names, absolute);
+}
+
NodePath NodePath::rel_path_to(const NodePath &p_np) const {
ERR_FAIL_COND_V(!is_absolute(), NodePath());
ERR_FAIL_COND_V(!p_np.is_absolute(), NodePath());
@@ -331,7 +360,7 @@ NodePath NodePath::simplified() const {
}
NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
- if (p_path.size() == 0) {
+ if (p_path.size() == 0 && !p_absolute) {
return;
}
@@ -343,7 +372,7 @@ NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
}
NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) {
- if (p_path.size() == 0 && p_subpath.size() == 0) {
+ if (p_path.size() == 0 && p_subpath.size() == 0 && !p_absolute) {
return;
}
diff --git a/core/string/node_path.h b/core/string/node_path.h
index 876d69924e..56799839d7 100644
--- a/core/string/node_path.h
+++ b/core/string/node_path.h
@@ -57,10 +57,12 @@ public:
StringName get_name(int p_idx) const;
int get_subname_count() const;
StringName get_subname(int p_idx) const;
+ int get_total_name_count() const;
Vector<StringName> get_names() const;
Vector<StringName> get_subnames() const;
StringName get_concatenated_names() const;
StringName get_concatenated_subnames() const;
+ NodePath slice(int p_begin, int p_end = INT_MAX) const;
NodePath rel_path_to(const NodePath &p_np) const;
NodePath get_as_property_path() const;
diff --git a/core/string/translation.compat.inc b/core/string/translation.compat.inc
new file mode 100644
index 0000000000..d792d4a6fc
--- /dev/null
+++ b/core/string/translation.compat.inc
@@ -0,0 +1,46 @@
+/**************************************************************************/
+/* translation.compat.inc */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef DISABLE_DEPRECATED
+
+void Translation::_bind_compatibility_methods() {
+ ClassDB::bind_compatibility_method(D_METHOD("add_message", "src_message", "xlated_message", "context"), &Translation::add_message, DEFVAL(""));
+ ClassDB::bind_compatibility_method(D_METHOD("add_plural_message", "src_message", "xlated_messages", "context"), &Translation::add_plural_message, DEFVAL(""));
+ ClassDB::bind_compatibility_method(D_METHOD("get_message", "src_message", "context"), &Translation::get_message, DEFVAL(""));
+ ClassDB::bind_compatibility_method(D_METHOD("get_plural_message", "src_message", "src_plural_message", "n", "context"), &Translation::get_plural_message, DEFVAL(""));
+ ClassDB::bind_compatibility_method(D_METHOD("erase_message", "src_message", "context"), &Translation::erase_message, DEFVAL(""));
+}
+
+void TranslationServer::_bind_compatibility_methods() {
+ ClassDB::bind_compatibility_method(D_METHOD("translate", "message", "context"), &TranslationServer::translate, DEFVAL(""));
+ ClassDB::bind_compatibility_method(D_METHOD("translate_plural", "message", "plural_message", "n", "context"), &TranslationServer::translate_plural, DEFVAL(""));
+}
+
+#endif
diff --git a/core/string/translation.cpp b/core/string/translation.cpp
index 829c9bf777..0a0052d6cb 100644
--- a/core/string/translation.cpp
+++ b/core/string/translation.cpp
@@ -29,6 +29,7 @@
/**************************************************************************/
#include "translation.h"
+#include "translation.compat.inc"
#include "core/config/project_settings.h"
#include "core/io/resource_loader.h"
@@ -155,11 +156,11 @@ int Translation::get_message_count() const {
void Translation::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_locale", "locale"), &Translation::set_locale);
ClassDB::bind_method(D_METHOD("get_locale"), &Translation::get_locale);
- ClassDB::bind_method(D_METHOD("add_message", "src_message", "xlated_message", "context"), &Translation::add_message, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("add_plural_message", "src_message", "xlated_messages", "context"), &Translation::add_plural_message, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("get_message", "src_message", "context"), &Translation::get_message, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("get_plural_message", "src_message", "src_plural_message", "n", "context"), &Translation::get_plural_message, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("erase_message", "src_message", "context"), &Translation::erase_message, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("add_message", "src_message", "xlated_message", "context"), &Translation::add_message, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("add_plural_message", "src_message", "xlated_messages", "context"), &Translation::add_plural_message, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("get_message", "src_message", "context"), &Translation::get_message, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("get_plural_message", "src_message", "src_plural_message", "n", "context"), &Translation::get_plural_message, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("erase_message", "src_message", "context"), &Translation::erase_message, DEFVAL(StringName()));
ClassDB::bind_method(D_METHOD("get_message_list"), &Translation::_get_message_list);
ClassDB::bind_method(D_METHOD("get_translated_message_list"), &Translation::get_translated_message_list);
ClassDB::bind_method(D_METHOD("get_message_count"), &Translation::get_message_count);
@@ -771,6 +772,20 @@ StringName TranslationServer::tool_translate_plural(const StringName &p_message,
return p_message_plural;
}
+void TranslationServer::set_property_translation(const Ref<Translation> &p_translation) {
+ property_translation = p_translation;
+}
+
+StringName TranslationServer::property_translate(const StringName &p_message) const {
+ if (property_translation.is_valid()) {
+ StringName r = property_translation->get_message(p_message);
+ if (r) {
+ return r;
+ }
+ }
+ return p_message;
+}
+
void TranslationServer::set_doc_translation(const Ref<Translation> &p_translation) {
doc_translation = p_translation;
}
@@ -799,13 +814,13 @@ StringName TranslationServer::doc_translate_plural(const StringName &p_message,
return p_message_plural;
}
-void TranslationServer::set_property_translation(const Ref<Translation> &p_translation) {
- property_translation = p_translation;
+void TranslationServer::set_extractable_translation(const Ref<Translation> &p_translation) {
+ extractable_translation = p_translation;
}
-StringName TranslationServer::property_translate(const StringName &p_message) const {
- if (property_translation.is_valid()) {
- StringName r = property_translation->get_message(p_message);
+StringName TranslationServer::extractable_translate(const StringName &p_message, const StringName &p_context) const {
+ if (extractable_translation.is_valid()) {
+ StringName r = extractable_translation->get_message(p_message, p_context);
if (r) {
return r;
}
@@ -813,6 +828,20 @@ StringName TranslationServer::property_translate(const StringName &p_message) co
return p_message;
}
+StringName TranslationServer::extractable_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
+ if (extractable_translation.is_valid()) {
+ StringName r = extractable_translation->get_plural_message(p_message, p_message_plural, p_n, p_context);
+ if (r) {
+ return r;
+ }
+ }
+
+ if (p_n == 1) {
+ return p_message;
+ }
+ return p_message_plural;
+}
+
bool TranslationServer::is_pseudolocalization_enabled() const {
return pseudolocalization_enabled;
}
@@ -983,6 +1012,29 @@ bool TranslationServer::is_placeholder(String &p_message, int p_index) const {
p_message[p_index + 1] == 'o' || p_message[p_index + 1] == 'x' || p_message[p_index + 1] == 'X' || p_message[p_index + 1] == 'f');
}
+#ifdef TOOLS_ENABLED
+void TranslationServer::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+ const String pf = p_function;
+ if (p_idx == 0) {
+ HashMap<String, String> *target_hash_map = nullptr;
+ if (pf == "get_language_name") {
+ target_hash_map = &language_map;
+ } else if (pf == "get_script_name") {
+ target_hash_map = &script_map;
+ } else if (pf == "get_country_name") {
+ target_hash_map = &country_name_map;
+ }
+
+ if (target_hash_map) {
+ for (const KeyValue<String, String> &E : *target_hash_map) {
+ r_options->push_back(E.key.quote());
+ }
+ }
+ }
+ Object::get_argument_options(p_function, p_idx, r_options);
+}
+#endif // TOOLS_ENABLED
+
void TranslationServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_locale", "locale"), &TranslationServer::set_locale);
ClassDB::bind_method(D_METHOD("get_locale"), &TranslationServer::get_locale);
@@ -1002,8 +1054,8 @@ void TranslationServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_locale_name", "locale"), &TranslationServer::get_locale_name);
- ClassDB::bind_method(D_METHOD("translate", "message", "context"), &TranslationServer::translate, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("translate_plural", "message", "plural_message", "n", "context"), &TranslationServer::translate_plural, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("translate", "message", "context"), &TranslationServer::translate, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("translate_plural", "message", "plural_message", "n", "context"), &TranslationServer::translate_plural, DEFVAL(StringName()));
ClassDB::bind_method(D_METHOD("add_translation", "translation"), &TranslationServer::add_translation);
ClassDB::bind_method(D_METHOD("remove_translation", "translation"), &TranslationServer::remove_translation);
diff --git a/core/string/translation.h b/core/string/translation.h
index 3f9dbcc476..470ba88232 100644
--- a/core/string/translation.h
+++ b/core/string/translation.h
@@ -51,6 +51,10 @@ class Translation : public Resource {
protected:
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ static void _bind_compatibility_methods();
+#endif
+
GDVIRTUAL2RC(StringName, _get_message, StringName, StringName);
GDVIRTUAL4RC(StringName, _get_plural_message, StringName, StringName, int, StringName);
@@ -78,8 +82,9 @@ class TranslationServer : public Object {
HashSet<Ref<Translation>> translations;
Ref<Translation> tool_translation;
- Ref<Translation> doc_translation;
Ref<Translation> property_translation;
+ Ref<Translation> doc_translation;
+ Ref<Translation> extractable_translation;
bool enabled = true;
@@ -111,6 +116,10 @@ class TranslationServer : public Object {
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ static void _bind_compatibility_methods();
+#endif
+
struct LocaleScriptInfo {
String name;
String script;
@@ -173,11 +182,14 @@ public:
Ref<Translation> get_tool_translation() const;
StringName tool_translate(const StringName &p_message, const StringName &p_context = "") const;
StringName tool_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
+ void set_property_translation(const Ref<Translation> &p_translation);
+ StringName property_translate(const StringName &p_message) const;
void set_doc_translation(const Ref<Translation> &p_translation);
StringName doc_translate(const StringName &p_message, const StringName &p_context = "") const;
StringName doc_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
- void set_property_translation(const Ref<Translation> &p_translation);
- StringName property_translate(const StringName &p_message) const;
+ void set_extractable_translation(const Ref<Translation> &p_translation);
+ StringName extractable_translate(const StringName &p_message, const StringName &p_context = "") const;
+ StringName extractable_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
void setup();
@@ -185,6 +197,10 @@ public:
void load_translations();
+#ifdef TOOLS_ENABLED
+ virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
+#endif // TOOLS_ENABLED
+
TranslationServer();
};
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 67b0fdee20..f4b00255a1 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -1044,17 +1044,17 @@ String String::_camelcase_to_underscore() const {
int start_index = 0;
for (int i = 1; i < size(); i++) {
- bool is_prev_upper = is_ascii_upper_case(cstr[i - 1]);
- bool is_prev_lower = is_ascii_lower_case(cstr[i - 1]);
+ bool is_prev_upper = is_unicode_upper_case(cstr[i - 1]);
+ bool is_prev_lower = is_unicode_lower_case(cstr[i - 1]);
bool is_prev_digit = is_digit(cstr[i - 1]);
- bool is_curr_upper = is_ascii_upper_case(cstr[i]);
- bool is_curr_lower = is_ascii_lower_case(cstr[i]);
+ bool is_curr_upper = is_unicode_upper_case(cstr[i]);
+ bool is_curr_lower = is_unicode_lower_case(cstr[i]);
bool is_curr_digit = is_digit(cstr[i]);
bool is_next_lower = false;
if (i + 1 < size()) {
- is_next_lower = is_ascii_lower_case(cstr[i + 1]);
+ is_next_lower = is_unicode_lower_case(cstr[i + 1]);
}
const bool cond_a = is_prev_lower && is_curr_upper; // aA
@@ -1536,7 +1536,7 @@ String String::num(double p_num, int p_decimals) {
fmt[5] = 'f';
fmt[6] = 0;
}
- // if we want to convert a double with as much decimal places as as
+ // if we want to convert a double with as much decimal places as
// DBL_MAX or DBL_MIN then we would theoretically need a buffer of at least
// DBL_MAX_10_EXP + 2 for DBL_MAX and DBL_MAX_10_EXP + 4 for DBL_MIN.
// BUT those values where still giving me exceptions, so I tested from
@@ -5391,9 +5391,7 @@ String DTRN(const String &p_text, const String &p_text_plural, int p_n, const St
/**
* "Run-time TRanslate". Performs string replacement for internationalization
- * within a running project. The translation string must be supplied by the
- * project, as Godot does not provide built-in translations for `RTR()` strings
- * to keep binary size low. A translation context can optionally be specified to
+ * without the editor. A translation context can optionally be specified to
* disambiguate between identical source strings in translations. When
* placeholders are desired, use `vformat(RTR("Example: %s"), some_string)`.
* If a string mentions a quantity (and may therefore need a dynamic plural form),
@@ -5407,9 +5405,8 @@ String RTR(const String &p_text, const String &p_context) {
String rtr = TranslationServer::get_singleton()->tool_translate(p_text, p_context);
if (rtr.is_empty() || rtr == p_text) {
return TranslationServer::get_singleton()->translate(p_text, p_context);
- } else {
- return rtr;
}
+ return rtr;
}
return p_text;
@@ -5417,13 +5414,10 @@ String RTR(const String &p_text, const String &p_context) {
/**
* "Run-time TRanslate for N items". Performs string replacement for
- * internationalization within a running project. The translation string must be
- * supplied by the project, as Godot does not provide built-in translations for
- * `RTRN()` strings to keep binary size low. A translation context can
- * optionally be specified to disambiguate between identical source strings in
- * translations. Use `RTR()` if the string doesn't need dynamic plural form.
- * When placeholders are desired, use
- * `vformat(RTRN("%d item", "%d items", some_integer), some_integer)`.
+ * internationalization without the editor. A translation context can optionally
+ * be specified to disambiguate between identical source strings in translations.
+ * Use `RTR()` if the string doesn't need dynamic plural form. When placeholders
+ * are desired, use `vformat(RTRN("%d item", "%d items", some_integer), some_integer)`.
* The placeholder must be present in both strings to avoid run-time warnings in `vformat()`.
*
* NOTE: Do not use `RTRN()` in editor-only code (typically within the `editor/`
@@ -5434,9 +5428,8 @@ String RTRN(const String &p_text, const String &p_text_plural, int p_n, const St
String rtr = TranslationServer::get_singleton()->tool_translate_plural(p_text, p_text_plural, p_n, p_context);
if (rtr.is_empty() || rtr == p_text || rtr == p_text_plural) {
return TranslationServer::get_singleton()->translate_plural(p_text, p_text_plural, p_n, p_context);
- } else {
- return rtr;
}
+ return rtr;
}
// Return message based on English plural rule if translation is not possible.
diff --git a/core/string/ustring.h b/core/string/ustring.h
index b1348ceb48..468a015302 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -556,6 +556,43 @@ String DTRN(const String &p_text, const String &p_text_plural, int p_n, const St
String RTR(const String &p_text, const String &p_context = "");
String RTRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context = "");
+/**
+ * "Extractable TRanslate". Used for strings that can appear inside an exported
+ * project (such as the ones in nodes like `FileDialog`), which are made possible
+ * to add in the POT generator. A translation context can optionally be specified
+ * to disambiguate between identical source strings in translations.
+ * When placeholders are desired, use vformat(ETR("Example: %s"), some_string)`.
+ * If a string mentions a quantity (and may therefore need a dynamic plural form),
+ * use `ETRN()` instead of `ETR()`.
+ *
+ * NOTE: This function is for string extraction only, and will just return the
+ * string it was given. The translation itself should be done internally by nodes
+ * with `atr()` instead.
+ */
+_FORCE_INLINE_ String ETR(const String &p_text, const String &p_context = "") {
+ return p_text;
+}
+
+/**
+ * "Extractable TRanslate for N items". Used for strings that can appear inside an
+ * exported project (such as the ones in nodes like `FileDialog`), which are made
+ * possible to add in the POT generator. A translation context can optionally be
+ * specified to disambiguate between identical source strings in translations.
+ * Use `ETR()` if the string doesn't need dynamic plural form. When placeholders
+ * are desired, use `vformat(ETRN("%d item", "%d items", some_integer), some_integer)`.
+ * The placeholder must be present in both strings to avoid run-time warnings in `vformat()`.
+ *
+ * NOTE: This function is for string extraction only, and will just return the
+ * string it was given. The translation itself should be done internally by nodes
+ * with `atr()` instead.
+ */
+_FORCE_INLINE_ String ETRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context = "") {
+ if (p_n == 1) {
+ return p_text;
+ }
+ return p_text_plural;
+}
+
bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end);
_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr) {
diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h
index e6c62ebf43..f92e0f4162 100644
--- a/core/templates/rid_owner.h
+++ b/core/templates/rid_owner.h
@@ -270,7 +270,7 @@ public:
if (THREAD_SAFE) {
spin_lock.unlock();
}
- ERR_FAIL_MSG("Attempted to free an uninitialized or invalid RID");
+ ERR_FAIL_MSG("Attempted to free an uninitialized or invalid RID.");
} else if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) {
if (THREAD_SAFE) {
spin_lock.unlock();
diff --git a/core/templates/search_array.h b/core/templates/search_array.h
index f537ef67fd..9c3f527323 100644
--- a/core/templates/search_array.h
+++ b/core/templates/search_array.h
@@ -38,12 +38,12 @@ class SearchArray {
public:
Comparator compare;
- inline int bisect(const T *p_array, int p_len, const T &p_value, bool p_before) const {
- int lo = 0;
- int hi = p_len;
+ inline int64_t bisect(const T *p_array, int64_t p_len, const T &p_value, bool p_before) const {
+ int64_t lo = 0;
+ int64_t hi = p_len;
if (p_before) {
while (lo < hi) {
- const int mid = (lo + hi) / 2;
+ const int64_t mid = (lo + hi) / 2;
if (compare(p_array[mid], p_value)) {
lo = mid + 1;
} else {
@@ -52,7 +52,7 @@ public:
}
} else {
while (lo < hi) {
- const int mid = (lo + hi) / 2;
+ const int64_t mid = (lo + hi) / 2;
if (compare(p_value, p_array[mid])) {
hi = mid;
} else {
diff --git a/core/templates/sort_array.h b/core/templates/sort_array.h
index fbe2a89a84..45aeaf1579 100644
--- a/core/templates/sort_array.h
+++ b/core/templates/sort_array.h
@@ -78,8 +78,8 @@ public:
}
}
- inline int bitlog(int n) const {
- int k;
+ inline int64_t bitlog(int64_t n) const {
+ int64_t k;
for (k = 0; n != 1; n >>= 1) {
++k;
}
@@ -88,8 +88,8 @@ public:
/* Heap / Heapsort functions */
- inline void push_heap(int p_first, int p_hole_idx, int p_top_index, T p_value, T *p_array) const {
- int parent = (p_hole_idx - 1) / 2;
+ inline void push_heap(int64_t p_first, int64_t p_hole_idx, int64_t p_top_index, T p_value, T *p_array) const {
+ int64_t parent = (p_hole_idx - 1) / 2;
while (p_hole_idx > p_top_index && compare(p_array[p_first + parent], p_value)) {
p_array[p_first + p_hole_idx] = p_array[p_first + parent];
p_hole_idx = parent;
@@ -98,17 +98,17 @@ public:
p_array[p_first + p_hole_idx] = p_value;
}
- inline void pop_heap(int p_first, int p_last, int p_result, T p_value, T *p_array) const {
+ inline void pop_heap(int64_t p_first, int64_t p_last, int64_t p_result, T p_value, T *p_array) const {
p_array[p_result] = p_array[p_first];
adjust_heap(p_first, 0, p_last - p_first, p_value, p_array);
}
- inline void pop_heap(int p_first, int p_last, T *p_array) const {
+ inline void pop_heap(int64_t p_first, int64_t p_last, T *p_array) const {
pop_heap(p_first, p_last - 1, p_last - 1, p_array[p_last - 1], p_array);
}
- inline void adjust_heap(int p_first, int p_hole_idx, int p_len, T p_value, T *p_array) const {
- int top_index = p_hole_idx;
- int second_child = 2 * p_hole_idx + 2;
+ inline void adjust_heap(int64_t p_first, int64_t p_hole_idx, int64_t p_len, T p_value, T *p_array) const {
+ int64_t top_index = p_hole_idx;
+ int64_t second_child = 2 * p_hole_idx + 2;
while (second_child < p_len) {
if (compare(p_array[p_first + second_child], p_array[p_first + (second_child - 1)])) {
@@ -127,18 +127,18 @@ public:
push_heap(p_first, p_hole_idx, top_index, p_value, p_array);
}
- inline void sort_heap(int p_first, int p_last, T *p_array) const {
+ inline void sort_heap(int64_t p_first, int64_t p_last, T *p_array) const {
while (p_last - p_first > 1) {
pop_heap(p_first, p_last--, p_array);
}
}
- inline void make_heap(int p_first, int p_last, T *p_array) const {
+ inline void make_heap(int64_t p_first, int64_t p_last, T *p_array) const {
if (p_last - p_first < 2) {
return;
}
- int len = p_last - p_first;
- int parent = (len - 2) / 2;
+ int64_t len = p_last - p_first;
+ int64_t parent = (len - 2) / 2;
while (true) {
adjust_heap(p_first, parent, len, p_array[p_first + parent], p_array);
@@ -149,9 +149,9 @@ public:
}
}
- inline void partial_sort(int p_first, int p_last, int p_middle, T *p_array) const {
+ inline void partial_sort(int64_t p_first, int64_t p_last, int64_t p_middle, T *p_array) const {
make_heap(p_first, p_middle, p_array);
- for (int i = p_middle; i < p_last; i++) {
+ for (int64_t i = p_middle; i < p_last; i++) {
if (compare(p_array[i], p_array[p_first])) {
pop_heap(p_first, p_middle, i, p_array[i], p_array);
}
@@ -159,18 +159,18 @@ public:
sort_heap(p_first, p_middle, p_array);
}
- inline void partial_select(int p_first, int p_last, int p_middle, T *p_array) const {
+ inline void partial_select(int64_t p_first, int64_t p_last, int64_t p_middle, T *p_array) const {
make_heap(p_first, p_middle, p_array);
- for (int i = p_middle; i < p_last; i++) {
+ for (int64_t i = p_middle; i < p_last; i++) {
if (compare(p_array[i], p_array[p_first])) {
pop_heap(p_first, p_middle, i, p_array[i], p_array);
}
}
}
- inline int partitioner(int p_first, int p_last, T p_pivot, T *p_array) const {
- const int unmodified_first = p_first;
- const int unmodified_last = p_last;
+ inline int64_t partitioner(int64_t p_first, int64_t p_last, T p_pivot, T *p_array) const {
+ const int64_t unmodified_first = p_first;
+ const int64_t unmodified_last = p_last;
while (true) {
while (compare(p_array[p_first], p_pivot)) {
@@ -196,7 +196,7 @@ public:
}
}
- inline void introsort(int p_first, int p_last, T *p_array, int p_max_depth) const {
+ inline void introsort(int64_t p_first, int64_t p_last, T *p_array, int64_t p_max_depth) const {
while (p_last - p_first > INTROSORT_THRESHOLD) {
if (p_max_depth == 0) {
partial_sort(p_first, p_last, p_last, p_array);
@@ -205,7 +205,7 @@ public:
p_max_depth--;
- int cut = partitioner(
+ int64_t cut = partitioner(
p_first,
p_last,
median_of_3(
@@ -219,7 +219,7 @@ public:
}
}
- inline void introselect(int p_first, int p_nth, int p_last, T *p_array, int p_max_depth) const {
+ inline void introselect(int64_t p_first, int64_t p_nth, int64_t p_last, T *p_array, int64_t p_max_depth) const {
while (p_last - p_first > 3) {
if (p_max_depth == 0) {
partial_select(p_first, p_nth + 1, p_last, p_array);
@@ -229,7 +229,7 @@ public:
p_max_depth--;
- int cut = partitioner(
+ int64_t cut = partitioner(
p_first,
p_last,
median_of_3(
@@ -248,8 +248,8 @@ public:
insertion_sort(p_first, p_last, p_array);
}
- inline void unguarded_linear_insert(int p_last, T p_value, T *p_array) const {
- int next = p_last - 1;
+ inline void unguarded_linear_insert(int64_t p_last, T p_value, T *p_array) const {
+ int64_t next = p_last - 1;
while (compare(p_value, p_array[next])) {
if (Validate) {
ERR_BAD_COMPARE(next == 0);
@@ -261,10 +261,10 @@ public:
p_array[p_last] = p_value;
}
- inline void linear_insert(int p_first, int p_last, T *p_array) const {
+ inline void linear_insert(int64_t p_first, int64_t p_last, T *p_array) const {
T val = p_array[p_last];
if (compare(val, p_array[p_first])) {
- for (int i = p_last; i > p_first; i--) {
+ for (int64_t i = p_last; i > p_first; i--) {
p_array[i] = p_array[i - 1];
}
@@ -274,22 +274,22 @@ public:
}
}
- inline void insertion_sort(int p_first, int p_last, T *p_array) const {
+ inline void insertion_sort(int64_t p_first, int64_t p_last, T *p_array) const {
if (p_first == p_last) {
return;
}
- for (int i = p_first + 1; i != p_last; i++) {
+ for (int64_t i = p_first + 1; i != p_last; i++) {
linear_insert(p_first, i, p_array);
}
}
- inline void unguarded_insertion_sort(int p_first, int p_last, T *p_array) const {
- for (int i = p_first; i != p_last; i++) {
+ inline void unguarded_insertion_sort(int64_t p_first, int64_t p_last, T *p_array) const {
+ for (int64_t i = p_first; i != p_last; i++) {
unguarded_linear_insert(i, p_array[i], p_array);
}
}
- inline void final_insertion_sort(int p_first, int p_last, T *p_array) const {
+ inline void final_insertion_sort(int64_t p_first, int64_t p_last, T *p_array) const {
if (p_last - p_first > INTROSORT_THRESHOLD) {
insertion_sort(p_first, p_first + INTROSORT_THRESHOLD, p_array);
unguarded_insertion_sort(p_first + INTROSORT_THRESHOLD, p_last, p_array);
@@ -298,18 +298,18 @@ public:
}
}
- inline void sort_range(int p_first, int p_last, T *p_array) const {
+ inline void sort_range(int64_t p_first, int64_t p_last, T *p_array) const {
if (p_first != p_last) {
introsort(p_first, p_last, p_array, bitlog(p_last - p_first) * 2);
final_insertion_sort(p_first, p_last, p_array);
}
}
- inline void sort(T *p_array, int p_len) const {
+ inline void sort(T *p_array, int64_t p_len) const {
sort_range(0, p_len, p_array);
}
- inline void nth_element(int p_first, int p_last, int p_nth, T *p_array) const {
+ inline void nth_element(int64_t p_first, int64_t p_last, int64_t p_nth, T *p_array) const {
if (p_first == p_last || p_nth == p_last) {
return;
}
diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp
index 55f687bdf9..6bad6f5a5b 100644
--- a/core/variant/callable.cpp
+++ b/core/variant/callable.cpp
@@ -30,10 +30,11 @@
#include "callable.h"
-#include "callable_bind.h"
#include "core/object/object.h"
#include "core/object/ref_counted.h"
#include "core/object/script_language.h"
+#include "core/variant/callable_bind.h"
+#include "core/variant/variant_callable.h"
void Callable::call_deferredp(const Variant **p_arguments, int p_argcount) const {
MessageQueue::get_singleton()->push_callablep(*this, p_arguments, p_argcount, true);
@@ -327,14 +328,27 @@ Callable::operator String() const {
}
}
+Callable Callable::create(const Variant &p_variant, const StringName &p_method) {
+ ERR_FAIL_COND_V_MSG(p_method == StringName(), Callable(), "Method argument to Callable::create method must be a non-empty string.");
+
+ switch (p_variant.get_type()) {
+ case Variant::NIL:
+ return Callable(ObjectID(), p_method);
+ case Variant::OBJECT:
+ return Callable(p_variant.operator ObjectID(), p_method);
+ default:
+ return Callable(memnew(VariantCallable(p_variant, p_method)));
+ }
+}
+
Callable::Callable(const Object *p_object, const StringName &p_method) {
- if (p_method == StringName()) {
+ if (unlikely(p_method == StringName())) {
object = 0;
- ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string");
+ ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string.");
}
- if (p_object == nullptr) {
+ if (unlikely(p_object == nullptr)) {
object = 0;
- ERR_FAIL_MSG("Object argument to Callable constructor must be non-null");
+ ERR_FAIL_MSG("Object argument to Callable constructor must be non-null.");
}
object = p_object->get_instance_id();
@@ -342,9 +356,9 @@ Callable::Callable(const Object *p_object, const StringName &p_method) {
}
Callable::Callable(ObjectID p_object, const StringName &p_method) {
- if (p_method == StringName()) {
+ if (unlikely(p_method == StringName())) {
object = 0;
- ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string");
+ ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string.");
}
object = p_object;
@@ -352,9 +366,9 @@ Callable::Callable(ObjectID p_object, const StringName &p_method) {
}
Callable::Callable(CallableCustom *p_custom) {
- if (p_custom->referenced) {
+ if (unlikely(p_custom->referenced)) {
object = 0;
- ERR_FAIL_MSG("Callable custom is already referenced");
+ ERR_FAIL_MSG("Callable custom is already referenced.");
}
p_custom->referenced = true;
object = 0; //ensure object is all zero, since pointer may be 32 bits
diff --git a/core/variant/callable.h b/core/variant/callable.h
index 3ae424e9bf..bba69d453e 100644
--- a/core/variant/callable.h
+++ b/core/variant/callable.h
@@ -99,7 +99,7 @@ public:
bool is_valid() const;
template <typename... VarArgs>
- Callable bind(VarArgs... p_args);
+ Callable bind(VarArgs... p_args) const;
Callable bindv(const Array &p_arguments);
Callable bindp(const Variant **p_arguments, int p_argcount) const;
@@ -125,6 +125,8 @@ public:
operator String() const;
+ static Callable create(const Variant &p_variant, const StringName &p_method);
+
Callable(const Object *p_object, const StringName &p_method);
Callable(ObjectID p_object, const StringName &p_method);
Callable(CallableCustom *p_custom);
diff --git a/core/variant/variant.h b/core/variant/variant.h
index d685444c30..c358559c9b 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -865,7 +865,7 @@ Variant Callable::call(VarArgs... p_args) const {
}
template <typename... VarArgs>
-Callable Callable::bind(VarArgs... p_args) {
+Callable Callable::bind(VarArgs... p_args) const {
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
const Variant *argptrs[sizeof...(p_args) + 1];
for (uint32_t i = 0; i < sizeof...(p_args); i++) {
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index b551a7059e..543ee1135f 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -2033,11 +2033,13 @@ static void _register_variant_builtin_methods() {
bind_method(NodePath, get_subname, sarray("idx"), varray());
bind_method(NodePath, get_concatenated_names, sarray(), varray());
bind_method(NodePath, get_concatenated_subnames, sarray(), varray());
+ bind_method(NodePath, slice, sarray("begin", "end"), varray(INT_MAX));
bind_method(NodePath, get_as_property_path, sarray(), varray());
bind_method(NodePath, is_empty, sarray(), varray());
/* Callable */
+ bind_static_method(Callable, create, sarray("variant", "method"), varray());
bind_method(Callable, callv, sarray("arguments"), varray());
bind_method(Callable, is_null, sarray(), varray());
bind_method(Callable, is_custom, sarray(), varray());
diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h
index ef7bf2dfc2..36935907ae 100644
--- a/core/variant/variant_construct.h
+++ b/core/variant/variant_construct.h
@@ -661,7 +661,7 @@ public:
VariantInternal::clear(r_ret);
}
static void ptr_construct(void *base, const void **p_args) {
- ERR_FAIL_MSG("can't ptrcall nil constructor");
+ ERR_FAIL_MSG("Cannot ptrcall nil constructor");
}
static int get_argument_count() {
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 171074188f..79bed9be33 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -810,7 +810,7 @@ struct VariantInternalAccessor<bool> {
#define VARIANT_ACCESSOR_NUMBER(m_type) \
template <> \
struct VariantInternalAccessor<m_type> { \
- static _FORCE_INLINE_ m_type get(const Variant *v) { return (m_type)*VariantInternal::get_int(v); } \
+ static _FORCE_INLINE_ m_type get(const Variant *v) { return (m_type) * VariantInternal::get_int(v); } \
static _FORCE_INLINE_ void set(Variant *v, m_type p_value) { *VariantInternal::get_int(v) = p_value; } \
};
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index 50c9c10987..20941b944f 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -433,9 +433,9 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
} \
m_assign_type num; \
if (value->get_type() == Variant::INT) { \
- num = (m_assign_type)*VariantGetInternalPtr<int64_t>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<int64_t>::get_ptr(value); \
} else if (value->get_type() == Variant::FLOAT) { \
- num = (m_assign_type)*VariantGetInternalPtr<double>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<double>::get_ptr(value); \
} else { \
*oob = false; \
*valid = false; \
@@ -495,9 +495,9 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
} \
m_assign_type num; \
if (value->get_type() == Variant::INT) { \
- num = (m_assign_type)*VariantGetInternalPtr<int64_t>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<int64_t>::get_ptr(value); \
} else if (value->get_type() == Variant::FLOAT) { \
- num = (m_assign_type)*VariantGetInternalPtr<double>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<double>::get_ptr(value); \
} else { \
*oob = false; \
*valid = false; \
diff --git a/core/version.h b/core/version.h
index abb81312ac..18a97cadf0 100644
--- a/core/version.h
+++ b/core/version.h
@@ -33,6 +33,8 @@
#include "core/version_generated.gen.h"
+#include <stdint.h>
+
// Copied from typedefs.h to stay lean.
#ifndef _STR
#define _STR(m_x) #m_x
@@ -77,4 +79,8 @@
// Git commit hash, generated at build time in `core/version_hash.gen.cpp`.
extern const char *const VERSION_HASH;
+// Git commit date UNIX timestamp (in seconds), generated at build time in `core/version_hash.gen.cpp`.
+// Set to 0 if unknown.
+extern const uint64_t VERSION_TIMESTAMP;
+
#endif // VERSION_H