diff --git a/core/class_db.cpp b/core/class_db.cpp index 59b100e282a..f97eaf6099e 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -248,9 +248,9 @@ void ClassDB::set_current_api(APIType p_api) { current_api = p_api; } -HashMap ClassDB::classes; -HashMap ClassDB::resource_base_extensions; -HashMap ClassDB::compat_classes; +HashMap ClassDB::classes; +HashMap ClassDB::resource_base_extensions; +HashMap ClassDB::compat_classes; ClassDB::ClassInfo::ClassInfo() { diff --git a/core/class_db.h b/core/class_db.h index 2c77ffe65f1..f1d18792360 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -114,10 +114,10 @@ public: APIType api; ClassInfo *inherits_ptr; - HashMap method_map; - HashMap constant_map; + HashMap method_map; + HashMap constant_map; HashMap > enum_map; - HashMap signal_map; + HashMap signal_map; List property_list; #ifdef DEBUG_METHODS_ENABLED List constant_order; @@ -126,7 +126,7 @@ public: List virtual_methods; StringName category; #endif - HashMap property_setget; + HashMap property_setget; StringName inherits; StringName name; @@ -143,9 +143,9 @@ public: } static RWLock *lock; - static HashMap classes; - static HashMap resource_base_extensions; - static HashMap compat_classes; + static HashMap classes; + static HashMap resource_base_extensions; + static HashMap compat_classes; #ifdef DEBUG_METHODS_ENABLED static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount); diff --git a/core/hashfuncs.h b/core/hashfuncs.h index ae99fa39c87..735e679d1e3 100644 --- a/core/hashfuncs.h +++ b/core/hashfuncs.h @@ -33,6 +33,8 @@ #include "math_defs.h" #include "math_funcs.h" +#include "node_path.h" +#include "string_db.h" #include "typedefs.h" #include "ustring.h" @@ -131,6 +133,7 @@ static inline uint64_t make_uint64_t(T p_in) { } 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 uint64_t p_int) { return hash_one_uint64(p_int); } @@ -145,6 +148,10 @@ struct HashMapHasherDefault { static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; } static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; } static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; } + + 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(); } + //static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); } }; diff --git a/core/node_path.cpp b/core/node_path.cpp index 64983fc0916..487d5ee8c6f 100644 --- a/core/node_path.cpp +++ b/core/node_path.cpp @@ -32,10 +32,7 @@ #include "print_string.h" -uint32_t NodePath::hash() const { - - if (!data) - return 0; +void NodePath::_update_hash_cache() const { uint32_t h = data->absolute ? 1 : 0; int pc = data->path.size(); @@ -49,13 +46,15 @@ uint32_t NodePath::hash() const { h = h ^ ssn[i].hash(); } - return h; + data->hash_cache_valid = true; + data->hash_cache = h; } void NodePath::prepend_period() { if (data->path.size() && data->path[0].operator String() != ".") { data->path.insert(0, "."); + data->hash_cache_valid = false; } } @@ -114,21 +113,33 @@ bool NodePath::operator==(const NodePath &p_path) const { if (data->absolute != p_path.data->absolute) return false; - if (data->path.size() != p_path.data->path.size()) + int path_size = data->path.size(); + + if (path_size != p_path.data->path.size()) { return false; + } - if (data->subpath.size() != p_path.data->subpath.size()) + int subpath_size = data->subpath.size(); + + if (subpath_size != p_path.data->subpath.size()) { return false; + } - for (int i = 0; i < data->path.size(); i++) { + const StringName *l_path_ptr = data->path.ptr(); + const StringName *r_path_ptr = p_path.data->path.ptr(); - if (data->path[i] != p_path.data->path[i]) + for (int i = 0; i < path_size; i++) { + + if (l_path_ptr[i] != r_path_ptr[i]) return false; } - for (int i = 0; i < data->subpath.size(); i++) { + const StringName *l_subpath_ptr = data->subpath.ptr(); + const StringName *r_subpath_ptr = p_path.data->subpath.ptr(); - if (data->subpath[i] != p_path.data->subpath[i]) + for (int i = 0; i < subpath_size; i++) { + + if (l_subpath_ptr[i] != r_subpath_ptr[i]) return false; } @@ -286,6 +297,7 @@ NodePath::NodePath(const Vector &p_path, bool p_absolute) { data->absolute = p_absolute; data->path = p_path; data->has_slashes = true; + data->hash_cache_valid = false; } NodePath::NodePath(const Vector &p_path, const Vector &p_subpath, bool p_absolute) { @@ -301,6 +313,7 @@ NodePath::NodePath(const Vector &p_path, const Vector &p data->path = p_path; data->subpath = p_subpath; data->has_slashes = true; + data->hash_cache_valid = false; } void NodePath::simplify() { @@ -324,6 +337,7 @@ void NodePath::simplify() { } } } + data->hash_cache_valid = false; } NodePath NodePath::simplified() const { @@ -396,6 +410,7 @@ NodePath::NodePath(const String &p_path) { data->absolute = absolute ? true : false; data->has_slashes = has_slashes; data->subpath = subpath; + data->hash_cache_valid = false; if (slices == 0) return; diff --git a/core/node_path.h b/core/node_path.h index 288f39721f8..71235029afd 100644 --- a/core/node_path.h +++ b/core/node_path.h @@ -47,11 +47,15 @@ class NodePath { StringName concatenated_subpath; bool absolute; bool has_slashes; + mutable bool hash_cache_valid; + mutable uint32_t hash_cache; }; - Data *data; + mutable Data *data; void unref(); + void _update_hash_cache() const; + public: _FORCE_INLINE_ StringName get_sname() const { @@ -78,7 +82,14 @@ public: NodePath get_parent() const; - uint32_t hash() const; + _FORCE_INLINE_ uint32_t hash() const { + if (!data) + return 0; + if (!data->hash_cache_valid) { + _update_hash_cache(); + } + return data->hash_cache; + } operator String() const; bool is_empty() const; diff --git a/core/object.h b/core/object.h index badb432885a..8dc3426d1d5 100644 --- a/core/object.h +++ b/core/object.h @@ -31,6 +31,7 @@ #ifndef OBJECT_H #define OBJECT_H +#include "hash_map.h" #include "list.h" #include "map.h" #include "os/rw_lock.h" @@ -451,7 +452,7 @@ private: Signal() { lock = 0; } }; - HashMap signal_map; + HashMap signal_map; List connections; #ifdef DEBUG_ENABLED SafeRefCount _lock_index; diff --git a/core/resource.cpp b/core/resource.cpp index 4cca73be5dc..87ff4d3c2a1 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -225,15 +225,20 @@ Ref Resource::duplicate(bool p_subresources) const { if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) continue; - Variant p = get(E->get().name).duplicate(true); - if (p.get_type() == Variant::OBJECT && p_subresources) { + Variant p = get(E->get().name); + + if ((p.get_type() == Variant::DICTIONARY || p.get_type() == Variant::ARRAY)) { + p = p.duplicate(p_subresources); //does not make a long of sense but should work? + } else if (p.get_type() == Variant::OBJECT && (p_subresources || (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE))) { RES sr = p; - if (sr.is_valid()) - p = sr->duplicate(true); - } + if (sr.is_valid()) { + r->set(E->get().name, sr->duplicate(p_subresources)); + } + } else { - r->set(E->get().name, p); + r->set(E->get().name, p); + } } return Ref(r); diff --git a/core/string_db.h b/core/string_db.h index 01d1ca4033b..965385b136d 100644 --- a/core/string_db.h +++ b/core/string_db.h @@ -31,7 +31,6 @@ #ifndef STRING_DB_H #define STRING_DB_H -#include "hash_map.h" #include "os/mutex.h" #include "safe_refcount.h" #include "ustring.h" @@ -168,11 +167,6 @@ public: ~StringName(); }; -struct StringNameHasher { - - static _FORCE_INLINE_ uint32_t hash(const StringName &p_string) { return p_string.hash(); } -}; - StringName _scs_create(const char *p_chr); #endif diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 621af2dfb77..983c3e18bc9 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -3417,8 +3417,15 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { Variant Variant::duplicate(bool deep) const { switch (type) { - // case OBJECT: - // return operator Object *()->duplicate(); + case OBJECT: { + if (deep && !_get_obj().ref.is_null()) { + Ref resource = _get_obj().ref; + if (resource.is_valid()) { + return resource->duplicate(true); + } + } + return *this; + } break; case DICTIONARY: return operator Dictionary().duplicate(deep); case ARRAY: diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index 72b5e092229..0bd64d6a1d3 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -137,7 +137,7 @@ class VisualScriptEditor : public ScriptEditorBase { Vector > args; }; - HashMap, StringNameHasher> node_styles; + HashMap > node_styles; StringName edited_func; void _update_graph_connections(); diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 946a1246ffa..6dcd5ca8ea1 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -1036,6 +1036,7 @@ bool AnimationNodeBlendTree::_set(const StringName &p_name, const Variant &p_val String name = p_name; if (name.begins_with("nodes/")) { + String node_name = name.get_slicec('/', 1); String what = name.get_slicec('/', 2); diff --git a/scene/gui/control.h b/scene/gui/control.h index 9124256624c..633f92f7336 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -202,12 +202,12 @@ private: NodePath focus_next; NodePath focus_prev; - HashMap, StringNameHasher> icon_override; - HashMap, StringNameHasher> shader_override; - HashMap, StringNameHasher> style_override; - HashMap, StringNameHasher> font_override; - HashMap color_override; - HashMap constant_override; + HashMap > icon_override; + HashMap > shader_override; + HashMap > style_override; + HashMap > font_override; + HashMap color_override; + HashMap constant_override; Map, int> font_refcount; } data; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 4dc7b03685c..6199f52ec5e 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1934,8 +1934,9 @@ Node *Node::_duplicate(int p_flags, Map *r_duplimap) const if (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE) { Resource *res = Object::cast_to(value); - if (res) // Duplicate only if it's a resource + if (res) { // Duplicate only if it's a resource current_node->set(name, res->duplicate()); + } } else { diff --git a/scene/resources/theme.h b/scene/resources/theme.h index c23f237c756..e0d4038e7e4 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -55,12 +55,12 @@ class Theme : public Resource { void _unref_font(Ref p_sc); void _emit_theme_changed(); - HashMap, StringNameHasher>, StringNameHasher> icon_map; - HashMap, StringNameHasher>, StringNameHasher> style_map; - HashMap, StringNameHasher>, StringNameHasher> font_map; - HashMap, StringNameHasher>, StringNameHasher> shader_map; - HashMap, StringNameHasher> color_map; - HashMap, StringNameHasher> constant_map; + HashMap > > icon_map; + HashMap > > style_map; + HashMap > > font_map; + HashMap > > shader_map; + HashMap > color_map; + HashMap > constant_map; protected: bool _set(const StringName &p_name, const Variant &p_value);