summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/config/project_settings.cpp19
-rw-r--r--core/config/project_settings.h8
-rw-r--r--core/core_constants.cpp1
-rw-r--r--core/extension/gdnative_interface.cpp12
-rw-r--r--core/extension/gdnative_interface.h2
-rw-r--r--core/input/input.cpp12
-rw-r--r--core/input/input.h4
-rw-r--r--core/io/config_file.cpp13
-rw-r--r--core/math/camera_matrix.cpp5
-rw-r--r--core/math/camera_matrix.h1
-rw-r--r--core/math/color.cpp61
-rw-r--r--core/math/color.h8
-rw-r--r--core/math/expression.cpp2
-rw-r--r--core/os/os.cpp31
-rw-r--r--core/variant/array.cpp44
-rw-r--r--core/variant/array.h2
-rw-r--r--core/variant/dictionary.cpp8
-rw-r--r--core/variant/dictionary.h1
-rw-r--r--core/variant/variant_call.cpp10
-rw-r--r--core/variant/variant_setget.h4
20 files changed, 229 insertions, 19 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index ff5ff83bf8..12d936d456 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -205,6 +205,11 @@ void ProjectSettings::set_as_basic(const String &p_name, bool p_basic) {
props[p_name].basic = p_basic;
}
+void ProjectSettings::set_as_internal(const String &p_name, bool p_internal) {
+ ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + ".");
+ props[p_name].internal = p_internal;
+}
+
void ProjectSettings::set_ignore_value_in_docs(const String &p_name, bool p_ignore) {
ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + ".");
#ifdef DEBUG_METHODS_ENABLED
@@ -344,7 +349,7 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const {
vc.name = E.key;
vc.order = v->order;
vc.type = v->variant.get_type();
- if (vc.name.begins_with("input/") || vc.name.begins_with("import/") || vc.name.begins_with("export/") || vc.name.begins_with("/remap") || vc.name.begins_with("/locale") || vc.name.begins_with("/autoload")) {
+ if (v->internal || vc.name.begins_with("input/") || vc.name.begins_with("importer_defaults/") || vc.name.begins_with("import/") || vc.name.begins_with("autoload/") || vc.name.begins_with("editor_plugins/") || vc.name.begins_with("shader_globals/")) {
vc.flags = PROPERTY_USAGE_STORAGE;
} else {
vc.flags = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE;
@@ -890,7 +895,7 @@ Error ProjectSettings::_save_custom_bnd(const String &p_file) { // add other par
Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_custom, const Vector<String> &p_custom_features, bool p_merge_with_current) {
ERR_FAIL_COND_V_MSG(p_path.is_empty(), ERR_INVALID_PARAMETER, "Project settings save path cannot be empty.");
- PackedStringArray project_features = has_setting("application/config/features") ? (PackedStringArray)get_setting("application/config/features") : PackedStringArray();
+ PackedStringArray project_features = get_setting("application/config/features");
// If there is no feature list currently present, force one to generate.
if (project_features.is_empty()) {
project_features = ProjectSettings::get_required_features();
@@ -994,7 +999,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
}
}
-Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed, bool p_ignore_value_in_docs, bool p_basic) {
+Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed, bool p_ignore_value_in_docs, bool p_basic, bool p_internal) {
Variant ret;
if (!ProjectSettings::get_singleton()->has_setting(p_var)) {
ProjectSettings::get_singleton()->set(p_var, p_default);
@@ -1006,6 +1011,7 @@ Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restar
ProjectSettings::get_singleton()->set_as_basic(p_var, p_basic);
ProjectSettings::get_singleton()->set_restart_if_changed(p_var, p_restart_if_changed);
ProjectSettings::get_singleton()->set_ignore_value_in_docs(p_var, p_ignore_value_in_docs);
+ ProjectSettings::get_singleton()->set_as_internal(p_var, p_internal);
return ret;
}
@@ -1151,7 +1157,7 @@ void ProjectSettings::_add_builtin_input_map() {
action["events"] = events;
String action_name = "input/" + E.key;
- GLOBAL_DEF(action_name, action);
+ GLOBAL_DEF_INTERNAL(action_name, action);
input_presets.push_back(action_name);
}
}
@@ -1235,6 +1241,11 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("compression/formats/gzip/compression_level", Compression::gzip_level);
custom_prop_info["compression/formats/gzip/compression_level"] = PropertyInfo(Variant::INT, "compression/formats/gzip/compression_level", PROPERTY_HINT_RANGE, "-1,9,1");
+
+ // These properties will not show up in the dialog nor in the documentation. If you want to exclude whole groups, see _get_property_list() method.
+ GLOBAL_DEF_INTERNAL("application/config/features", PackedStringArray());
+ GLOBAL_DEF_INTERNAL("internationalization/locale/translation_remaps", PackedStringArray());
+ GLOBAL_DEF_INTERNAL("internationalization/locale/translations", PackedStringArray());
}
ProjectSettings::~ProjectSettings() {
diff --git a/core/config/project_settings.h b/core/config/project_settings.h
index d9b1a9b81b..c3992a4db2 100644
--- a/core/config/project_settings.h
+++ b/core/config/project_settings.h
@@ -62,6 +62,7 @@ protected:
int order = 0;
bool persist = false;
bool basic = false;
+ bool internal = false;
Variant variant;
Variant initial;
bool hide_from_editor = false;
@@ -141,6 +142,7 @@ public:
void set_initial_value(const String &p_name, const Variant &p_value);
void set_as_basic(const String &p_name, bool p_basic);
+ void set_as_internal(const String &p_name, bool p_internal);
void set_restart_if_changed(const String &p_name, bool p_restart);
void set_ignore_value_in_docs(const String &p_name, bool p_ignore);
bool get_ignore_value_in_docs(const String &p_name) const;
@@ -191,8 +193,8 @@ public:
~ProjectSettings();
};
-//not a macro any longer
-Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed = false, bool p_ignore_value_in_docs = false, bool p_basic = false);
+// Not a macro any longer.
+Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed = false, bool p_ignore_value_in_docs = false, bool p_basic = false, bool p_internal = false);
#define GLOBAL_DEF(m_var, m_value) _GLOBAL_DEF(m_var, m_value)
#define GLOBAL_DEF_RST(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true)
#define GLOBAL_DEF_NOVAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, true)
@@ -204,4 +206,6 @@ Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restar
#define GLOBAL_DEF_NOVAL_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, true, true)
#define GLOBAL_DEF_RST_NOVAL_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, true, true)
+#define GLOBAL_DEF_INTERNAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, false, false, true)
+
#endif // PROJECT_SETTINGS_H
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index ea1304f5ba..bbc937d575 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -638,6 +638,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_REVERSE);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VIRTUAL);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_FROM_SCRIPT);
+ BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VARARG);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_STATIC);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_OBJECT_CORE);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAGS_DEFAULT);
diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp
index a1d54f9c6d..58103e3af3 100644
--- a/core/extension/gdnative_interface.cpp
+++ b/core/extension/gdnative_interface.cpp
@@ -230,6 +230,16 @@ static void gdnative_variant_iter_get(const GDNativeVariantPtr p_self, GDNativeV
}
/// Variant functions.
+static GDNativeInt gdnative_variant_hash(const GDNativeVariantPtr p_self) {
+ const Variant *self = (const Variant *)p_self;
+ return self->hash();
+}
+
+static GDNativeInt gdnative_variant_recursive_hash(const GDNativeVariantPtr p_self, GDNativeInt p_recursion_count) {
+ const Variant *self = (const Variant *)p_self;
+ return self->recursive_hash(p_recursion_count);
+}
+
static GDNativeBool gdnative_variant_hash_compare(const GDNativeVariantPtr p_self, const GDNativeVariantPtr p_other) {
const Variant *self = (const Variant *)p_self;
const Variant *other = (const Variant *)p_other;
@@ -944,6 +954,8 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
gdni.variant_iter_init = gdnative_variant_iter_init;
gdni.variant_iter_next = gdnative_variant_iter_next;
gdni.variant_iter_get = gdnative_variant_iter_get;
+ gdni.variant_hash = gdnative_variant_hash;
+ gdni.variant_recursive_hash = gdnative_variant_recursive_hash;
gdni.variant_hash_compare = gdnative_variant_hash_compare;
gdni.variant_booleanize = gdnative_variant_booleanize;
gdni.variant_sub = gdnative_variant_sub;
diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h
index 98976b29f6..095c7983ee 100644
--- a/core/extension/gdnative_interface.h
+++ b/core/extension/gdnative_interface.h
@@ -413,6 +413,8 @@ typedef struct {
GDNativeBool (*variant_iter_init)(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_iter, GDNativeBool *r_valid);
GDNativeBool (*variant_iter_next)(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_iter, GDNativeBool *r_valid);
void (*variant_iter_get)(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_iter, GDNativeVariantPtr r_ret, GDNativeBool *r_valid);
+ GDNativeInt (*variant_hash)(const GDNativeVariantPtr p_self);
+ GDNativeInt (*variant_recursive_hash)(const GDNativeVariantPtr p_self, GDNativeInt p_recursion_count);
GDNativeBool (*variant_hash_compare)(const GDNativeVariantPtr p_self, const GDNativeVariantPtr p_other);
GDNativeBool (*variant_booleanize)(const GDNativeVariantPtr p_self);
void (*variant_sub)(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, GDNativeVariantPtr r_dst);
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 4befdfac58..b3a68bb98c 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -134,8 +134,12 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event);
ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &Input::set_use_accumulated_input);
+ ClassDB::bind_method(D_METHOD("is_using_accumulated_input"), &Input::is_using_accumulated_input);
ClassDB::bind_method(D_METHOD("flush_buffered_events"), &Input::flush_buffered_events);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_mode"), "set_mouse_mode", "get_mouse_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_accumulated_input"), "set_use_accumulated_input", "is_using_accumulated_input");
+
BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
BIND_ENUM_CONSTANT(MOUSE_MODE_CAPTURED);
@@ -897,6 +901,10 @@ void Input::set_use_accumulated_input(bool p_enable) {
use_accumulated_input = p_enable;
}
+bool Input::is_using_accumulated_input() {
+ return use_accumulated_input;
+}
+
void Input::release_pressed_events() {
flush_buffered_events(); // this is needed to release actions strengths
@@ -1401,8 +1409,8 @@ String Input::get_joy_guid(int p_device) const {
return joy_names[p_device].uid;
}
-Array Input::get_connected_joypads() {
- Array ret;
+TypedArray<int> Input::get_connected_joypads() {
+ TypedArray<int> ret;
HashMap<int, Joypad>::Iterator elem = joy_names.begin();
while (elem) {
if (elem->value.connected) {
diff --git a/core/input/input.h b/core/input/input.h
index 9a5b8e6e06..f02f2abae5 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -36,6 +36,7 @@
#include "core/os/keyboard.h"
#include "core/os/thread_safe.h"
#include "core/templates/rb_set.h"
+#include "core/variant/typed_array.h"
class Input : public Object {
GDCLASS(Input, Object);
@@ -259,7 +260,7 @@ public:
float get_joy_axis(int p_device, JoyAxis p_axis) const;
String get_joy_name(int p_idx);
- Array get_connected_joypads();
+ TypedArray<int> get_connected_joypads();
Vector2 get_joy_vibration_strength(int p_device);
float get_joy_vibration_duration(int p_device);
uint64_t get_joy_vibration_timestamp(int p_device);
@@ -326,6 +327,7 @@ public:
bool is_using_input_buffering();
void set_use_input_buffering(bool p_enable);
void set_use_accumulated_input(bool p_enable);
+ bool is_using_accumulated_input();
void release_pressed_events();
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index dd0191f43f..ae421654ca 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -61,19 +61,19 @@ PackedStringArray ConfigFile::_get_section_keys(const String &p_section) const {
}
void ConfigFile::set_value(const String &p_section, const String &p_key, const Variant &p_value) {
- if (p_value.get_type() == Variant::NIL) {
- //erase
+ if (p_value.get_type() == Variant::NIL) { // Erase key.
if (!values.has(p_section)) {
- return; // ?
+ return;
}
+
values[p_section].erase(p_key);
if (values[p_section].is_empty()) {
values.erase(p_section);
}
-
} else {
if (!values.has(p_section)) {
- values[p_section] = HashMap<String, Variant>();
+ // Insert section-less keys at the beginning.
+ values.insert(p_section, HashMap<String, Variant>(), p_section.is_empty());
}
values[p_section][p_key] = p_value;
@@ -125,6 +125,9 @@ void ConfigFile::erase_section_key(const String &p_section, const String &p_key)
ERR_FAIL_COND_MSG(!values[p_section].has(p_key), vformat("Cannot erase nonexistent key \"%s\" from section \"%s\".", p_key, p_section));
values[p_section].erase(p_key);
+ if (values[p_section].is_empty()) {
+ values.erase(p_section);
+ }
}
Error ConfigFile::save(const String &p_path) {
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 9443addd22..57c53b0adb 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -710,6 +710,11 @@ void CameraMatrix::scale_translate_to_fit(const AABB &p_aabb) {
matrix[3][3] = 1;
}
+void CameraMatrix::add_jitter_offset(const Vector2 &p_offset) {
+ matrix[3][0] += p_offset.x;
+ matrix[3][1] += p_offset.y;
+}
+
CameraMatrix::operator Transform3D() const {
Transform3D tr;
const real_t *m = &matrix[0][0];
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index f1aea5e4e8..a4051cee3b 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -95,6 +95,7 @@ struct CameraMatrix {
operator String() const;
void scale_translate_to_fit(const AABB &p_aabb);
+ void add_jitter_offset(const Vector2 &p_offset);
void make_scale(const Vector3 &p_scale);
int get_pixels_per_meter(int p_for_pixel_width) const;
operator Transform3D() const;
diff --git a/core/math/color.cpp b/core/math/color.cpp
index 74552a2894..4bdeafd2f2 100644
--- a/core/math/color.cpp
+++ b/core/math/color.cpp
@@ -35,6 +35,8 @@
#include "core/string/print_string.h"
#include "core/templates/rb_map.h"
+#include "thirdparty/misc/ok_color.h"
+
uint32_t Color::to_argb32() const {
uint32_t c = (uint8_t)Math::round(a * 255);
c <<= 8;
@@ -240,6 +242,20 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
}
}
+void Color::set_ok_hsl(float p_h, float p_s, float p_l, float p_alpha) {
+ ok_color::HSL hsl;
+ hsl.h = p_h;
+ hsl.s = p_s;
+ hsl.l = p_l;
+ ok_color new_ok_color;
+ ok_color::RGB rgb = new_ok_color.okhsl_to_srgb(hsl);
+ Color c = Color(rgb.r, rgb.g, rgb.b, p_alpha).clamp();
+ r = c.r;
+ g = c.g;
+ b = c.b;
+ a = c.a;
+}
+
bool Color::is_equal_approx(const Color &p_color) const {
return Math::is_equal_approx(r, p_color.r) && Math::is_equal_approx(g, p_color.g) && Math::is_equal_approx(b, p_color.b) && Math::is_equal_approx(a, p_color.a);
}
@@ -568,3 +584,48 @@ Color Color::operator-() const {
1.0f - b,
1.0f - a);
}
+
+Color Color::from_ok_hsl(float p_h, float p_s, float p_l, float p_alpha) {
+ Color c;
+ c.set_ok_hsl(p_h, p_s, p_l, p_alpha);
+ return c;
+}
+
+float Color::get_ok_hsl_h() const {
+ ok_color::RGB rgb;
+ rgb.r = r;
+ rgb.g = g;
+ rgb.b = b;
+ ok_color new_ok_color;
+ ok_color::HSL ok_hsl = new_ok_color.srgb_to_okhsl(rgb);
+ if (Math::is_nan(ok_hsl.h)) {
+ return 0.0f;
+ }
+ return CLAMP(ok_hsl.h, 0.0f, 1.0f);
+}
+
+float Color::get_ok_hsl_s() const {
+ ok_color::RGB rgb;
+ rgb.r = r;
+ rgb.g = g;
+ rgb.b = b;
+ ok_color new_ok_color;
+ ok_color::HSL ok_hsl = new_ok_color.srgb_to_okhsl(rgb);
+ if (Math::is_nan(ok_hsl.s)) {
+ return 0.0f;
+ }
+ return CLAMP(ok_hsl.s, 0.0f, 1.0f);
+}
+
+float Color::get_ok_hsl_l() const {
+ ok_color::RGB rgb;
+ rgb.r = r;
+ rgb.g = g;
+ rgb.b = b;
+ ok_color new_ok_color;
+ ok_color::HSL ok_hsl = new_ok_color.srgb_to_okhsl(rgb);
+ if (Math::is_nan(ok_hsl.l)) {
+ return 0.0f;
+ }
+ return CLAMP(ok_hsl.l, 0.0f, 1.0f);
+}
diff --git a/core/math/color.h b/core/math/color.h
index 91e0bf5532..0afa6006a8 100644
--- a/core/math/color.h
+++ b/core/math/color.h
@@ -56,6 +56,10 @@ struct _NO_DISCARD_ Color {
float get_s() const;
float get_v() const;
void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0);
+ float get_ok_hsl_h() const;
+ float get_ok_hsl_s() const;
+ float get_ok_hsl_l() const;
+ void set_ok_hsl(float p_h, float p_s, float p_l, float p_alpha = 1.0);
_FORCE_INLINE_ float &operator[](int p_idx) {
return components[p_idx];
@@ -195,6 +199,7 @@ struct _NO_DISCARD_ Color {
static Color get_named_color(int p_idx);
static Color from_string(const String &p_string, const Color &p_default);
static Color from_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0);
+ static Color from_ok_hsl(float p_h, float p_s, float p_l, float p_alpha = 1.0);
static Color from_rgbe9995(uint32_t p_rgbe);
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
@@ -213,6 +218,9 @@ struct _NO_DISCARD_ Color {
_FORCE_INLINE_ void set_h(float p_h) { set_hsv(p_h, get_s(), get_v()); }
_FORCE_INLINE_ void set_s(float p_s) { set_hsv(get_h(), p_s, get_v()); }
_FORCE_INLINE_ void set_v(float p_v) { set_hsv(get_h(), get_s(), p_v); }
+ _FORCE_INLINE_ void set_ok_hsl_h(float p_h) { set_ok_hsl(p_h, get_ok_hsl_s(), get_ok_hsl_l()); }
+ _FORCE_INLINE_ void set_ok_hsl_s(float p_s) { set_ok_hsl(get_ok_hsl_h(), p_s, get_ok_hsl_l()); }
+ _FORCE_INLINE_ void set_ok_hsl_l(float p_l) { set_ok_hsl(get_ok_hsl_h(), get_ok_hsl_s(), p_l); }
_FORCE_INLINE_ Color() {}
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 97dc175d94..5a90f68b66 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -1245,7 +1245,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
case Expression::ENode::TYPE_INPUT: {
const Expression::InputNode *in = static_cast<const Expression::InputNode *>(p_node);
if (in->index < 0 || in->index >= p_inputs.size()) {
- r_error_str = vformat(RTR("Invalid input %i (not passed) in expression"), in->index);
+ r_error_str = vformat(RTR("Invalid input %d (not passed) in expression"), in->index);
return true;
}
r_ret = p_inputs[in->index];
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 4f7095b0fc..327f1c95f2 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -413,19 +413,29 @@ bool OS::has_feature(const String &p_feature) {
if (sizeof(void *) == 4 && p_feature == "32") {
return true;
}
-#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__)
+#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)
+#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(_M_X64)
if (p_feature == "x86_64") {
return true;
}
-#elif (defined(__i386) || defined(__i386__))
+#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
+ if (p_feature == "x86_32") {
+ return true;
+ }
+#endif
if (p_feature == "x86") {
return true;
}
-#elif defined(__aarch64__)
+#elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || defined(_M_ARM64)
+#if defined(__aarch64__) || defined(_M_ARM64)
if (p_feature == "arm64") {
return true;
}
-#elif defined(__arm__)
+#elif defined(__arm__) || defined(_M_ARM)
+ if (p_feature == "arm32") {
+ return true;
+ }
+#endif
#if defined(__ARM_ARCH_7A__)
if (p_feature == "armv7a" || p_feature == "armv7") {
return true;
@@ -457,6 +467,19 @@ bool OS::has_feature(const String &p_feature) {
if (p_feature == "ppc") {
return true;
}
+#elif defined(__wasm__)
+#if defined(__wasm64__)
+ if (p_feature == "wasm64") {
+ return true;
+ }
+#elif defined(__wasm32__)
+ if (p_feature == "wasm32") {
+ return true;
+ }
+#endif
+ if (p_feature == "wasm") {
+ return true;
+ }
#endif
if (_check_internal_feature_support(p_feature)) {
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index 7551350c95..b1e142d239 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -501,6 +501,50 @@ Variant Array::reduce(const Callable &p_callable, const Variant &p_accum) const
return ret;
}
+bool Array::any(const Callable &p_callable) const {
+ const Variant *argptrs[1];
+ for (int i = 0; i < size(); i++) {
+ argptrs[0] = &get(i);
+
+ Variant result;
+ Callable::CallError ce;
+ p_callable.call(argptrs, 1, result, ce);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_FAIL_V_MSG(false, "Error calling method from 'any': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
+ }
+
+ if (result.operator bool()) {
+ // Return as early as possible when one of the conditions is `true`.
+ // This improves performance compared to relying on `filter(...).size() >= 1`.
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool Array::all(const Callable &p_callable) const {
+ const Variant *argptrs[1];
+ for (int i = 0; i < size(); i++) {
+ argptrs[0] = &get(i);
+
+ Variant result;
+ Callable::CallError ce;
+ p_callable.call(argptrs, 1, result, ce);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_FAIL_V_MSG(false, "Error calling method from 'all': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
+ }
+
+ if (!(result.operator bool())) {
+ // Return as early as possible when one of the inverted conditions is `false`.
+ // This improves performance compared to relying on `filter(...).size() >= array_size().`.
+ return false;
+ }
+ }
+
+ return true;
+}
+
struct _ArrayVariantSort {
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
bool valid = false;
diff --git a/core/variant/array.h b/core/variant/array.h
index f537700f99..c007376734 100644
--- a/core/variant/array.h
+++ b/core/variant/array.h
@@ -108,6 +108,8 @@ public:
Array filter(const Callable &p_callable) const;
Array map(const Callable &p_callable) const;
Variant reduce(const Callable &p_callable, const Variant &p_accum) const;
+ bool any(const Callable &p_callable) const;
+ bool all(const Callable &p_callable) const;
bool operator<(const Array &p_array) const;
bool operator<=(const Array &p_array) const;
diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp
index bda8c93a79..822021f440 100644
--- a/core/variant/dictionary.cpp
+++ b/core/variant/dictionary.cpp
@@ -269,6 +269,14 @@ void Dictionary::clear() {
_p->variant_map.clear();
}
+void Dictionary::merge(const Dictionary &p_dictionary, bool p_overwrite) {
+ for (const KeyValue<Variant, Variant> &E : p_dictionary._p->variant_map) {
+ if (p_overwrite || !has(E.key)) {
+ this->operator[](E.key) = E.value;
+ }
+ }
+}
+
void Dictionary::_unref() const {
ERR_FAIL_COND(!_p);
if (_p->refcount.unref()) {
diff --git a/core/variant/dictionary.h b/core/variant/dictionary.h
index 1224a4ff6f..2632893e8d 100644
--- a/core/variant/dictionary.h
+++ b/core/variant/dictionary.h
@@ -62,6 +62,7 @@ public:
int size() const;
bool is_empty() const;
void clear();
+ void merge(const Dictionary &p_dictionary, bool p_overwrite = false);
bool has(const Variant &p_key) const;
bool has_all(const Array &p_keys) const;
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index a3568a8d6a..741d3e5b8f 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1472,6 +1472,10 @@ static void _register_variant_builtin_methods() {
bind_static_method(String, chr, sarray("char"), varray());
bind_static_method(String, humanize_size, sarray("size"), varray());
+ /* StringName */
+
+ bind_method(StringName, hash, sarray(), varray());
+
/* Vector2 */
bind_method(Vector2, angle, sarray(), varray());
@@ -1671,6 +1675,8 @@ static void _register_variant_builtin_methods() {
bind_static_method(Color, get_named_color, sarray("idx"), varray());
bind_static_method(Color, from_string, sarray("str", "default"), varray());
bind_static_method(Color, from_hsv, sarray("h", "s", "v", "alpha"), varray(1.0));
+ bind_static_method(Color, from_ok_hsl, sarray("h", "s", "l", "alpha"), varray(1.0));
+
bind_static_method(Color, from_rgbe9995, sarray("rgbe"), varray());
/* RID */
@@ -1684,6 +1690,7 @@ static void _register_variant_builtin_methods() {
bind_method(NodePath, get_name_count, sarray(), varray());
bind_method(NodePath, get_name, sarray("idx"), varray());
bind_method(NodePath, get_subname_count, sarray(), varray());
+ bind_method(NodePath, hash, sarray(), varray());
bind_method(NodePath, get_subname, sarray("idx"), varray());
bind_method(NodePath, get_concatenated_subnames, sarray(), varray());
bind_method(NodePath, get_as_property_path, sarray(), varray());
@@ -1808,6 +1815,7 @@ static void _register_variant_builtin_methods() {
bind_method(Dictionary, size, sarray(), varray());
bind_method(Dictionary, is_empty, sarray(), varray());
bind_method(Dictionary, clear, sarray(), varray());
+ bind_method(Dictionary, merge, sarray("dictionary", "overwrite"), varray(false));
bind_method(Dictionary, has, sarray("key"), varray());
bind_method(Dictionary, has_all, sarray("keys"), varray());
bind_method(Dictionary, erase, sarray("key"), varray());
@@ -1853,6 +1861,8 @@ static void _register_variant_builtin_methods() {
bind_method(Array, filter, sarray("method"), varray());
bind_method(Array, map, sarray("method"), varray());
bind_method(Array, reduce, sarray("method", "accum"), varray(Variant()));
+ bind_method(Array, any, sarray("method"), varray());
+ bind_method(Array, all, sarray("method"), varray());
bind_method(Array, max, sarray(), varray());
bind_method(Array, min, sarray(), varray());
diff --git a/core/variant/variant_setget.h b/core/variant/variant_setget.h
index 3b95f0531b..bc4dc4b408 100644
--- a/core/variant/variant_setget.h
+++ b/core/variant/variant_setget.h
@@ -329,4 +329,8 @@ SETGET_NUMBER_STRUCT_FUNC(Color, double, h, set_h, get_h)
SETGET_NUMBER_STRUCT_FUNC(Color, double, s, set_s, get_s)
SETGET_NUMBER_STRUCT_FUNC(Color, double, v, set_v, get_v)
+SETGET_NUMBER_STRUCT_FUNC(Color, double, ok_hsl_h, set_ok_hsl_h, get_ok_hsl_h)
+SETGET_NUMBER_STRUCT_FUNC(Color, double, ok_hsl_s, set_ok_hsl_s, get_ok_hsl_s)
+SETGET_NUMBER_STRUCT_FUNC(Color, double, ok_hsl_l, set_ok_hsl_l, get_ok_hsl_l)
+
#endif // VARIANT_SETGET_H