summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/config/project_settings.cpp4
-rw-r--r--core/core_constants.cpp1
-rw-r--r--core/io/file_access_pack.h4
-rw-r--r--core/io/image.cpp43
-rw-r--r--core/io/image.h12
-rw-r--r--core/io/resource.cpp20
-rw-r--r--core/math/delaunay_3d.h2
-rw-r--r--core/multiplayer/multiplayer_peer.cpp11
-rw-r--r--core/object/callable_method_pointer.cpp4
-rw-r--r--core/object/class_db.cpp52
-rw-r--r--core/object/method_bind.cpp25
-rw-r--r--core/object/object.h1
-rw-r--r--core/os/os.cpp4
-rw-r--r--core/os/os.h1
-rw-r--r--core/templates/hashfuncs.h162
-rw-r--r--core/variant/array.cpp6
-rw-r--r--core/variant/callable.cpp3
-rw-r--r--core/variant/dictionary.cpp8
-rw-r--r--core/variant/variant.cpp144
-rw-r--r--core/variant/variant_call.cpp16
-rw-r--r--core/variant/variant_utility.cpp12
21 files changed, 377 insertions, 158 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 28fbc78501..7145e628c1 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -41,7 +41,6 @@
#include "core/os/keyboard.h"
#include "core/variant/variant_parser.h"
#include "core/version.h"
-
#include "modules/modules_enabled.gen.h" // For mono.
const String ProjectSettings::PROJECT_DATA_DIR_NAME_SUFFIX = "godot";
@@ -1250,9 +1249,6 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF_INTERNAL("application/config/features", PackedStringArray());
GLOBAL_DEF_INTERNAL("internationalization/locale/translation_remaps", PackedStringArray());
GLOBAL_DEF_INTERNAL("internationalization/locale/translations", PackedStringArray());
-
- GLOBAL_DEF("rendering/textures/vram_compression/minimum_size", 512);
- custom_prop_info["rendering/textures/vram_compression/minimum_size"] = PropertyInfo(Variant::INT, "rendering/textures/vram_compression/minimum_size", PROPERTY_HINT_RANGE, "16,16384,1");
}
ProjectSettings::~ProjectSettings() {
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 4e0845e625..1f46223a1d 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -607,6 +607,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_OBJECT_TOO_BIG);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_PATH_VALID_TYPES);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_SAVE_FILE);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_GLOBAL_SAVE_FILE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_OBJECTID);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_POINTER);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ARRAY_TYPE);
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index 19a0cce796..e656f6b885 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -84,8 +84,8 @@ private:
return (a == p_val.a) && (b == p_val.b);
}
static uint32_t hash(const PathMD5 &p_val) {
- uint32_t h = hash_djb2_one_32(p_val.a);
- return hash_djb2_one_32(p_val.b, h);
+ uint32_t h = hash_murmur3_one_32(p_val.a);
+ return hash_fmix32(hash_murmur3_one_32(p_val.b, h));
}
PathMD5() {}
diff --git a/core/io/image.cpp b/core/io/image.cpp
index dfba45c4e9..a945d3e6cd 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -81,9 +81,14 @@ const char *Image::format_names[Image::FORMAT_MAX] = {
};
SavePNGFunc Image::save_png_func = nullptr;
+SaveJPGFunc Image::save_jpg_func = nullptr;
SaveEXRFunc Image::save_exr_func = nullptr;
SavePNGBufferFunc Image::save_png_buffer_func = nullptr;
+SaveJPGBufferFunc Image::save_jpg_buffer_func = nullptr;
+
+SaveWebPFunc Image::save_webp_func = nullptr;
+SaveWebPBufferFunc Image::save_webp_buffer_func = nullptr;
void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixel_size, uint8_t *p_data, const uint8_t *p_pixel) {
uint32_t ofs = (p_y * width + p_x) * p_pixel_size;
@@ -2286,6 +2291,14 @@ Error Image::save_png(const String &p_path) const {
return save_png_func(p_path, Ref<Image>((Image *)this));
}
+Error Image::save_jpg(const String &p_path, float p_quality) const {
+ if (save_jpg_func == nullptr) {
+ return ERR_UNAVAILABLE;
+ }
+
+ return save_jpg_func(p_path, Ref<Image>((Image *)this), p_quality);
+}
+
Vector<uint8_t> Image::save_png_to_buffer() const {
if (save_png_buffer_func == nullptr) {
return Vector<uint8_t>();
@@ -2294,6 +2307,14 @@ Vector<uint8_t> Image::save_png_to_buffer() const {
return save_png_buffer_func(Ref<Image>((Image *)this));
}
+Vector<uint8_t> Image::save_jpg_to_buffer(float p_quality) const {
+ if (save_jpg_buffer_func == nullptr) {
+ return Vector<uint8_t>();
+ }
+
+ return save_jpg_buffer_func(Ref<Image>((Image *)this), p_quality);
+}
+
Error Image::save_exr(const String &p_path, bool p_grayscale) const {
if (save_exr_func == nullptr) {
return ERR_UNAVAILABLE;
@@ -2302,6 +2323,24 @@ Error Image::save_exr(const String &p_path, bool p_grayscale) const {
return save_exr_func(p_path, Ref<Image>((Image *)this), p_grayscale);
}
+Error Image::save_webp(const String &p_path, const bool p_lossy, const float p_quality) const {
+ if (save_webp_func == nullptr) {
+ return ERR_UNAVAILABLE;
+ }
+ ERR_FAIL_COND_V_MSG(p_lossy && !(0.0f <= p_quality && p_quality <= 1.0f), ERR_INVALID_PARAMETER, "The WebP lossy quality was set to " + rtos(p_quality) + ", which is not valid. WebP lossy quality must be between 0.0 and 1.0 (inclusive).");
+
+ return save_webp_func(p_path, Ref<Image>((Image *)this), p_lossy, p_quality);
+}
+
+Vector<uint8_t> Image::save_webp_to_buffer(const bool p_lossy, const float p_quality) const {
+ if (save_webp_buffer_func == nullptr) {
+ return Vector<uint8_t>();
+ }
+ ERR_FAIL_COND_V_MSG(p_lossy && !(0.0f <= p_quality && p_quality <= 1.0f), Vector<uint8_t>(), "The WebP lossy quality was set to " + rtos(p_quality) + ", which is not valid. WebP lossy quality must be between 0.0 and 1.0 (inclusive).");
+
+ return save_webp_buffer_func(Ref<Image>((Image *)this), p_lossy, p_quality);
+}
+
int Image::get_image_data_size(int p_width, int p_height, Format p_format, bool p_mipmaps) {
int mm;
return _get_dst_image_size(p_width, p_height, p_format, mm, p_mipmaps ? -1 : 0);
@@ -3138,7 +3177,11 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("load", "path"), &Image::load);
ClassDB::bind_method(D_METHOD("save_png", "path"), &Image::save_png);
ClassDB::bind_method(D_METHOD("save_png_to_buffer"), &Image::save_png_to_buffer);
+ ClassDB::bind_method(D_METHOD("save_jpg", "path", "quality"), &Image::save_jpg, DEFVAL(0.75));
+ ClassDB::bind_method(D_METHOD("save_jpg_to_buffer", "quality"), &Image::save_jpg_to_buffer, DEFVAL(0.75));
ClassDB::bind_method(D_METHOD("save_exr", "path", "grayscale"), &Image::save_exr, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("save_webp", "path", "lossy", "quality"), &Image::save_webp, DEFVAL(false), DEFVAL(0.75f));
+ ClassDB::bind_method(D_METHOD("save_webp_to_buffer", "lossy", "quality"), &Image::save_webp_to_buffer, DEFVAL(false), DEFVAL(0.75f));
ClassDB::bind_method(D_METHOD("detect_alpha"), &Image::detect_alpha);
ClassDB::bind_method(D_METHOD("is_invisible"), &Image::is_invisible);
diff --git a/core/io/image.h b/core/io/image.h
index 1025554d51..229103f792 100644
--- a/core/io/image.h
+++ b/core/io/image.h
@@ -45,7 +45,11 @@ class Image;
typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
typedef Vector<uint8_t> (*SavePNGBufferFunc)(const Ref<Image> &p_img);
+typedef Error (*SaveJPGFunc)(const String &p_path, const Ref<Image> &p_img, float p_quality);
+typedef Vector<uint8_t> (*SaveJPGBufferFunc)(const Ref<Image> &p_img, float p_quality);
typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size);
+typedef Error (*SaveWebPFunc)(const String &p_path, const Ref<Image> &p_img, const bool p_lossy, const float p_quality);
+typedef Vector<uint8_t> (*SaveWebPBufferFunc)(const Ref<Image> &p_img, const bool p_lossy, const float p_quality);
typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
@@ -54,8 +58,12 @@ class Image : public Resource {
public:
static SavePNGFunc save_png_func;
+ static SaveJPGFunc save_jpg_func;
static SaveEXRFunc save_exr_func;
static SavePNGBufferFunc save_png_buffer_func;
+ static SaveJPGBufferFunc save_jpg_buffer_func;
+ static SaveWebPFunc save_webp_func;
+ static SaveWebPBufferFunc save_webp_buffer_func;
enum {
MAX_WIDTH = (1 << 24), // force a limit somehow
@@ -281,8 +289,12 @@ public:
Error load(const String &p_path);
Error save_png(const String &p_path) const;
+ Error save_jpg(const String &p_path, float p_quality = 0.75) const;
Vector<uint8_t> save_png_to_buffer() const;
+ Vector<uint8_t> save_jpg_to_buffer(float p_quality = 0.75) const;
Error save_exr(const String &p_path, bool p_grayscale) const;
+ Error save_webp(const String &p_path, const bool p_lossy = false, const float p_quality = 0.75f) const;
+ Vector<uint8_t> save_webp_to_buffer(const bool p_lossy = false, const float p_quality = 0.75f) const;
void create_empty(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
create(p_width, p_height, p_use_mipmaps, p_format);
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index ad01eb1083..ed7228d0b9 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -100,14 +100,14 @@ String Resource::generate_scene_unique_id() {
// If it's not unique it does not matter because the saver will try again.
OS::Date date = OS::get_singleton()->get_date();
OS::Time time = OS::get_singleton()->get_time();
- uint32_t hash = hash_djb2_one_32(OS::get_singleton()->get_ticks_usec());
- hash = hash_djb2_one_32(date.year, hash);
- hash = hash_djb2_one_32(date.month, hash);
- hash = hash_djb2_one_32(date.day, hash);
- hash = hash_djb2_one_32(time.hour, hash);
- hash = hash_djb2_one_32(time.minute, hash);
- hash = hash_djb2_one_32(time.second, hash);
- hash = hash_djb2_one_32(Math::rand(), hash);
+ uint32_t hash = hash_murmur3_one_32(OS::get_singleton()->get_ticks_usec());
+ hash = hash_murmur3_one_32(date.year, hash);
+ hash = hash_murmur3_one_32(date.month, hash);
+ hash = hash_murmur3_one_32(date.day, hash);
+ hash = hash_murmur3_one_32(time.hour, hash);
+ hash = hash_murmur3_one_32(time.minute, hash);
+ hash = hash_murmur3_one_32(time.second, hash);
+ hash = hash_murmur3_one_32(Math::rand(), hash);
static constexpr uint32_t characters = 5;
static constexpr uint32_t char_count = ('z' - 'a');
@@ -328,7 +328,7 @@ void Resource::notify_change_to_owners() {
#ifdef TOOLS_ENABLED
uint32_t Resource::hash_edited_version() const {
- uint32_t hash = hash_djb2_one_32(get_edited_version());
+ uint32_t hash = hash_murmur3_one_32(get_edited_version());
List<PropertyInfo> plist;
get_property_list(&plist);
@@ -337,7 +337,7 @@ uint32_t Resource::hash_edited_version() const {
if (E.usage & PROPERTY_USAGE_STORAGE && E.type == Variant::OBJECT && E.hint == PROPERTY_HINT_RESOURCE_TYPE) {
Ref<Resource> res = get(E.name);
if (res.is_valid()) {
- hash = hash_djb2_one_32(res->hash_edited_version(), hash);
+ hash = hash_murmur3_one_32(res->hash_edited_version(), hash);
}
}
}
diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h
index f8a10ec87e..4ab00e1f34 100644
--- a/core/math/delaunay_3d.h
+++ b/core/math/delaunay_3d.h
@@ -101,7 +101,7 @@ class Delaunay3D {
_FORCE_INLINE_ static uint32_t hash(const Triangle &p_triangle) {
uint32_t h = hash_djb2_one_32(p_triangle.triangle[0]);
h = hash_djb2_one_32(p_triangle.triangle[1], h);
- return hash_djb2_one_32(p_triangle.triangle[2], h);
+ return hash_fmix32(hash_djb2_one_32(p_triangle.triangle[2], h));
}
};
diff --git a/core/multiplayer/multiplayer_peer.cpp b/core/multiplayer/multiplayer_peer.cpp
index ae3b139bcc..b262903ce8 100644
--- a/core/multiplayer/multiplayer_peer.cpp
+++ b/core/multiplayer/multiplayer_peer.cpp
@@ -36,17 +36,18 @@ uint32_t MultiplayerPeer::generate_unique_id() const {
uint32_t hash = 0;
while (hash == 0 || hash == 1) {
- hash = hash_djb2_one_32(
+ hash = hash_murmur3_one_32(
(uint32_t)OS::get_singleton()->get_ticks_usec());
- hash = hash_djb2_one_32(
+ hash = hash_murmur3_one_32(
(uint32_t)OS::get_singleton()->get_unix_time(), hash);
- hash = hash_djb2_one_32(
+ hash = hash_murmur3_one_32(
(uint32_t)OS::get_singleton()->get_user_data_dir().hash64(), hash);
- hash = hash_djb2_one_32(
+ hash = hash_murmur3_one_32(
(uint32_t)((uint64_t)this), hash); // Rely on ASLR heap
- hash = hash_djb2_one_32(
+ hash = hash_murmur3_one_32(
(uint32_t)((uint64_t)&hash), hash); // Rely on ASLR stack
+ hash = hash_fmix32(hash);
hash = hash & 0x7FFFFFFF; // Make it compatible with unsigned, since negative ID is used for exclusion
}
diff --git a/core/object/callable_method_pointer.cpp b/core/object/callable_method_pointer.cpp
index 1bf926cafc..81f8ab6be2 100644
--- a/core/object/callable_method_pointer.cpp
+++ b/core/object/callable_method_pointer.cpp
@@ -85,9 +85,9 @@ void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_pt
// Precompute hash.
for (uint32_t i = 0; i < comp_size; i++) {
if (i == 0) {
- h = hash_djb2_one_32(comp_ptr[i]);
+ h = hash_murmur3_one_32(comp_ptr[i]);
} else {
- h = hash_djb2_one_32(comp_ptr[i], h);
+ h = hash_murmur3_one_32(comp_ptr[i], h);
}
}
}
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index 533cb6e789..3c9f373d12 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -164,7 +164,7 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
OBJTYPE_RLOCK;
#ifdef DEBUG_METHODS_ENABLED
- uint64_t hash = hash_djb2_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG));
+ uint64_t hash = hash_murmur3_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG));
List<StringName> class_list;
ClassDB::get_class_list(&class_list);
@@ -177,8 +177,8 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
if (t->api != p_api || !t->exposed) {
continue;
}
- hash = hash_djb2_one_64(t->name.hash(), hash);
- hash = hash_djb2_one_64(t->inherits.hash(), hash);
+ hash = hash_murmur3_one_64(t->name.hash(), hash);
+ hash = hash_murmur3_one_64(t->inherits.hash(), hash);
{ //methods
@@ -200,27 +200,27 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
for (const StringName &F : snames) {
MethodBind *mb = t->method_map[F];
- hash = hash_djb2_one_64(mb->get_name().hash(), hash);
- hash = hash_djb2_one_64(mb->get_argument_count(), hash);
- hash = hash_djb2_one_64(mb->get_argument_type(-1), hash); //return
+ hash = hash_murmur3_one_64(mb->get_name().hash(), hash);
+ hash = hash_murmur3_one_64(mb->get_argument_count(), hash);
+ hash = hash_murmur3_one_64(mb->get_argument_type(-1), hash); //return
for (int i = 0; i < mb->get_argument_count(); i++) {
const PropertyInfo info = mb->get_argument_info(i);
- hash = hash_djb2_one_64(info.type, hash);
- hash = hash_djb2_one_64(info.name.hash(), hash);
- hash = hash_djb2_one_64(info.hint, hash);
- hash = hash_djb2_one_64(info.hint_string.hash(), hash);
+ hash = hash_murmur3_one_64(info.type, hash);
+ hash = hash_murmur3_one_64(info.name.hash(), hash);
+ hash = hash_murmur3_one_64(info.hint, hash);
+ hash = hash_murmur3_one_64(info.hint_string.hash(), hash);
}
- hash = hash_djb2_one_64(mb->get_default_argument_count(), hash);
+ hash = hash_murmur3_one_64(mb->get_default_argument_count(), hash);
for (int i = 0; i < mb->get_default_argument_count(); i++) {
//hash should not change, i hope for tis
Variant da = mb->get_default_argument(i);
- hash = hash_djb2_one_64(da.hash(), hash);
+ hash = hash_murmur3_one_64(da.hash(), hash);
}
- hash = hash_djb2_one_64(mb->get_hint_flags(), hash);
+ hash = hash_murmur3_one_64(mb->get_hint_flags(), hash);
}
}
@@ -235,8 +235,8 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
snames.sort_custom<StringName::AlphCompare>();
for (const StringName &F : snames) {
- hash = hash_djb2_one_64(F.hash(), hash);
- hash = hash_djb2_one_64(t->constant_map[F], hash);
+ hash = hash_murmur3_one_64(F.hash(), hash);
+ hash = hash_murmur3_one_64(t->constant_map[F], hash);
}
}
@@ -252,9 +252,9 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
for (const StringName &F : snames) {
MethodInfo &mi = t->signal_map[F];
- hash = hash_djb2_one_64(F.hash(), hash);
+ hash = hash_murmur3_one_64(F.hash(), hash);
for (int i = 0; i < mi.arguments.size(); i++) {
- hash = hash_djb2_one_64(mi.arguments[i].type, hash);
+ hash = hash_murmur3_one_64(mi.arguments[i].type, hash);
}
}
}
@@ -273,23 +273,23 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
PropertySetGet *psg = t->property_setget.getptr(F);
ERR_FAIL_COND_V(!psg, 0);
- hash = hash_djb2_one_64(F.hash(), hash);
- hash = hash_djb2_one_64(psg->setter.hash(), hash);
- hash = hash_djb2_one_64(psg->getter.hash(), hash);
+ hash = hash_murmur3_one_64(F.hash(), hash);
+ hash = hash_murmur3_one_64(psg->setter.hash(), hash);
+ hash = hash_murmur3_one_64(psg->getter.hash(), hash);
}
}
//property list
for (const PropertyInfo &F : t->property_list) {
- hash = hash_djb2_one_64(F.name.hash(), hash);
- hash = hash_djb2_one_64(F.type, hash);
- hash = hash_djb2_one_64(F.hint, hash);
- hash = hash_djb2_one_64(F.hint_string.hash(), hash);
- hash = hash_djb2_one_64(F.usage, hash);
+ hash = hash_murmur3_one_64(F.name.hash(), hash);
+ hash = hash_murmur3_one_64(F.type, hash);
+ hash = hash_murmur3_one_64(F.hint, hash);
+ hash = hash_murmur3_one_64(F.hint_string.hash(), hash);
+ hash = hash_murmur3_one_64(F.usage, hash);
}
}
- return hash;
+ return hash_fmix32(hash);
#else
return 0;
#endif
diff --git a/core/object/method_bind.cpp b/core/object/method_bind.cpp
index a208c1a2b2..a4474ea53b 100644
--- a/core/object/method_bind.cpp
+++ b/core/object/method_bind.cpp
@@ -35,32 +35,27 @@
#include "method_bind.h"
uint32_t MethodBind::get_hash() const {
- uint32_t hash = hash_djb2_one_32(has_return() ? 1 : 0);
- hash = hash_djb2_one_32(get_argument_count(), hash);
-
-#ifndef _MSC_VER
-#warning This needs proper class name and argument type for hashing
-#endif
-#if 0
+ uint32_t hash = hash_murmur3_one_32(has_return() ? 1 : 0);
+ hash = hash_murmur3_one_32(get_argument_count(), hash);
for (int i = (has_return() ? -1 : 0); i < get_argument_count(); i++) {
PropertyInfo pi = i == -1 ? get_return_info() : get_argument_info(i);
- hash = hash_djb2_one_32(get_argument_type(i), hash);
+ hash = hash_murmur3_one_32(get_argument_type(i), hash);
if (pi.class_name != StringName()) {
- hash = hash_djb2_one_32(pi.class_name.operator String().hash(), hash);
+ hash = hash_murmur3_one_32(pi.class_name.operator String().hash(), hash);
}
}
-#endif
- hash = hash_djb2_one_32(get_default_argument_count(), hash);
+
+ hash = hash_murmur3_one_32(get_default_argument_count(), hash);
for (int i = 0; i < get_default_argument_count(); i++) {
Variant v = get_default_argument(i);
- hash = hash_djb2_one_32(v.hash(), hash);
+ hash = hash_murmur3_one_32(v.hash(), hash);
}
- hash = hash_djb2_one_32(is_const(), hash);
- hash = hash_djb2_one_32(is_vararg(), hash);
+ hash = hash_murmur3_one_32(is_const(), hash);
+ hash = hash_murmur3_one_32(is_vararg(), hash);
- return hash;
+ return hash_fmix32(hash);
}
PropertyInfo MethodBind::get_argument_info(int p_argument) const {
diff --git a/core/object/object.h b/core/object/object.h
index 8117783fae..02dd875acf 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -85,6 +85,7 @@ enum PropertyHint {
PROPERTY_HINT_OBJECT_TOO_BIG, ///< object is too big to send
PROPERTY_HINT_NODE_PATH_VALID_TYPES,
PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
+ PROPERTY_HINT_GLOBAL_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
PROPERTY_HINT_INT_IS_OBJECTID,
PROPERTY_HINT_ARRAY_TYPE,
PROPERTY_HINT_INT_IS_POINTER,
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 327f1c95f2..93477f4288 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -388,6 +388,10 @@ bool OS::has_feature(const String &p_feature) {
return true;
}
+ if (p_feature == "movie") {
+ return _writing_movie;
+ }
+
#ifdef DEBUG_ENABLED
if (p_feature == "debug") {
return true;
diff --git a/core/os/os.h b/core/os/os.h
index 157b8ab992..c6ea9d869a 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -58,6 +58,7 @@ class OS {
bool _allow_layered = false;
bool _stdout_enabled = true;
bool _stderr_enabled = true;
+ bool _writing_movie = false;
CompositeLogger *_logger = nullptr;
diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h
index 98ff7fa4ce..b0371f2ab5 100644
--- a/core/templates/hashfuncs.h
+++ b/core/templates/hashfuncs.h
@@ -62,7 +62,7 @@ static _FORCE_INLINE_ uint32_t hash_djb2(const char *p_cstr) {
uint32_t c;
while ((c = *chr++)) {
- hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+ hash = ((hash << 5) + hash) ^ c; /* hash * 33 ^ c */
}
return hash;
@@ -72,14 +72,14 @@ static _FORCE_INLINE_ uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len
uint32_t hash = p_prev;
for (int i = 0; i < p_len; i++) {
- hash = ((hash << 5) + hash) + p_buff[i]; /* hash * 33 + c */
+ hash = ((hash << 5) + hash) ^ p_buff[i]; /* hash * 33 + c */
}
return hash;
}
static _FORCE_INLINE_ uint32_t hash_djb2_one_32(uint32_t p_in, uint32_t p_prev = 5381) {
- return ((p_prev << 5) + p_prev) + p_in;
+ return ((p_prev << 5) + p_prev) ^ p_in;
}
/**
@@ -100,14 +100,76 @@ static _FORCE_INLINE_ uint32_t hash_one_uint64(const uint64_t p_int) {
return uint32_t(v);
}
+#define HASH_MURMUR3_SEED 0x7F07C65
// Murmurhash3 32-bit version.
// All MurmurHash versions are public domain software, and the author disclaims all copyright to their code.
-static _FORCE_INLINE_ uint32_t rotl32(uint32_t x, int8_t r) {
+static _FORCE_INLINE_ uint32_t hash_murmur3_one_32(uint32_t p_in, uint32_t p_seed = HASH_MURMUR3_SEED) {
+ p_in *= 0xcc9e2d51;
+ p_in = (p_in << 15) | (p_in >> 17);
+ p_in *= 0x1b873593;
+
+ p_seed ^= p_in;
+ p_seed = (p_seed << 13) | (p_seed >> 19);
+ p_seed = p_seed * 5 + 0xe6546b64;
+
+ return p_seed;
+}
+
+static _FORCE_INLINE_ uint32_t hash_murmur3_one_float(float p_in, uint32_t p_seed = HASH_MURMUR3_SEED) {
+ union {
+ float f;
+ uint32_t i;
+ } u;
+
+ // Normalize +/- 0.0 and NaN values so they hash the same.
+ if (p_in == 0.0f) {
+ u.f = 0.0;
+ } else if (Math::is_nan(p_in)) {
+ u.f = NAN;
+ } else {
+ u.f = p_in;
+ }
+
+ return hash_murmur3_one_32(u.i, p_seed);
+}
+
+static _FORCE_INLINE_ uint32_t hash_murmur3_one_64(uint64_t p_in, uint32_t p_seed = HASH_MURMUR3_SEED) {
+ p_seed = hash_murmur3_one_32(p_in & 0xFFFFFFFF, p_seed);
+ return hash_murmur3_one_32(p_in >> 32, p_seed);
+}
+
+static _FORCE_INLINE_ uint32_t hash_murmur3_one_double(double p_in, uint32_t p_seed = HASH_MURMUR3_SEED) {
+ union {
+ double d;
+ uint64_t i;
+ } u;
+
+ // Normalize +/- 0.0 and NaN values so they hash the same.
+ if (p_in == 0.0f) {
+ u.d = 0.0;
+ } else if (Math::is_nan(p_in)) {
+ u.d = NAN;
+ } else {
+ u.d = p_in;
+ }
+
+ return hash_murmur3_one_64(u.i, p_seed);
+}
+
+static _FORCE_INLINE_ uint32_t hash_murmur3_one_real(real_t p_in, uint32_t p_seed = HASH_MURMUR3_SEED) {
+#ifdef REAL_T_IS_DOUBLE
+ return hash_murmur3_one_double(p_in, p_seed);
+#else
+ return hash_murmur3_one_float(p_in, p_seed);
+#endif
+}
+
+static _FORCE_INLINE_ uint32_t hash_rotl32(uint32_t x, int8_t r) {
return (x << r) | (x >> (32 - r));
}
-static _FORCE_INLINE_ uint32_t fmix32(uint32_t h) {
+static _FORCE_INLINE_ uint32_t hash_fmix32(uint32_t h) {
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
@@ -117,7 +179,7 @@ static _FORCE_INLINE_ uint32_t fmix32(uint32_t h) {
return h;
}
-static _FORCE_INLINE_ uint32_t hash_murmur3_32(const void *key, int length, const uint32_t seed = 0x7F07C65) {
+static _FORCE_INLINE_ uint32_t hash_murmur3_buffer(const void *key, int length, const uint32_t seed = HASH_MURMUR3_SEED) {
// Although not required, this is a random prime number.
const uint8_t *data = (const uint8_t *)key;
const int nblocks = length / 4;
@@ -133,11 +195,11 @@ static _FORCE_INLINE_ uint32_t hash_murmur3_32(const void *key, int length, cons
uint32_t k1 = blocks[i];
k1 *= c1;
- k1 = rotl32(k1, 15);
+ k1 = hash_rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
- h1 = rotl32(h1, 13);
+ h1 = hash_rotl32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
@@ -155,14 +217,14 @@ static _FORCE_INLINE_ uint32_t hash_murmur3_32(const void *key, int length, cons
case 1:
k1 ^= tail[0];
k1 *= c1;
- k1 = rotl32(k1, 15);
+ k1 = hash_rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
};
// Finalize with additional bit mixing.
h1 ^= length;
- return fmix32(h1);
+ return hash_fmix32(h1);
}
static _FORCE_INLINE_ uint32_t hash_djb2_one_float(double p_in, uint32_t p_prev = 5381) {
@@ -184,7 +246,7 @@ static _FORCE_INLINE_ uint32_t hash_djb2_one_float(double p_in, uint32_t p_prev
}
template <class T>
-static _FORCE_INLINE_ uint32_t make_uint32_t(T p_in) {
+static _FORCE_INLINE_ uint32_t hash_make_uint32_t(T p_in) {
union {
T t;
uint32_t _u32;
@@ -213,11 +275,11 @@ static _FORCE_INLINE_ uint64_t hash_djb2_one_float_64(double p_in, uint64_t p_pr
}
static _FORCE_INLINE_ uint64_t hash_djb2_one_64(uint64_t p_in, uint64_t p_prev = 5381) {
- return ((p_prev << 5) + p_prev) + p_in;
+ return ((p_prev << 5) + p_prev) ^ p_in;
}
template <class T>
-static _FORCE_INLINE_ uint64_t make_uint64_t(T p_in) {
+static _FORCE_INLINE_ uint64_t hash_make_uint64_t(T p_in) {
union {
T t;
uint64_t _u64;
@@ -241,9 +303,9 @@ struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
- static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return fmix32(p_wchar); }
- static _FORCE_INLINE_ uint32_t hash(const char16_t p_uchar) { return fmix32(p_uchar); }
- static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return fmix32(p_uchar); }
+ static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return hash_fmix32(p_wchar); }
+ static _FORCE_INLINE_ uint32_t hash(const char16_t p_uchar) { return hash_fmix32(p_uchar); }
+ static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return hash_fmix32(p_uchar); }
static _FORCE_INLINE_ uint32_t hash(const RID &p_rid) { return hash_one_uint64(p_rid.get_id()); }
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); }
static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); }
@@ -251,21 +313,59 @@ struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { return hash_one_uint64(p_int); }
static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash_one_uint64(p_int); }
- static _FORCE_INLINE_ uint32_t hash(const float p_float) { return hash_djb2_one_float(p_float); }
- static _FORCE_INLINE_ uint32_t hash(const double p_double) { return hash_djb2_one_float(p_double); }
- static _FORCE_INLINE_ uint32_t hash(const uint32_t p_int) { return fmix32(p_int); }
- static _FORCE_INLINE_ uint32_t hash(const int32_t p_int) { return fmix32(p_int); }
- static _FORCE_INLINE_ uint32_t hash(const uint16_t p_int) { return fmix32(p_int); }
- static _FORCE_INLINE_ uint32_t hash(const int16_t p_int) { return fmix32(p_int); }
- static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return fmix32(p_int); }
- static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return fmix32(p_int); }
- static _FORCE_INLINE_ uint32_t hash(const Vector2i &p_vec) { return hash_murmur3_32(&p_vec, sizeof(Vector2i)); }
- static _FORCE_INLINE_ uint32_t hash(const Vector3i &p_vec) { return hash_murmur3_32(&p_vec, sizeof(Vector3i)); }
- static _FORCE_INLINE_ uint32_t hash(const Vector2 &p_vec) { return hash_murmur3_32(&p_vec, sizeof(Vector2)); }
- static _FORCE_INLINE_ uint32_t hash(const Vector3 &p_vec) { return hash_murmur3_32(&p_vec, sizeof(Vector3)); }
- static _FORCE_INLINE_ uint32_t hash(const Rect2i &p_rect) { return hash_murmur3_32(&p_rect, sizeof(Rect2i)); }
- static _FORCE_INLINE_ uint32_t hash(const Rect2 &p_rect) { return hash_murmur3_32(&p_rect, sizeof(Rect2)); }
- static _FORCE_INLINE_ uint32_t hash(const AABB &p_aabb) { return hash_murmur3_32(&p_aabb, sizeof(AABB)); }
+ static _FORCE_INLINE_ uint32_t hash(const float p_float) { return hash_murmur3_one_float(p_float); }
+ static _FORCE_INLINE_ uint32_t hash(const double p_double) { return hash_murmur3_one_double(p_double); }
+ static _FORCE_INLINE_ uint32_t hash(const uint32_t p_int) { return hash_fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const int32_t p_int) { return hash_fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const uint16_t p_int) { return hash_fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const int16_t p_int) { return hash_fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return hash_fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return hash_fmix32(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const Vector2i &p_vec) {
+ uint32_t h = hash_murmur3_one_32(p_vec.x);
+ h = hash_murmur3_one_32(p_vec.y, h);
+ return hash_fmix32(h);
+ }
+ static _FORCE_INLINE_ uint32_t hash(const Vector3i &p_vec) {
+ uint32_t h = hash_murmur3_one_32(p_vec.x);
+ h = hash_murmur3_one_32(p_vec.y, h);
+ h = hash_murmur3_one_32(p_vec.z, h);
+ return hash_fmix32(h);
+ }
+ static _FORCE_INLINE_ uint32_t hash(const Vector2 &p_vec) {
+ uint32_t h = hash_murmur3_one_real(p_vec.x);
+ h = hash_murmur3_one_real(p_vec.y, h);
+ return hash_fmix32(h);
+ }
+ static _FORCE_INLINE_ uint32_t hash(const Vector3 &p_vec) {
+ uint32_t h = hash_murmur3_one_real(p_vec.x);
+ h = hash_murmur3_one_real(p_vec.y, h);
+ h = hash_murmur3_one_real(p_vec.z, h);
+ return hash_fmix32(h);
+ }
+ static _FORCE_INLINE_ uint32_t hash(const Rect2i &p_rect) {
+ uint32_t h = hash_murmur3_one_32(p_rect.position.x);
+ h = hash_murmur3_one_32(p_rect.position.y, h);
+ h = hash_murmur3_one_32(p_rect.size.x, h);
+ h = hash_murmur3_one_32(p_rect.size.y, h);
+ return hash_fmix32(h);
+ }
+ static _FORCE_INLINE_ uint32_t hash(const Rect2 &p_rect) {
+ uint32_t h = hash_murmur3_one_real(p_rect.position.x);
+ h = hash_murmur3_one_real(p_rect.position.y, h);
+ h = hash_murmur3_one_real(p_rect.size.x, h);
+ h = hash_murmur3_one_real(p_rect.size.y, h);
+ return hash_fmix32(h);
+ }
+ static _FORCE_INLINE_ uint32_t hash(const AABB &p_aabb) {
+ uint32_t h = hash_murmur3_one_real(p_aabb.position.x);
+ h = hash_murmur3_one_real(p_aabb.position.y, h);
+ h = hash_murmur3_one_real(p_aabb.position.z, h);
+ h = hash_murmur3_one_real(p_aabb.size.x, h);
+ h = hash_murmur3_one_real(p_aabb.size.y, h);
+ h = hash_murmur3_one_real(p_aabb.size.z, h);
+ return hash_fmix32(h);
+ }
};
template <typename T>
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index 599c3e1dfe..af166e09a3 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -190,13 +190,13 @@ uint32_t Array::recursive_hash(int recursion_count) const {
return 0;
}
- uint32_t h = hash_djb2_one_32(Variant::ARRAY);
+ uint32_t h = hash_murmur3_one_32(Variant::ARRAY);
recursion_count++;
for (int i = 0; i < _p->array.size(); i++) {
- h = hash_djb2_one_32(_p->array[i].recursive_hash(recursion_count), h);
+ h = hash_murmur3_one_32(_p->array[i].recursive_hash(recursion_count), h);
}
- return h;
+ return hash_fmix32(h);
}
bool Array::_assign(const Array &p_array) {
diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp
index 516b8f2d51..5453f0d5c6 100644
--- a/core/variant/callable.cpp
+++ b/core/variant/callable.cpp
@@ -143,7 +143,8 @@ uint32_t Callable::hash() const {
return custom->hash();
} else {
uint32_t hash = method.hash();
- return hash_djb2_one_64(object, hash);
+ hash = hash_murmur3_one_64(object, hash);
+ return hash_fmix32(hash);
}
}
diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp
index 822021f440..d9f4359ee5 100644
--- a/core/variant/dictionary.cpp
+++ b/core/variant/dictionary.cpp
@@ -298,15 +298,15 @@ uint32_t Dictionary::recursive_hash(int recursion_count) const {
return 0;
}
- uint32_t h = hash_djb2_one_32(Variant::DICTIONARY);
+ uint32_t h = hash_murmur3_one_32(Variant::DICTIONARY);
recursion_count++;
for (const KeyValue<Variant, Variant> &E : _p->variant_map) {
- h = hash_djb2_one_32(E.key.recursive_hash(recursion_count), h);
- h = hash_djb2_one_32(E.value.recursive_hash(recursion_count), h);
+ h = hash_murmur3_one_32(E.key.recursive_hash(recursion_count), h);
+ h = hash_murmur3_one_32(E.value.recursive_hash(recursion_count), h);
}
- return h;
+ return hash_fmix32(h);
}
Array Dictionary::keys() const {
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index aa640924e4..6007268e21 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -2780,7 +2780,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
return hash_one_uint64((uint64_t)_data._int);
} break;
case FLOAT: {
- return hash_djb2_one_float(_data._float);
+ return hash_murmur3_one_float(_data._float);
} break;
case STRING: {
return reinterpret_cast<const String *>(_data._mem)->hash();
@@ -2788,50 +2788,102 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
// math types
case VECTOR2: {
- return hash_murmur3_32(reinterpret_cast<const Vector2 *>(_data._mem), sizeof(Vector2));
+ return HashMapHasherDefault::hash(*reinterpret_cast<const Vector2 *>(_data._mem));
} break;
case VECTOR2I: {
- return hash_murmur3_32(reinterpret_cast<const Vector2i *>(_data._mem), sizeof(Vector2i));
+ return HashMapHasherDefault::hash(*reinterpret_cast<const Vector2i *>(_data._mem));
} break;
case RECT2: {
- return hash_murmur3_32(reinterpret_cast<const Rect2 *>(_data._mem), sizeof(Rect2));
+ return HashMapHasherDefault::hash(*reinterpret_cast<const Rect2 *>(_data._mem));
} break;
case RECT2I: {
- return hash_murmur3_32(reinterpret_cast<const Rect2i *>(_data._mem), sizeof(Rect2i));
+ return HashMapHasherDefault::hash(*reinterpret_cast<const Rect2i *>(_data._mem));
} break;
case TRANSFORM2D: {
- return hash_murmur3_32(reinterpret_cast<const Transform2D *>(_data._transform2d), sizeof(Transform2D));
+ uint32_t h = HASH_MURMUR3_SEED;
+ const Transform2D &t = *_data._transform2d;
+ h = hash_murmur3_one_real(t[0].x, h);
+ h = hash_murmur3_one_real(t[0].y, h);
+ h = hash_murmur3_one_real(t[1].x, h);
+ h = hash_murmur3_one_real(t[1].y, h);
+ h = hash_murmur3_one_real(t[2].x, h);
+ h = hash_murmur3_one_real(t[2].y, h);
+
+ return hash_fmix32(h);
} break;
case VECTOR3: {
- return hash_murmur3_32(reinterpret_cast<const Vector3 *>(_data._mem), sizeof(Vector3));
+ return HashMapHasherDefault::hash(*reinterpret_cast<const Vector3 *>(_data._mem));
} break;
case VECTOR3I: {
- return hash_murmur3_32(reinterpret_cast<const Vector3i *>(_data._mem), sizeof(Vector3i));
+ return HashMapHasherDefault::hash(*reinterpret_cast<const Vector3i *>(_data._mem));
} break;
case PLANE: {
- return hash_murmur3_32(reinterpret_cast<const Plane *>(_data._mem), sizeof(Plane));
+ uint32_t h = HASH_MURMUR3_SEED;
+ const Plane &p = *reinterpret_cast<const Plane *>(_data._mem);
+ h = hash_murmur3_one_real(p.normal.x, h);
+ h = hash_murmur3_one_real(p.normal.y, h);
+ h = hash_murmur3_one_real(p.normal.z, h);
+ h = hash_murmur3_one_real(p.d, h);
+ return hash_fmix32(h);
} break;
case AABB: {
- return hash_murmur3_32(_data._aabb, sizeof(AABB));
+ return HashMapHasherDefault::hash(*_data._aabb);
} break;
case QUATERNION: {
- return hash_murmur3_32(reinterpret_cast<const Quaternion *>(_data._mem), sizeof(Quaternion));
+ uint32_t h = HASH_MURMUR3_SEED;
+ const Quaternion &q = *reinterpret_cast<const Quaternion *>(_data._mem);
+ h = hash_murmur3_one_real(q.x, h);
+ h = hash_murmur3_one_real(q.y, h);
+ h = hash_murmur3_one_real(q.z, h);
+ h = hash_murmur3_one_real(q.w, h);
+ return hash_fmix32(h);
} break;
case BASIS: {
- return hash_murmur3_32(_data._basis, sizeof(Basis));
+ uint32_t h = HASH_MURMUR3_SEED;
+ const Basis &b = *_data._basis;
+ h = hash_murmur3_one_real(b[0].x, h);
+ h = hash_murmur3_one_real(b[0].y, h);
+ h = hash_murmur3_one_real(b[0].z, h);
+ h = hash_murmur3_one_real(b[1].x, h);
+ h = hash_murmur3_one_real(b[1].y, h);
+ h = hash_murmur3_one_real(b[1].z, h);
+ h = hash_murmur3_one_real(b[2].x, h);
+ h = hash_murmur3_one_real(b[2].y, h);
+ h = hash_murmur3_one_real(b[2].z, h);
+ return hash_fmix32(h);
} break;
case TRANSFORM3D: {
- return hash_murmur3_32(_data._transform3d, sizeof(Transform3D));
+ uint32_t h = HASH_MURMUR3_SEED;
+ const Transform3D &t = *_data._transform3d;
+ h = hash_murmur3_one_real(t.basis[0].x, h);
+ h = hash_murmur3_one_real(t.basis[0].y, h);
+ h = hash_murmur3_one_real(t.basis[0].z, h);
+ h = hash_murmur3_one_real(t.basis[1].x, h);
+ h = hash_murmur3_one_real(t.basis[1].y, h);
+ h = hash_murmur3_one_real(t.basis[1].z, h);
+ h = hash_murmur3_one_real(t.basis[2].x, h);
+ h = hash_murmur3_one_real(t.basis[2].y, h);
+ h = hash_murmur3_one_real(t.basis[2].z, h);
+ h = hash_murmur3_one_real(t.origin.x, h);
+ h = hash_murmur3_one_real(t.origin.y, h);
+ h = hash_murmur3_one_real(t.origin.z, h);
+ return hash_fmix32(h);
} break;
// misc types
case COLOR: {
- return hash_murmur3_32(reinterpret_cast<const Color *>(_data._mem), sizeof(Color));
+ uint32_t h = HASH_MURMUR3_SEED;
+ const Color &c = *reinterpret_cast<const Color *>(_data._mem);
+ h = hash_murmur3_one_float(c.r, h);
+ h = hash_murmur3_one_float(c.g, h);
+ h = hash_murmur3_one_float(c.b, h);
+ h = hash_murmur3_one_float(c.a, h);
+ return hash_fmix32(h);
} break;
case RID: {
return hash_one_uint64(reinterpret_cast<const ::RID *>(_data._mem)->get_id());
} break;
case OBJECT: {
- return hash_one_uint64(make_uint64_t(_get_obj().obj));
+ return hash_one_uint64(hash_make_uint64_t(_get_obj().obj));
} break;
case STRING_NAME: {
return reinterpret_cast<const StringName *>(_data._mem)->hash();
@@ -2850,7 +2902,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
case SIGNAL: {
const Signal &s = *reinterpret_cast<const Signal *>(_data._mem);
uint32_t hash = s.get_name().hash();
- return hash_djb2_one_64(s.get_object_id(), hash);
+ return hash_murmur3_one_64(s.get_object_id(), hash);
} break;
case ARRAY: {
const Array &arr = *reinterpret_cast<const Array *>(_data._mem);
@@ -2862,9 +2914,9 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
int len = arr.size();
if (likely(len)) {
const uint8_t *r = arr.ptr();
- return hash_murmur3_32((uint8_t *)&r[0], len);
+ return hash_murmur3_buffer((uint8_t *)&r[0], len);
} else {
- return hash_djb2_one_64(0);
+ return hash_murmur3_one_64(0);
}
} break;
@@ -2873,9 +2925,9 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
int len = arr.size();
if (likely(len)) {
const int32_t *r = arr.ptr();
- return hash_murmur3_32((uint8_t *)&r[0], len * sizeof(int32_t));
+ return hash_murmur3_buffer((uint8_t *)&r[0], len * sizeof(int32_t));
} else {
- return hash_djb2_one_64(0);
+ return hash_murmur3_one_64(0);
}
} break;
@@ -2884,9 +2936,9 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
int len = arr.size();
if (likely(len)) {
const int64_t *r = arr.ptr();
- return hash_murmur3_32((uint8_t *)&r[0], len * sizeof(int64_t));
+ return hash_murmur3_buffer((uint8_t *)&r[0], len * sizeof(int64_t));
} else {
- return hash_djb2_one_64(0);
+ return hash_murmur3_one_64(0);
}
} break;
@@ -2896,9 +2948,13 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
if (likely(len)) {
const float *r = arr.ptr();
- return hash_murmur3_32((uint8_t *)&r[0], len * sizeof(float));
+ uint32_t h = HASH_MURMUR3_SEED;
+ for (int32_t i = 0; i < len; i++) {
+ h = hash_murmur3_one_float(r[i], h);
+ }
+ return hash_fmix32(h);
} else {
- return hash_djb2_one_float(0.0);
+ return hash_murmur3_one_float(0.0);
}
} break;
@@ -2908,14 +2964,18 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
if (likely(len)) {
const double *r = arr.ptr();
- return hash_murmur3_32((uint8_t *)&r[0], len * sizeof(double));
+ uint32_t h = HASH_MURMUR3_SEED;
+ for (int32_t i = 0; i < len; i++) {
+ h = hash_murmur3_one_double(r[i], h);
+ }
+ return hash_fmix32(h);
} else {
- return hash_djb2_one_float(0.0);
+ return hash_murmur3_one_float(0.0);
}
} break;
case PACKED_STRING_ARRAY: {
- uint32_t hash = 5831;
+ uint32_t hash = HASH_MURMUR3_SEED;
const Vector<String> &arr = PackedArrayRef<String>::get_array(_data.packed_array);
int len = arr.size();
@@ -2923,14 +2983,15 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
const String *r = arr.ptr();
for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_32(r[i].hash(), hash);
+ hash = hash_murmur3_one_32(r[i].hash(), hash);
}
+ hash = hash_fmix32(hash);
}
return hash;
} break;
case PACKED_VECTOR2_ARRAY: {
- uint32_t hash = 5831;
+ uint32_t hash = HASH_MURMUR3_SEED;
const Vector<Vector2> &arr = PackedArrayRef<Vector2>::get_array(_data.packed_array);
int len = arr.size();
@@ -2938,15 +2999,16 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
const Vector2 *r = arr.ptr();
for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_float(r[i].x, hash);
- hash = hash_djb2_one_float(r[i].y, hash);
+ hash = hash_murmur3_one_real(r[i].x, hash);
+ hash = hash_murmur3_one_real(r[i].y, hash);
}
+ hash = hash_fmix32(hash);
}
return hash;
} break;
case PACKED_VECTOR3_ARRAY: {
- uint32_t hash = 5831;
+ uint32_t hash = HASH_MURMUR3_SEED;
const Vector<Vector3> &arr = PackedArrayRef<Vector3>::get_array(_data.packed_array);
int len = arr.size();
@@ -2954,16 +3016,17 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
const Vector3 *r = arr.ptr();
for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_float(r[i].x, hash);
- hash = hash_djb2_one_float(r[i].y, hash);
- hash = hash_djb2_one_float(r[i].z, hash);
+ hash = hash_murmur3_one_real(r[i].x, hash);
+ hash = hash_murmur3_one_real(r[i].y, hash);
+ hash = hash_murmur3_one_real(r[i].z, hash);
}
+ hash = hash_fmix32(hash);
}
return hash;
} break;
case PACKED_COLOR_ARRAY: {
- uint32_t hash = 5831;
+ uint32_t hash = HASH_MURMUR3_SEED;
const Vector<Color> &arr = PackedArrayRef<Color>::get_array(_data.packed_array);
int len = arr.size();
@@ -2971,11 +3034,12 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
const Color *r = arr.ptr();
for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_float(r[i].r, hash);
- hash = hash_djb2_one_float(r[i].g, hash);
- hash = hash_djb2_one_float(r[i].b, hash);
- hash = hash_djb2_one_float(r[i].a, hash);
+ hash = hash_murmur3_one_float(r[i].r, hash);
+ hash = hash_murmur3_one_float(r[i].g, hash);
+ hash = hash_murmur3_one_float(r[i].b, hash);
+ hash = hash_murmur3_one_float(r[i].a, hash);
}
+ hash = hash_fmix32(hash);
}
return hash;
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 6e8dc64811..cb9dfe478b 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1170,19 +1170,19 @@ uint32_t Variant::get_builtin_method_hash(Variant::Type p_type, const StringName
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, 0);
const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method);
ERR_FAIL_COND_V(!method, 0);
- uint32_t hash = hash_djb2_one_32(method->is_const);
- hash = hash_djb2_one_32(method->is_static, hash);
- hash = hash_djb2_one_32(method->is_vararg, hash);
- hash = hash_djb2_one_32(method->has_return_type, hash);
+ uint32_t hash = hash_murmur3_one_32(method->is_const);
+ hash = hash_murmur3_one_32(method->is_static, hash);
+ hash = hash_murmur3_one_32(method->is_vararg, hash);
+ hash = hash_murmur3_one_32(method->has_return_type, hash);
if (method->has_return_type) {
- hash = hash_djb2_one_32(method->return_type, hash);
+ hash = hash_murmur3_one_32(method->return_type, hash);
}
- hash = hash_djb2_one_32(method->argument_count, hash);
+ hash = hash_murmur3_one_32(method->argument_count, hash);
for (int i = 0; i < method->argument_count; i++) {
- hash = method->get_argument_type(i);
+ hash = hash_murmur3_one_32(method->get_argument_type(i), hash);
}
- return hash;
+ return hash_fmix32(hash);
}
void Variant::get_method_list(List<MethodInfo> *p_list) const {
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index 66badce268..7fabdcbc82 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -1423,17 +1423,17 @@ uint32_t Variant::get_utility_function_hash(const StringName &p_name) {
const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name);
ERR_FAIL_COND_V(!bfi, 0);
- uint32_t hash = hash_djb2_one_32(bfi->is_vararg);
- hash = hash_djb2_one_32(bfi->returns_value, hash);
+ uint32_t hash = hash_murmur3_one_32(bfi->is_vararg);
+ hash = hash_murmur3_one_32(bfi->returns_value, hash);
if (bfi->returns_value) {
- hash = hash_djb2_one_32(bfi->return_type, hash);
+ hash = hash_murmur3_one_32(bfi->return_type, hash);
}
- hash = hash_djb2_one_32(bfi->argcount, hash);
+ hash = hash_murmur3_one_32(bfi->argcount, hash);
for (int i = 0; i < bfi->argcount; i++) {
- hash = hash_djb2_one_32(bfi->get_arg_type(i), hash);
+ hash = hash_murmur3_one_32(bfi->get_arg_type(i), hash);
}
- return hash;
+ return hash_fmix32(hash);
}
void Variant::get_utility_function_list(List<StringName> *r_functions) {