diff options
Diffstat (limited to 'core/string')
-rw-r--r-- | core/string/optimized_translation.cpp | 15 | ||||
-rw-r--r-- | core/string/translation.cpp | 35 | ||||
-rw-r--r-- | core/string/translation.h | 5 | ||||
-rw-r--r-- | core/string/ustring.cpp | 69 | ||||
-rw-r--r-- | core/string/ustring.h | 24 |
5 files changed, 95 insertions, 53 deletions
diff --git a/core/string/optimized_translation.cpp b/core/string/optimized_translation.cpp index 5863bd1c46..f8be564740 100644 --- a/core/string/optimized_translation.cpp +++ b/core/string/optimized_translation.cpp @@ -64,7 +64,6 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) { int idx = 0; int total_compression_size = 0; - int total_string_size = 0; for (const StringName &E : keys) { //hash string @@ -102,7 +101,6 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) { compressed.write[idx] = ps; total_compression_size += ps.compressed.size(); - total_string_size += src_s.size(); idx++; } @@ -147,26 +145,23 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) { uint32_t *btw = (uint32_t *)&btwb[0]; int btindex = 0; - int collisions = 0; for (int i = 0; i < size; i++) { const Map<uint32_t, int> &t = table[i]; if (t.size() == 0) { htw[i] = 0xFFFFFFFF; //nothing continue; - } else if (t.size() > 1) { - collisions += t.size() - 1; } htw[i] = btindex; btw[btindex++] = t.size(); btw[btindex++] = hfunc_table[i]; - for (Map<uint32_t, int>::Element *E = t.front(); E; E = E->next()) { - btw[btindex++] = E->key(); - btw[btindex++] = compressed[E->get()].offset; - btw[btindex++] = compressed[E->get()].compressed.size(); - btw[btindex++] = compressed[E->get()].orig_len; + for (const KeyValue<uint32_t, int> &E : t) { + btw[btindex++] = E.key; + btw[btindex++] = compressed[E.value].offset; + btw[btindex++] = compressed[E.value].compressed.size(); + btw[btindex++] = compressed[E.value].orig_len; } } diff --git a/core/string/translation.cpp b/core/string/translation.cpp index cb7d924556..cf61467d08 100644 --- a/core/string/translation.cpp +++ b/core/string/translation.cpp @@ -35,7 +35,6 @@ #include "core/os/os.h" #ifdef TOOLS_ENABLED -#include "editor/editor_settings.h" #include "main/main.h" #endif @@ -810,9 +809,12 @@ static const char *locale_names[] = { // - https://msdn.microsoft.com/en-us/library/windows/desktop/ms693062(v=vs.85).aspx static const char *locale_renames[][2] = { - { "in", "id" }, // Indonesian - { "iw", "he" }, // Hebrew - { "no", "nb" }, // Norwegian Bokmål + { "in", "id" }, // Indonesian + { "iw", "he" }, // Hebrew + { "no", "nb" }, // Norwegian Bokmål + { "C", "en" }, // "C" is the simple/default/untranslated Computer locale. + // ASCII-only, English, no currency symbols. Godot treats this as "en". + // See https://unix.stackexchange.com/a/87763/164141 "The C locale is"... { nullptr, nullptr } }; @@ -820,8 +822,8 @@ static const char *locale_renames[][2] = { Dictionary Translation::_get_messages() const { Dictionary d; - for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) { - d[E->key()] = E->value(); + for (const KeyValue<StringName, StringName> &E : translation_map) { + d[E.key] = E.value; } return d; } @@ -830,8 +832,8 @@ Vector<String> Translation::_get_message_list() const { Vector<String> msgs; msgs.resize(translation_map.size()); int idx = 0; - for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) { - msgs.set(idx, E->key()); + for (const KeyValue<StringName, StringName> &E : translation_map) { + msgs.set(idx, E.key); idx += 1; } @@ -875,6 +877,11 @@ void Translation::add_plural_message(const StringName &p_src_text, const Vector< } StringName Translation::get_message(const StringName &p_src_text, const StringName &p_context) const { + StringName ret; + if (GDVIRTUAL_CALL(_get_message, p_src_text, p_context, ret)) { + return ret; + } + if (p_context != StringName()) { WARN_PRINT("Translation class doesn't handle context. Using context in get_message() on a Translation instance is probably a mistake. \nUse a derived Translation class that handles context, such as TranslationPO class"); } @@ -888,6 +895,11 @@ StringName Translation::get_message(const StringName &p_src_text, const StringNa } StringName Translation::get_plural_message(const StringName &p_src_text, const StringName &p_plural_text, int p_n, const StringName &p_context) const { + StringName ret; + if (GDVIRTUAL_CALL(_get_plural_message, p_src_text, p_plural_text, p_n, p_context, ret)) { + return ret; + } + WARN_PRINT("Translation class doesn't handle plural messages. Calling get_plural_message() on a Translation instance is probably a mistake. \nUse a derived Translation class that handles plurals, such as TranslationPO class"); return get_message(p_src_text); } @@ -901,8 +913,8 @@ void Translation::erase_message(const StringName &p_src_text, const StringName & } void Translation::get_message_list(List<StringName> *r_messages) const { - for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) { - r_messages->push_back(E->key()); + for (const KeyValue<StringName, StringName> &E : translation_map) { + r_messages->push_back(E.key); } } @@ -923,6 +935,9 @@ void Translation::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_messages"), &Translation::_set_messages); ClassDB::bind_method(D_METHOD("_get_messages"), &Translation::_get_messages); + GDVIRTUAL_BIND(_get_plural_message, "src_message", "src_plural_message", "n", "context"); + GDVIRTUAL_BIND(_get_message, "src_message", "context"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "messages", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_messages", "_get_messages"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "locale"), "set_locale", "get_locale"); } diff --git a/core/string/translation.h b/core/string/translation.h index 4f179ac0fe..6aec0bb8ea 100644 --- a/core/string/translation.h +++ b/core/string/translation.h @@ -32,6 +32,8 @@ #define TRANSLATION_H #include "core/io/resource.h" +#include "core/object/gdvirtual.gen.inc" +#include "core/object/script_language.h" class Translation : public Resource { GDCLASS(Translation, Resource); @@ -48,6 +50,9 @@ class Translation : public Resource { protected: static void _bind_methods(); + GDVIRTUAL2RC(StringName, _get_message, StringName, StringName); + GDVIRTUAL4RC(StringName, _get_plural_message, StringName, StringName, int, StringName); + public: void set_locale(const String &p_locale); _FORCE_INLINE_ String get_locale() const { return locale; } diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index a3b5356b1d..daeb7fbd17 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1551,19 +1551,21 @@ String String::num_real(double p_num, bool p_trailing) { bool neg = p_num < 0; p_num = ABS(p_num); - int intn = (int)p_num; + int64_t intn = (int64_t)p_num; // Decimal part. if (intn != p_num) { - double dec = p_num - (double)(intn); + double dec = p_num - (double)intn; int digit = 0; -#if REAL_T_IS_DOUBLE +#ifdef REAL_T_IS_DOUBLE int decimals = 14; + double tolerance = 1e-14; #else int decimals = 6; + double tolerance = 1e-6; #endif // We want to align the digits to the above sane default, so we only // need to subtract log10 for numbers with a positive power of ten. @@ -1575,16 +1577,21 @@ String String::num_real(double p_num, bool p_trailing) { decimals = MAX_DECIMALS; } - int dec_int = 0; - int dec_max = 0; + // In case the value ends up ending in "99999", we want to add a + // tiny bit to the value we're checking when deciding when to stop, + // so we multiply by slightly above 1 (1 + 1e-7 or 1e-15). + double check_multiplier = 1 + tolerance / 10; + + int64_t dec_int = 0; + int64_t dec_max = 0; while (true) { dec *= 10.0; - dec_int = dec_int * 10 + (int)dec % 10; + dec_int = dec_int * 10 + (int64_t)dec % 10; dec_max = dec_max * 10 + 9; digit++; - if ((dec - (double)((int)dec)) < 1e-6) { + if ((dec - (double)(int64_t)(dec * check_multiplier)) < tolerance) { break; } @@ -1594,7 +1601,7 @@ String String::num_real(double p_num, bool p_trailing) { } dec *= 10; - int last = (int)dec % 10; + int last = (int64_t)dec % 10; if (last > 5) { if (dec_int == dec_max) { @@ -1653,13 +1660,13 @@ String String::num_scientific(double p_num) { #if defined(__GNUC__) || defined(_MSC_VER) -#if (defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900)) && defined(_TWO_DIGIT_EXPONENT) && !defined(_UCRT) - // MinGW and old MSC require _set_output_format() to conform to C99 output for printf +#if defined(__MINGW32__) && defined(_TWO_DIGIT_EXPONENT) && !defined(_UCRT) + // MinGW requires _set_output_format() to conform to C99 output for printf unsigned int old_exponent_format = _set_output_format(_TWO_DIGIT_EXPONENT); #endif snprintf(buf, 256, "%lg", p_num); -#if (defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900)) && defined(_TWO_DIGIT_EXPONENT) && !defined(_UCRT) +#if defined(__MINGW32__) && defined(_TWO_DIGIT_EXPONENT) && !defined(_UCRT) _set_output_format(old_exponent_format); #endif @@ -3555,7 +3562,7 @@ String String::strip_edges(bool left, bool right) const { } if (right) { - for (int i = (int)(len - 1); i >= 0; i--) { + for (int i = len - 1; i >= 0; i--) { if (operator[](i) <= 32) { end--; } else { @@ -4329,23 +4336,39 @@ bool String::is_relative_path() const { } String String::get_base_dir() const { - int basepos = find(":/"); - if (basepos == -1) { - basepos = find(":\\"); + int end = 0; + + // url scheme style base + int basepos = find("://"); + if (basepos != -1) { + end = basepos + 3; + } + + // windows top level directory base + if (end == 0) { + basepos = find(":/"); + if (basepos == -1) { + basepos = find(":\\"); + } + if (basepos != -1) { + end = basepos + 2; + } + } + + // unix root directory base + if (end == 0) { + if (begins_with("/")) { + end = 1; + } } + String rs; String base; - if (basepos != -1) { - int end = basepos + 3; + if (end != 0) { rs = substr(end, length()); base = substr(0, end); } else { - if (begins_with("/")) { - rs = substr(1, length()); - base = "/"; - } else { - rs = *this; - } + rs = *this; } int sep = MAX(rs.rfind("/"), rs.rfind("\\")); diff --git a/core/string/ustring.h b/core/string/ustring.h index 6a4b40da60..1d80ccf58d 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -51,11 +51,15 @@ class CharProxy { CowData<T> &_cowdata; static const T _null = 0; - _FORCE_INLINE_ CharProxy(const int &p_index, CowData<T> &cowdata) : + _FORCE_INLINE_ CharProxy(const int &p_index, CowData<T> &p_cowdata) : _index(p_index), - _cowdata(cowdata) {} + _cowdata(p_cowdata) {} public: + _FORCE_INLINE_ CharProxy(const CharProxy<T> &p_other) : + _index(p_other._index), + _cowdata(p_other._cowdata) {} + _FORCE_INLINE_ operator T() const { if (unlikely(_index == _cowdata.size())) { return _null; @@ -68,12 +72,12 @@ public: return _cowdata.ptr() + _index; } - _FORCE_INLINE_ void operator=(const T &other) const { - _cowdata.set(_index, other); + _FORCE_INLINE_ void operator=(const T &p_other) const { + _cowdata.set(_index, p_other); } - _FORCE_INLINE_ void operator=(const CharProxy<T> &other) const { - _cowdata.set(_index, other.operator T()); + _FORCE_INLINE_ void operator=(const CharProxy<T> &p_other) const { + _cowdata.set(_index, p_other.operator T()); } }; @@ -523,10 +527,10 @@ String DTRN(const String &p_text, const String &p_text_plural, int p_n, const St #define TTRGET(m_value) TTR(m_value) #else -#define TTR(m_value) (String()) -#define TTRN(m_value) (String()) -#define DTR(m_value) (String()) -#define DTRN(m_value) (String()) +#define TTR(m_value) String() +#define TTRN(m_value) String() +#define DTR(m_value) String() +#define DTRN(m_value) String() #define TTRC(m_value) (m_value) #define TTRGET(m_value) (m_value) #endif |