-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
This commit is contained in:
parent
ecee0c92ff
commit
2dc738ce27
|
@ -248,9 +248,9 @@ void ClassDB::set_current_api(APIType p_api) {
|
||||||
current_api = p_api;
|
current_api = p_api;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap<StringName, ClassDB::ClassInfo, StringNameHasher> ClassDB::classes;
|
HashMap<StringName, ClassDB::ClassInfo> ClassDB::classes;
|
||||||
HashMap<StringName, StringName, StringNameHasher> ClassDB::resource_base_extensions;
|
HashMap<StringName, StringName> ClassDB::resource_base_extensions;
|
||||||
HashMap<StringName, StringName, StringNameHasher> ClassDB::compat_classes;
|
HashMap<StringName, StringName> ClassDB::compat_classes;
|
||||||
|
|
||||||
ClassDB::ClassInfo::ClassInfo() {
|
ClassDB::ClassInfo::ClassInfo() {
|
||||||
|
|
||||||
|
|
|
@ -114,10 +114,10 @@ public:
|
||||||
|
|
||||||
APIType api;
|
APIType api;
|
||||||
ClassInfo *inherits_ptr;
|
ClassInfo *inherits_ptr;
|
||||||
HashMap<StringName, MethodBind *, StringNameHasher> method_map;
|
HashMap<StringName, MethodBind *> method_map;
|
||||||
HashMap<StringName, int, StringNameHasher> constant_map;
|
HashMap<StringName, int> constant_map;
|
||||||
HashMap<StringName, List<StringName> > enum_map;
|
HashMap<StringName, List<StringName> > enum_map;
|
||||||
HashMap<StringName, MethodInfo, StringNameHasher> signal_map;
|
HashMap<StringName, MethodInfo> signal_map;
|
||||||
List<PropertyInfo> property_list;
|
List<PropertyInfo> property_list;
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
#ifdef DEBUG_METHODS_ENABLED
|
||||||
List<StringName> constant_order;
|
List<StringName> constant_order;
|
||||||
|
@ -126,7 +126,7 @@ public:
|
||||||
List<MethodInfo> virtual_methods;
|
List<MethodInfo> virtual_methods;
|
||||||
StringName category;
|
StringName category;
|
||||||
#endif
|
#endif
|
||||||
HashMap<StringName, PropertySetGet, StringNameHasher> property_setget;
|
HashMap<StringName, PropertySetGet> property_setget;
|
||||||
|
|
||||||
StringName inherits;
|
StringName inherits;
|
||||||
StringName name;
|
StringName name;
|
||||||
|
@ -143,9 +143,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static RWLock *lock;
|
static RWLock *lock;
|
||||||
static HashMap<StringName, ClassInfo, StringNameHasher> classes;
|
static HashMap<StringName, ClassInfo> classes;
|
||||||
static HashMap<StringName, StringName, StringNameHasher> resource_base_extensions;
|
static HashMap<StringName, StringName> resource_base_extensions;
|
||||||
static HashMap<StringName, StringName, StringNameHasher> compat_classes;
|
static HashMap<StringName, StringName> compat_classes;
|
||||||
|
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
#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);
|
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount);
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
|
|
||||||
#include "math_defs.h"
|
#include "math_defs.h"
|
||||||
#include "math_funcs.h"
|
#include "math_funcs.h"
|
||||||
|
#include "node_path.h"
|
||||||
|
#include "string_db.h"
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
#include "ustring.h"
|
#include "ustring.h"
|
||||||
|
|
||||||
|
@ -131,6 +133,7 @@ static inline uint64_t make_uint64_t(T p_in) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HashMapHasherDefault {
|
struct HashMapHasherDefault {
|
||||||
|
|
||||||
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
|
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 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); }
|
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 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 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 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); }
|
//static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,7 @@
|
||||||
|
|
||||||
#include "print_string.h"
|
#include "print_string.h"
|
||||||
|
|
||||||
uint32_t NodePath::hash() const {
|
void NodePath::_update_hash_cache() const {
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
uint32_t h = data->absolute ? 1 : 0;
|
uint32_t h = data->absolute ? 1 : 0;
|
||||||
int pc = data->path.size();
|
int pc = data->path.size();
|
||||||
|
@ -49,13 +46,15 @@ uint32_t NodePath::hash() const {
|
||||||
h = h ^ ssn[i].hash();
|
h = h ^ ssn[i].hash();
|
||||||
}
|
}
|
||||||
|
|
||||||
return h;
|
data->hash_cache_valid = true;
|
||||||
|
data->hash_cache = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodePath::prepend_period() {
|
void NodePath::prepend_period() {
|
||||||
|
|
||||||
if (data->path.size() && data->path[0].operator String() != ".") {
|
if (data->path.size() && data->path[0].operator String() != ".") {
|
||||||
data->path.insert(0, ".");
|
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)
|
if (data->absolute != p_path.data->absolute)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (data->path.size() != p_path.data->path.size())
|
int path_size = data->path.size();
|
||||||
return false;
|
|
||||||
|
|
||||||
if (data->subpath.size() != p_path.data->subpath.size())
|
if (path_size != p_path.data->path.size()) {
|
||||||
return false;
|
|
||||||
|
|
||||||
for (int i = 0; i < data->path.size(); i++) {
|
|
||||||
|
|
||||||
if (data->path[i] != p_path.data->path[i])
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < data->subpath.size(); i++) {
|
int subpath_size = data->subpath.size();
|
||||||
|
|
||||||
if (data->subpath[i] != p_path.data->subpath[i])
|
if (subpath_size != p_path.data->subpath.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (l_path_ptr[i] != r_path_ptr[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (l_subpath_ptr[i] != r_subpath_ptr[i])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,6 +297,7 @@ NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
|
||||||
data->absolute = p_absolute;
|
data->absolute = p_absolute;
|
||||||
data->path = p_path;
|
data->path = p_path;
|
||||||
data->has_slashes = true;
|
data->has_slashes = true;
|
||||||
|
data->hash_cache_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) {
|
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->path = p_path;
|
||||||
data->subpath = p_subpath;
|
data->subpath = p_subpath;
|
||||||
data->has_slashes = true;
|
data->has_slashes = true;
|
||||||
|
data->hash_cache_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodePath::simplify() {
|
void NodePath::simplify() {
|
||||||
|
@ -324,6 +337,7 @@ void NodePath::simplify() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
data->hash_cache_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodePath NodePath::simplified() const {
|
NodePath NodePath::simplified() const {
|
||||||
|
@ -396,6 +410,7 @@ NodePath::NodePath(const String &p_path) {
|
||||||
data->absolute = absolute ? true : false;
|
data->absolute = absolute ? true : false;
|
||||||
data->has_slashes = has_slashes;
|
data->has_slashes = has_slashes;
|
||||||
data->subpath = subpath;
|
data->subpath = subpath;
|
||||||
|
data->hash_cache_valid = false;
|
||||||
|
|
||||||
if (slices == 0)
|
if (slices == 0)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -47,11 +47,15 @@ class NodePath {
|
||||||
StringName concatenated_subpath;
|
StringName concatenated_subpath;
|
||||||
bool absolute;
|
bool absolute;
|
||||||
bool has_slashes;
|
bool has_slashes;
|
||||||
|
mutable bool hash_cache_valid;
|
||||||
|
mutable uint32_t hash_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
Data *data;
|
mutable Data *data;
|
||||||
void unref();
|
void unref();
|
||||||
|
|
||||||
|
void _update_hash_cache() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
_FORCE_INLINE_ StringName get_sname() const {
|
_FORCE_INLINE_ StringName get_sname() const {
|
||||||
|
|
||||||
|
@ -78,7 +82,14 @@ public:
|
||||||
|
|
||||||
NodePath get_parent() const;
|
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;
|
operator String() const;
|
||||||
bool is_empty() const;
|
bool is_empty() const;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#ifndef OBJECT_H
|
#ifndef OBJECT_H
|
||||||
#define OBJECT_H
|
#define OBJECT_H
|
||||||
|
|
||||||
|
#include "hash_map.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "os/rw_lock.h"
|
#include "os/rw_lock.h"
|
||||||
|
@ -451,7 +452,7 @@ private:
|
||||||
Signal() { lock = 0; }
|
Signal() { lock = 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
HashMap<StringName, Signal, StringNameHasher> signal_map;
|
HashMap<StringName, Signal> signal_map;
|
||||||
List<Connection> connections;
|
List<Connection> connections;
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
SafeRefCount _lock_index;
|
SafeRefCount _lock_index;
|
||||||
|
|
|
@ -225,16 +225,21 @@ Ref<Resource> Resource::duplicate(bool p_subresources) const {
|
||||||
|
|
||||||
if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
|
if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
|
||||||
continue;
|
continue;
|
||||||
Variant p = get(E->get().name).duplicate(true);
|
Variant p = get(E->get().name);
|
||||||
if (p.get_type() == Variant::OBJECT && p_subresources) {
|
|
||||||
|
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;
|
RES sr = p;
|
||||||
if (sr.is_valid())
|
if (sr.is_valid()) {
|
||||||
p = sr->duplicate(true);
|
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);
|
return Ref<Resource>(r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#ifndef STRING_DB_H
|
#ifndef STRING_DB_H
|
||||||
#define STRING_DB_H
|
#define STRING_DB_H
|
||||||
|
|
||||||
#include "hash_map.h"
|
|
||||||
#include "os/mutex.h"
|
#include "os/mutex.h"
|
||||||
#include "safe_refcount.h"
|
#include "safe_refcount.h"
|
||||||
#include "ustring.h"
|
#include "ustring.h"
|
||||||
|
@ -168,11 +167,6 @@ public:
|
||||||
~StringName();
|
~StringName();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StringNameHasher {
|
|
||||||
|
|
||||||
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string) { return p_string.hash(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
StringName _scs_create(const char *p_chr);
|
StringName _scs_create(const char *p_chr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3417,8 +3417,15 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
|
||||||
|
|
||||||
Variant Variant::duplicate(bool deep) const {
|
Variant Variant::duplicate(bool deep) const {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// case OBJECT:
|
case OBJECT: {
|
||||||
// return operator Object *()->duplicate();
|
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:
|
case DICTIONARY:
|
||||||
return operator Dictionary().duplicate(deep);
|
return operator Dictionary().duplicate(deep);
|
||||||
case ARRAY:
|
case ARRAY:
|
||||||
|
|
|
@ -137,7 +137,7 @@ class VisualScriptEditor : public ScriptEditorBase {
|
||||||
Vector<Pair<Variant::Type, String> > args;
|
Vector<Pair<Variant::Type, String> > args;
|
||||||
};
|
};
|
||||||
|
|
||||||
HashMap<StringName, Ref<StyleBox>, StringNameHasher> node_styles;
|
HashMap<StringName, Ref<StyleBox> > node_styles;
|
||||||
StringName edited_func;
|
StringName edited_func;
|
||||||
|
|
||||||
void _update_graph_connections();
|
void _update_graph_connections();
|
||||||
|
|
|
@ -1036,6 +1036,7 @@ bool AnimationNodeBlendTree::_set(const StringName &p_name, const Variant &p_val
|
||||||
|
|
||||||
String name = p_name;
|
String name = p_name;
|
||||||
if (name.begins_with("nodes/")) {
|
if (name.begins_with("nodes/")) {
|
||||||
|
|
||||||
String node_name = name.get_slicec('/', 1);
|
String node_name = name.get_slicec('/', 1);
|
||||||
String what = name.get_slicec('/', 2);
|
String what = name.get_slicec('/', 2);
|
||||||
|
|
||||||
|
|
|
@ -202,12 +202,12 @@ private:
|
||||||
NodePath focus_next;
|
NodePath focus_next;
|
||||||
NodePath focus_prev;
|
NodePath focus_prev;
|
||||||
|
|
||||||
HashMap<StringName, Ref<Texture>, StringNameHasher> icon_override;
|
HashMap<StringName, Ref<Texture> > icon_override;
|
||||||
HashMap<StringName, Ref<Shader>, StringNameHasher> shader_override;
|
HashMap<StringName, Ref<Shader> > shader_override;
|
||||||
HashMap<StringName, Ref<StyleBox>, StringNameHasher> style_override;
|
HashMap<StringName, Ref<StyleBox> > style_override;
|
||||||
HashMap<StringName, Ref<Font>, StringNameHasher> font_override;
|
HashMap<StringName, Ref<Font> > font_override;
|
||||||
HashMap<StringName, Color, StringNameHasher> color_override;
|
HashMap<StringName, Color> color_override;
|
||||||
HashMap<StringName, int, StringNameHasher> constant_override;
|
HashMap<StringName, int> constant_override;
|
||||||
Map<Ref<Font>, int> font_refcount;
|
Map<Ref<Font>, int> font_refcount;
|
||||||
|
|
||||||
} data;
|
} data;
|
||||||
|
|
|
@ -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) {
|
if (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE) {
|
||||||
|
|
||||||
Resource *res = Object::cast_to<Resource>(value);
|
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());
|
current_node->set(name, res->duplicate());
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
@ -55,12 +55,12 @@ class Theme : public Resource {
|
||||||
void _unref_font(Ref<Font> p_sc);
|
void _unref_font(Ref<Font> p_sc);
|
||||||
void _emit_theme_changed();
|
void _emit_theme_changed();
|
||||||
|
|
||||||
HashMap<StringName, HashMap<StringName, Ref<Texture>, StringNameHasher>, StringNameHasher> icon_map;
|
HashMap<StringName, HashMap<StringName, Ref<Texture> > > icon_map;
|
||||||
HashMap<StringName, HashMap<StringName, Ref<StyleBox>, StringNameHasher>, StringNameHasher> style_map;
|
HashMap<StringName, HashMap<StringName, Ref<StyleBox> > > style_map;
|
||||||
HashMap<StringName, HashMap<StringName, Ref<Font>, StringNameHasher>, StringNameHasher> font_map;
|
HashMap<StringName, HashMap<StringName, Ref<Font> > > font_map;
|
||||||
HashMap<StringName, HashMap<StringName, Ref<Shader>, StringNameHasher>, StringNameHasher> shader_map;
|
HashMap<StringName, HashMap<StringName, Ref<Shader> > > shader_map;
|
||||||
HashMap<StringName, HashMap<StringName, Color, StringNameHasher>, StringNameHasher> color_map;
|
HashMap<StringName, HashMap<StringName, Color> > color_map;
|
||||||
HashMap<StringName, HashMap<StringName, int, StringNameHasher>, StringNameHasher> constant_map;
|
HashMap<StringName, HashMap<StringName, int> > constant_map;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool _set(const StringName &p_name, const Variant &p_value);
|
bool _set(const StringName &p_name, const Variant &p_value);
|
||||||
|
|
Loading…
Reference in New Issue