Browse Source

-Fixes to how hashing happened, now StringName and NodePath use default hasher, this was leading to some severe slowdown in scenarios
-Fixes to some duplication scenarios for instanced scenes

Juan Linietsky 7 years ago
parent
commit
2dc738ce27

+ 3 - 3
core/class_db.cpp

@@ -248,9 +248,9 @@ void ClassDB::set_current_api(APIType p_api) {
 	current_api = p_api;
 }
 
-HashMap<StringName, ClassDB::ClassInfo, StringNameHasher> ClassDB::classes;
-HashMap<StringName, StringName, StringNameHasher> ClassDB::resource_base_extensions;
-HashMap<StringName, StringName, StringNameHasher> ClassDB::compat_classes;
+HashMap<StringName, ClassDB::ClassInfo> ClassDB::classes;
+HashMap<StringName, StringName> ClassDB::resource_base_extensions;
+HashMap<StringName, StringName> ClassDB::compat_classes;
 
 ClassDB::ClassInfo::ClassInfo() {
 

+ 7 - 7
core/class_db.h

@@ -114,10 +114,10 @@ public:
 
 		APIType api;
 		ClassInfo *inherits_ptr;
-		HashMap<StringName, MethodBind *, StringNameHasher> method_map;
-		HashMap<StringName, int, StringNameHasher> constant_map;
+		HashMap<StringName, MethodBind *> method_map;
+		HashMap<StringName, int> constant_map;
 		HashMap<StringName, List<StringName> > enum_map;
-		HashMap<StringName, MethodInfo, StringNameHasher> signal_map;
+		HashMap<StringName, MethodInfo> signal_map;
 		List<PropertyInfo> property_list;
 #ifdef DEBUG_METHODS_ENABLED
 		List<StringName> constant_order;
@@ -126,7 +126,7 @@ public:
 		List<MethodInfo> virtual_methods;
 		StringName category;
 #endif
-		HashMap<StringName, PropertySetGet, StringNameHasher> property_setget;
+		HashMap<StringName, PropertySetGet> property_setget;
 
 		StringName inherits;
 		StringName name;
@@ -143,9 +143,9 @@ public:
 	}
 
 	static RWLock *lock;
-	static HashMap<StringName, ClassInfo, StringNameHasher> classes;
-	static HashMap<StringName, StringName, StringNameHasher> resource_base_extensions;
-	static HashMap<StringName, StringName, StringNameHasher> compat_classes;
+	static HashMap<StringName, ClassInfo> classes;
+	static HashMap<StringName, StringName> resource_base_extensions;
+	static HashMap<StringName, StringName> 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);

+ 7 - 0
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); }
 };
 

+ 26 - 11
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;
+	}
+
+	int subpath_size = data->subpath.size();
 
-	if (data->subpath.size() != p_path.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();
+
+	for (int i = 0; i < path_size; i++) {
 
-		if (data->path[i] != p_path.data->path[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();
+
+	for (int i = 0; i < subpath_size; i++) {
 
-		if (data->subpath[i] != p_path.data->subpath[i])
+		if (l_subpath_ptr[i] != r_subpath_ptr[i])
 			return false;
 	}
 
@@ -286,6 +297,7 @@ NodePath::NodePath(const Vector<StringName> &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<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) {
@@ -301,6 +313,7 @@ NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &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;

+ 13 - 2
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;

+ 2 - 1
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<StringName, Signal, StringNameHasher> signal_map;
+	HashMap<StringName, Signal> signal_map;
 	List<Connection> connections;
 #ifdef DEBUG_ENABLED
 	SafeRefCount _lock_index;

+ 11 - 6
core/resource.cpp

@@ -225,15 +225,20 @@ Ref<Resource> 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<Resource>(r);

+ 0 - 6
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

+ 9 - 2
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> resource = _get_obj().ref;
+				if (resource.is_valid()) {
+					return resource->duplicate(true);
+				}
+			}
+			return *this;
+		} break;
 		case DICTIONARY:
 			return operator Dictionary().duplicate(deep);
 		case ARRAY:

+ 1 - 1
modules/visual_script/visual_script_editor.h

@@ -137,7 +137,7 @@ class VisualScriptEditor : public ScriptEditorBase {
 		Vector<Pair<Variant::Type, String> > args;
 	};
 
-	HashMap<StringName, Ref<StyleBox>, StringNameHasher> node_styles;
+	HashMap<StringName, Ref<StyleBox> > node_styles;
 	StringName edited_func;
 
 	void _update_graph_connections();

+ 1 - 0
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);
 

+ 6 - 6
scene/gui/control.h

@@ -202,12 +202,12 @@ private:
 		NodePath focus_next;
 		NodePath focus_prev;
 
-		HashMap<StringName, Ref<Texture>, StringNameHasher> icon_override;
-		HashMap<StringName, Ref<Shader>, StringNameHasher> shader_override;
-		HashMap<StringName, Ref<StyleBox>, StringNameHasher> style_override;
-		HashMap<StringName, Ref<Font>, StringNameHasher> font_override;
-		HashMap<StringName, Color, StringNameHasher> color_override;
-		HashMap<StringName, int, StringNameHasher> constant_override;
+		HashMap<StringName, Ref<Texture> > icon_override;
+		HashMap<StringName, Ref<Shader> > shader_override;
+		HashMap<StringName, Ref<StyleBox> > style_override;
+		HashMap<StringName, Ref<Font> > font_override;
+		HashMap<StringName, Color> color_override;
+		HashMap<StringName, int> constant_override;
 		Map<Ref<Font>, int> font_refcount;
 
 	} data;

+ 2 - 1
scene/main/node.cpp

@@ -1934,8 +1934,9 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
 			if (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE) {
 
 				Resource *res = Object::cast_to<Resource>(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 {
 

+ 6 - 6
scene/resources/theme.h

@@ -55,12 +55,12 @@ class Theme : public Resource {
 	void _unref_font(Ref<Font> p_sc);
 	void _emit_theme_changed();
 
-	HashMap<StringName, HashMap<StringName, Ref<Texture>, StringNameHasher>, StringNameHasher> icon_map;
-	HashMap<StringName, HashMap<StringName, Ref<StyleBox>, StringNameHasher>, StringNameHasher> style_map;
-	HashMap<StringName, HashMap<StringName, Ref<Font>, StringNameHasher>, StringNameHasher> font_map;
-	HashMap<StringName, HashMap<StringName, Ref<Shader>, StringNameHasher>, StringNameHasher> shader_map;
-	HashMap<StringName, HashMap<StringName, Color, StringNameHasher>, StringNameHasher> color_map;
-	HashMap<StringName, HashMap<StringName, int, StringNameHasher>, StringNameHasher> constant_map;
+	HashMap<StringName, HashMap<StringName, Ref<Texture> > > icon_map;
+	HashMap<StringName, HashMap<StringName, Ref<StyleBox> > > style_map;
+	HashMap<StringName, HashMap<StringName, Ref<Font> > > font_map;
+	HashMap<StringName, HashMap<StringName, Ref<Shader> > > shader_map;
+	HashMap<StringName, HashMap<StringName, Color> > color_map;
+	HashMap<StringName, HashMap<StringName, int> > constant_map;
 
 protected:
 	bool _set(const StringName &p_name, const Variant &p_value);