You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-09 12:50:35 +00:00
Always use String as StringName backing internally.
This commit is contained in:
@@ -33,18 +33,8 @@
|
||||
#include "core/os/os.h"
|
||||
#include "core/string/print_string.h"
|
||||
|
||||
StaticCString StaticCString::create(const char *p_ptr) {
|
||||
StaticCString scs;
|
||||
scs.ptr = p_ptr;
|
||||
return scs;
|
||||
}
|
||||
|
||||
bool StringName::_Data::operator==(const String &p_name) const {
|
||||
if (cname) {
|
||||
return p_name == cname;
|
||||
} else {
|
||||
return name == p_name;
|
||||
}
|
||||
return name == p_name;
|
||||
}
|
||||
|
||||
bool StringName::_Data::operator!=(const String &p_name) const {
|
||||
@@ -52,21 +42,13 @@ bool StringName::_Data::operator!=(const String &p_name) const {
|
||||
}
|
||||
|
||||
bool StringName::_Data::operator==(const char *p_name) const {
|
||||
if (cname) {
|
||||
return strcmp(cname, p_name) == 0;
|
||||
} else {
|
||||
return name == p_name;
|
||||
}
|
||||
return name == p_name;
|
||||
}
|
||||
|
||||
bool StringName::_Data::operator!=(const char *p_name) const {
|
||||
return !operator==(p_name);
|
||||
}
|
||||
|
||||
StringName _scs_create(const char *p_chr, bool p_static) {
|
||||
return (p_chr[0] ? StringName(StaticCString::create(p_chr), p_static) : StringName());
|
||||
}
|
||||
|
||||
void StringName::setup() {
|
||||
ERR_FAIL_COND(configured);
|
||||
for (int i = 0; i < STRING_TABLE_LEN; i++) {
|
||||
@@ -115,9 +97,7 @@ void StringName::cleanup() {
|
||||
lost_strings++;
|
||||
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
String dname = String(d->cname ? d->cname : d->name);
|
||||
|
||||
print_line(vformat("Orphan StringName: %s (static: %d, total: %d)", dname, d->static_count.get(), d->refcount.get()));
|
||||
print_line(vformat("Orphan StringName: %s (static: %d, total: %d)", d->name, d->static_count.get(), d->refcount.get()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,11 +118,7 @@ void StringName::unref() {
|
||||
MutexLock lock(mutex);
|
||||
|
||||
if (CoreGlobals::leak_reporting_enabled && _data->static_count.get() > 0) {
|
||||
if (_data->cname) {
|
||||
ERR_PRINT("BUG: Unreferenced static string to 0: " + String(_data->cname));
|
||||
} else {
|
||||
ERR_PRINT("BUG: Unreferenced static string to 0: " + String(_data->name));
|
||||
}
|
||||
ERR_PRINT("BUG: Unreferenced static string to 0: " + _data->name);
|
||||
}
|
||||
if (_data->prev) {
|
||||
_data->prev->next = _data->next;
|
||||
@@ -193,12 +169,7 @@ bool StringName::operator!=(const char *p_name) const {
|
||||
|
||||
char32_t StringName::operator[](int p_index) const {
|
||||
if (_data) {
|
||||
if (_data->cname) {
|
||||
CRASH_BAD_INDEX(p_index, static_cast<long>(strlen(_data->cname)));
|
||||
return _data->cname[p_index];
|
||||
} else {
|
||||
return _data->name[p_index];
|
||||
}
|
||||
return _data->name[p_index];
|
||||
}
|
||||
|
||||
CRASH_BAD_INDEX(p_index, 0);
|
||||
@@ -207,11 +178,7 @@ char32_t StringName::operator[](int p_index) const {
|
||||
|
||||
int StringName::length() const {
|
||||
if (_data) {
|
||||
if (_data->cname) {
|
||||
return strlen(_data->cname);
|
||||
} else {
|
||||
return _data->name.length();
|
||||
}
|
||||
return _data->name.length();
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -219,11 +186,7 @@ int StringName::length() const {
|
||||
|
||||
bool StringName::is_empty() const {
|
||||
if (_data) {
|
||||
if (_data->cname) {
|
||||
return _data->cname[0] == 0;
|
||||
} else {
|
||||
return _data->name.is_empty();
|
||||
}
|
||||
return _data->name.is_empty();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -302,7 +265,6 @@ StringName::StringName(const char *p_name, bool p_static) {
|
||||
_data->static_count.set(p_static ? 1 : 0);
|
||||
_data->hash = hash;
|
||||
_data->idx = idx;
|
||||
_data->cname = nullptr;
|
||||
_data->next = _table[idx];
|
||||
_data->prev = nullptr;
|
||||
|
||||
@@ -319,62 +281,6 @@ StringName::StringName(const char *p_name, bool p_static) {
|
||||
_table[idx] = _data;
|
||||
}
|
||||
|
||||
StringName::StringName(const StaticCString &p_static_string, bool p_static) {
|
||||
_data = nullptr;
|
||||
|
||||
ERR_FAIL_COND(!configured);
|
||||
|
||||
ERR_FAIL_COND(!p_static_string.ptr || !p_static_string.ptr[0]);
|
||||
|
||||
const uint32_t hash = String::hash(p_static_string.ptr);
|
||||
const uint32_t idx = hash & STRING_TABLE_MASK;
|
||||
|
||||
MutexLock lock(mutex);
|
||||
_data = _table[idx];
|
||||
|
||||
while (_data) {
|
||||
// compare hash first
|
||||
if (_data->hash == hash && _data->operator==(p_static_string.ptr)) {
|
||||
break;
|
||||
}
|
||||
_data = _data->next;
|
||||
}
|
||||
|
||||
if (_data && _data->refcount.ref()) {
|
||||
// exists
|
||||
if (p_static) {
|
||||
_data->static_count.increment();
|
||||
}
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (unlikely(debug_stringname)) {
|
||||
_data->debug_references++;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
_data = memnew(_Data);
|
||||
|
||||
_data->refcount.init();
|
||||
_data->static_count.set(p_static ? 1 : 0);
|
||||
_data->hash = hash;
|
||||
_data->idx = idx;
|
||||
_data->cname = p_static_string.ptr;
|
||||
_data->next = _table[idx];
|
||||
_data->prev = nullptr;
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (unlikely(debug_stringname)) {
|
||||
// Keep in memory, force static.
|
||||
_data->refcount.ref();
|
||||
_data->static_count.increment();
|
||||
}
|
||||
#endif
|
||||
if (_table[idx]) {
|
||||
_table[idx]->prev = _data;
|
||||
}
|
||||
_table[idx] = _data;
|
||||
}
|
||||
|
||||
StringName::StringName(const String &p_name, bool p_static) {
|
||||
_data = nullptr;
|
||||
|
||||
@@ -416,7 +322,6 @@ StringName::StringName(const String &p_name, bool p_static) {
|
||||
_data->static_count.set(p_static ? 1 : 0);
|
||||
_data->hash = hash;
|
||||
_data->idx = idx;
|
||||
_data->cname = nullptr;
|
||||
_data->next = _table[idx];
|
||||
_data->prev = nullptr;
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
@@ -38,11 +38,6 @@
|
||||
|
||||
class Main;
|
||||
|
||||
struct StaticCString {
|
||||
const char *ptr;
|
||||
static StaticCString create(const char *p_ptr);
|
||||
};
|
||||
|
||||
class StringName {
|
||||
enum {
|
||||
STRING_TABLE_BITS = 16,
|
||||
@@ -53,12 +48,11 @@ class StringName {
|
||||
struct _Data {
|
||||
SafeRefCount refcount;
|
||||
SafeNumeric<uint32_t> static_count;
|
||||
const char *cname = nullptr;
|
||||
String name;
|
||||
#ifdef DEBUG_ENABLED
|
||||
uint32_t debug_references = 0;
|
||||
#endif
|
||||
String get_name() const { return cname ? String(cname) : name; }
|
||||
const String &get_name() const { return name; }
|
||||
bool operator==(const String &p_name) const;
|
||||
bool operator!=(const String &p_name) const;
|
||||
bool operator==(const char *p_name) const;
|
||||
@@ -97,13 +91,14 @@ class StringName {
|
||||
StringName(_Data *p_data) { _data = p_data; }
|
||||
|
||||
public:
|
||||
explicit operator bool() const { return _data && (_data->cname || !_data->name.is_empty()); }
|
||||
explicit operator bool() const { return _data && !_data->name.is_empty(); }
|
||||
|
||||
bool operator==(const String &p_name) const;
|
||||
bool operator==(const char *p_name) const;
|
||||
bool operator!=(const String &p_name) const;
|
||||
bool operator!=(const char *p_name) const;
|
||||
|
||||
const char32_t *get_data() const { return _data ? _data->name.ptr() : U""; }
|
||||
char32_t operator[](int p_index) const;
|
||||
int length() const;
|
||||
bool is_empty() const;
|
||||
@@ -112,11 +107,7 @@ public:
|
||||
if (!_data) {
|
||||
return false;
|
||||
}
|
||||
if (_data->cname != nullptr) {
|
||||
return (char32_t)_data->cname[0] == (char32_t)UNIQUE_NODE_PREFIX[0];
|
||||
} else {
|
||||
return (char32_t)_data->name[0] == (char32_t)UNIQUE_NODE_PREFIX[0];
|
||||
}
|
||||
return (char32_t)_data->name[0] == (char32_t)UNIQUE_NODE_PREFIX[0];
|
||||
}
|
||||
_FORCE_INLINE_ bool operator<(const StringName &p_name) const {
|
||||
return _data < p_name._data;
|
||||
@@ -151,11 +142,7 @@ public:
|
||||
|
||||
_FORCE_INLINE_ operator String() const {
|
||||
if (_data) {
|
||||
if (_data->cname) {
|
||||
return String(_data->cname);
|
||||
} else {
|
||||
return _data->name;
|
||||
}
|
||||
return _data->name;
|
||||
}
|
||||
|
||||
return String();
|
||||
@@ -171,40 +158,13 @@ public:
|
||||
return compare(l, r);
|
||||
}
|
||||
_FORCE_INLINE_ static bool compare(const StringName &l, const StringName &r) {
|
||||
const char *l_cname = l._data ? l._data->cname : "";
|
||||
const char *r_cname = r._data ? r._data->cname : "";
|
||||
|
||||
if (l_cname) {
|
||||
if (r_cname) {
|
||||
return str_compare(l_cname, r_cname) < 0;
|
||||
} else {
|
||||
return str_compare(l_cname, r._data->name.ptr()) < 0;
|
||||
}
|
||||
} else {
|
||||
if (r_cname) {
|
||||
return str_compare(l._data->name.ptr(), r_cname) < 0;
|
||||
} else {
|
||||
return str_compare(l._data->name.ptr(), r._data->name.ptr()) < 0;
|
||||
}
|
||||
}
|
||||
return str_compare(l.get_data(), r.get_data()) < 0;
|
||||
}
|
||||
_FORCE_INLINE_ static bool compare(const String &l, const StringName &r) {
|
||||
const char *r_cname = r._data ? r._data->cname : "";
|
||||
|
||||
if (r_cname) {
|
||||
return str_compare(l.get_data(), r_cname) < 0;
|
||||
} else {
|
||||
return str_compare(l.get_data(), r._data->name.ptr()) < 0;
|
||||
}
|
||||
return str_compare(l.get_data(), r.get_data()) < 0;
|
||||
}
|
||||
_FORCE_INLINE_ static bool compare(const StringName &l, const String &r) {
|
||||
const char *l_cname = l._data ? l._data->cname : "";
|
||||
|
||||
if (l_cname) {
|
||||
return str_compare(l_cname, r.get_data()) < 0;
|
||||
} else {
|
||||
return str_compare(l._data->name.ptr(), r.get_data()) < 0;
|
||||
}
|
||||
return str_compare(l.get_data(), r.get_data()) < 0;
|
||||
}
|
||||
_FORCE_INLINE_ static bool compare(const String &l, const String &r) {
|
||||
return str_compare(l.get_data(), r.get_data()) < 0;
|
||||
@@ -229,7 +189,6 @@ public:
|
||||
p_name._data = nullptr;
|
||||
}
|
||||
StringName(const String &p_name, bool p_static = false);
|
||||
StringName(const StaticCString &p_static_string, bool p_static = false);
|
||||
StringName() {}
|
||||
|
||||
static void assign_static_unique_class_name(StringName *ptr, const char *p_name);
|
||||
@@ -259,8 +218,6 @@ bool operator!=(const String &p_name, const StringName &p_string_name);
|
||||
bool operator==(const char *p_name, const StringName &p_string_name);
|
||||
bool operator!=(const char *p_name, const StringName &p_string_name);
|
||||
|
||||
StringName _scs_create(const char *p_chr, bool p_static = false);
|
||||
|
||||
/*
|
||||
* The SNAME macro is used to speed up StringName creation, as it allows caching it after the first usage in a very efficient way.
|
||||
* It should NOT be used everywhere, but instead in places where high performance is required and the creation of a StringName
|
||||
@@ -273,4 +230,4 @@ StringName _scs_create(const char *p_chr, bool p_static = false);
|
||||
* Use in places that can be called hundreds of times per frame (or more) is recommended, but this situation is very rare. If in doubt, do not use.
|
||||
*/
|
||||
|
||||
#define SNAME(m_arg) ([]() -> const StringName & { static StringName sname = _scs_create(m_arg, true); return sname; })()
|
||||
#define SNAME(m_arg) ([]() -> const StringName & { static StringName sname = StringName(m_arg, true); return sname; })()
|
||||
|
||||
Reference in New Issue
Block a user