diff options
Diffstat (limited to 'core')
51 files changed, 372 insertions, 126 deletions
diff --git a/core/SCsub b/core/SCsub index ed9a0a231d..755c5c65c6 100644 --- a/core/SCsub +++ b/core/SCsub @@ -80,6 +80,8 @@ if env['builtin_zlib']: env_thirdparty.Prepend(CPPPATH=[thirdparty_zlib_dir]) # Needs to be available in main env too env.Prepend(CPPPATH=[thirdparty_zlib_dir]) + if (env['target'] == 'debug'): + env_thirdparty.Append(CPPDEFINES=['ZLIB_DEBUG']) env_thirdparty.add_source_files(env.core_sources, thirdparty_zlib_sources) @@ -118,6 +120,8 @@ if env['builtin_zstd']: "compress/zstd_ldm.c", "compress/zstd_opt.c", "compress/zstdmt_compress.c", + "compress/zstd_compress_literals.c", + "compress/zstd_compress_sequences.c", "decompress/huf_decompress.c", "decompress/zstd_ddict.c", "decompress/zstd_decompress_block.c", diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index d07ba44788..c539f912aa 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -1136,6 +1136,16 @@ bool _OS::request_permission(const String &p_name) { return OS::get_singleton()->request_permission(p_name); } +bool _OS::request_permissions() { + + return OS::get_singleton()->request_permissions(); +} + +Vector<String> _OS::get_granted_permissions() const { + + return OS::get_singleton()->get_granted_permissions(); +} + _OS *_OS::singleton = NULL; void _OS::_bind_methods() { @@ -1319,6 +1329,8 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_power_percent_left"), &_OS::get_power_percent_left); ClassDB::bind_method(D_METHOD("request_permission", "name"), &_OS::request_permission); + ClassDB::bind_method(D_METHOD("request_permissions"), &_OS::request_permissions); + ClassDB::bind_method(D_METHOD("get_granted_permissions"), &_OS::get_granted_permissions); ADD_PROPERTY(PropertyInfo(Variant::STRING, "clipboard"), "set_clipboard", "get_clipboard"); ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen"), "set_current_screen", "get_current_screen"); @@ -3153,6 +3165,9 @@ Ref<JSONParseResult> _JSON::parse(const String &p_json) { result->error = JSON::parse(p_json, result->result, result->error_string, result->error_line); + if (result->error != OK) { + ERR_PRINTS(vformat("Error parsing JSON at line %s: %s", result->error_line, result->error_string)); + } return result; } diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 693b85710a..1a4fd1d5cb 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -349,6 +349,8 @@ public: bool has_feature(const String &p_feature) const; bool request_permission(const String &p_name); + bool request_permissions(); + Vector<String> get_granted_permissions() const; static _OS *get_singleton() { return singleton; } diff --git a/core/compressed_translation.cpp b/core/compressed_translation.cpp index f102721470..d927b74897 100644 --- a/core/compressed_translation.cpp +++ b/core/compressed_translation.cpp @@ -136,6 +136,8 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) { bucket_table_size += 2 + b.size() * 4; } + ERR_FAIL_COND(bucket_table_size == 0); + hash_table.resize(size); bucket_table.resize(bucket_table_size); diff --git a/core/cowdata.h b/core/cowdata.h index 3e40ad0f4b..c92e20920c 100644 --- a/core/cowdata.h +++ b/core/cowdata.h @@ -33,6 +33,7 @@ #include <string.h> +#include "core/error_macros.h" #include "core/os/memory.h" #include "core/safe_refcount.h" diff --git a/core/crypto/hashing_context.cpp b/core/crypto/hashing_context.cpp index bd863f546b..b5aa0ddc18 100644 --- a/core/crypto/hashing_context.cpp +++ b/core/crypto/hashing_context.cpp @@ -50,6 +50,7 @@ Error HashingContext::start(HashType p_type) { Error HashingContext::update(PoolByteArray p_chunk) { ERR_FAIL_COND_V(ctx == NULL, ERR_UNCONFIGURED); size_t len = p_chunk.size(); + ERR_FAIL_COND_V(len == 0, FAILED); PoolByteArray::Read r = p_chunk.read(); switch (type) { case HASH_MD5: diff --git a/core/dictionary.cpp b/core/dictionary.cpp index 5e4dfb9a5a..0d9945991e 100644 --- a/core/dictionary.cpp +++ b/core/dictionary.cpp @@ -192,13 +192,9 @@ uint32_t Dictionary::hash() const { uint32_t h = hash_djb2_one_32(Variant::DICTIONARY); - List<Variant> keys; - get_key_list(&keys); - - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - - h = hash_djb2_one_32(E->get().hash(), h); - h = hash_djb2_one_32(operator[](E->get()).hash(), h); + for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { + h = hash_djb2_one_32(E.key().hash(), h); + h = hash_djb2_one_32(E.value().hash(), h); } return h; @@ -207,10 +203,11 @@ uint32_t Dictionary::hash() const { Array Dictionary::keys() const { Array varr; - varr.resize(size()); if (_p->variant_map.empty()) return varr; + varr.resize(size()); + int i = 0; for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { varr[i] = E.key(); @@ -223,10 +220,11 @@ Array Dictionary::keys() const { Array Dictionary::values() const { Array varr; - varr.resize(size()); if (_p->variant_map.empty()) return varr; + varr.resize(size()); + int i = 0; for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { varr[i] = E.get(); @@ -255,11 +253,8 @@ Dictionary Dictionary::duplicate(bool p_deep) const { Dictionary n; - List<Variant> keys; - get_key_list(&keys); - - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - n[E->get()] = p_deep ? operator[](E->get()).duplicate(p_deep) : operator[](E->get()); + for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) { + n[E.key()] = p_deep ? E.value().duplicate(true) : E.value(); } return n; diff --git a/core/error_macros.cpp b/core/error_macros.cpp index 0e8e4a9bb4..eda6b9cbbb 100644 --- a/core/error_macros.cpp +++ b/core/error_macros.cpp @@ -31,6 +31,7 @@ #include "error_macros.h" #include "core/io/logger.h" +#include "core/ustring.h" #include "os/os.h" bool _err_error_exists = false; @@ -42,6 +43,11 @@ void _err_set_last_error(const char *p_err) { OS::get_singleton()->set_last_error(p_err); } +void _err_set_last_error(const String &p_err) { + + _err_set_last_error(p_err.utf8().get_data()); +} + void _err_clear_last_error() { OS::get_singleton()->clear_last_error(); @@ -99,6 +105,10 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co } } +void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type) { + _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_type); +} + void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, bool fatal) { String fstr(fatal ? "FATAL: " : ""); diff --git a/core/error_macros.h b/core/error_macros.h index 65802de9d2..d4b69ff40d 100644 --- a/core/error_macros.h +++ b/core/error_macros.h @@ -55,8 +55,10 @@ enum ErrorHandlerType { ERR_HANDLER_SHADER, }; +class String; typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type); void _err_set_last_error(const char *p_err); +void _err_set_last_error(const String &p_err); void _err_clear_last_error(); struct ErrorHandlerList { @@ -77,6 +79,7 @@ void add_error_handler(ErrorHandlerList *p_handler); void remove_error_handler(ErrorHandlerList *p_handler); void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR); void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, bool fatal = false); #ifndef _STR @@ -98,10 +101,10 @@ extern bool _err_error_exists; _err_set_last_error(m_reason); \ _err_error_exists = true; \ } -#define ERR_EXPLAIN(m_string) \ - { \ - _err_set_last_error(String(m_string).utf8().get_data()); \ - _err_error_exists = true; \ +#define ERR_EXPLAIN(m_string) \ + { \ + _err_set_last_error(m_string); \ + _err_error_exists = true; \ } #else @@ -430,10 +433,10 @@ extern bool _err_error_exists; _err_error_exists = false; \ } -#define ERR_PRINTS(m_string) \ - { \ - _err_print_error(FUNCTION_STR, __FILE__, __LINE__, String(m_string).utf8().get_data()); \ - _err_error_exists = false; \ +#define ERR_PRINTS(m_string) \ + { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \ + _err_error_exists = false; \ } #define ERR_PRINT_ONCE(m_string) \ @@ -455,10 +458,10 @@ extern bool _err_error_exists; _err_error_exists = false; \ } -#define WARN_PRINTS(m_string) \ - { \ - _err_print_error(FUNCTION_STR, __FILE__, __LINE__, String(m_string).utf8().get_data(), ERR_HANDLER_WARNING); \ - _err_error_exists = false; \ +#define WARN_PRINTS(m_string) \ + { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \ + _err_error_exists = false; \ } #define WARN_PRINT_ONCE(m_string) \ diff --git a/core/hash_map.h b/core/hash_map.h index 38da1d59ab..edc67e7806 100644 --- a/core/hash_map.h +++ b/core/hash_map.h @@ -210,6 +210,7 @@ private: e->next = hash_table[index]; e->hash = hash; e->pair.key = p_key; + e->pair.data = TData(); hash_table[index] = e; elements++; diff --git a/core/image.cpp b/core/image.cpp index e0b0a1f8be..74706535b3 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -885,8 +885,8 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { bool mipmap_aware = p_interpolation == INTERPOLATE_TRILINEAR /* || p_interpolation == INTERPOLATE_TRICUBIC */; - ERR_FAIL_COND_MSG(p_width <= 0, "Image width cannot be greater than 0."); - ERR_FAIL_COND_MSG(p_height <= 0, "Image height cannot be greater than 0."); + ERR_FAIL_COND_MSG(p_width <= 0, "Image width must be greater than 0."); + ERR_FAIL_COND_MSG(p_height <= 0, "Image height must be greater than 0."); ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, "Image width cannot be greater than " + itos(MAX_WIDTH) + "."); ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, "Image height cannot be greater than " + itos(MAX_HEIGHT) + "."); @@ -1284,8 +1284,8 @@ static void _generate_po2_mipmap(const Component *p_src, Component *p_dst, uint3 Component *dst_ptr = &p_dst[i * dst_w * CC]; uint32_t count = dst_w; - while (count--) { - + while (count) { + count--; for (int j = 0; j < CC; j++) { average_func(dst_ptr[j], rup_ptr[j], rup_ptr[j + right_step], rdown_ptr[j], rdown_ptr[j + right_step]); } @@ -1322,6 +1322,8 @@ void Image::expand_x2_hq2x() { PoolVector<uint8_t>::Read r = data.read(); PoolVector<uint8_t>::Write w = dest.write(); + ERR_FAIL_COND(!r.ptr()); + hq2x_resize((const uint32_t *)r.ptr(), width, height, (uint32_t *)w.ptr()); } @@ -1373,6 +1375,7 @@ void Image::shrink_x2() { int ps = get_format_pixel_size(format); new_img.resize((width / 2) * (height / 2) * ps); ERR_FAIL_COND(new_img.size() == 0); + ERR_FAIL_COND(data.size() == 0); { PoolVector<uint8_t>::Write w = new_img.write(); @@ -2895,6 +2898,8 @@ void Image::bumpmap_to_normalmap(float bump_scale) { PoolVector<uint8_t>::Read rp = data.read(); PoolVector<uint8_t>::Write wp = result_image.write(); + ERR_FAIL_COND(!rp.ptr()); + unsigned char *write_ptr = wp.ptr(); float *read_ptr = (float *)rp.ptr(); @@ -2930,7 +2935,7 @@ void Image::srgb_to_linear() { if (data.size() == 0) return; - static const uint8_t srgb2lin[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 26, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 53, 54, 55, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 85, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 101, 102, 103, 105, 106, 107, 109, 110, 112, 113, 114, 116, 117, 119, 120, 122, 123, 125, 126, 128, 129, 131, 132, 134, 135, 137, 139, 140, 142, 144, 145, 147, 148, 150, 152, 153, 155, 157, 159, 160, 162, 164, 166, 167, 169, 171, 173, 175, 176, 178, 180, 182, 184, 186, 188, 190, 192, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 235, 237, 239, 241, 243, 245, 248, 250, 252 }; + static const uint8_t srgb2lin[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 26, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 53, 54, 55, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 85, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 101, 102, 103, 105, 106, 107, 109, 110, 112, 113, 114, 116, 117, 119, 120, 122, 123, 125, 126, 128, 129, 131, 132, 134, 135, 137, 139, 140, 142, 144, 145, 147, 148, 150, 152, 153, 155, 157, 159, 160, 162, 164, 166, 167, 169, 171, 173, 175, 176, 178, 180, 182, 184, 186, 188, 190, 192, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 235, 237, 239, 241, 243, 245, 248, 250, 252, 255 }; ERR_FAIL_COND(format != FORMAT_RGB8 && format != FORMAT_RGBA8); diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 271e5c5a0b..5684c82d1c 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -123,6 +123,13 @@ void ConfigFile::erase_section(const String &p_section) { values.erase(p_section); } +void ConfigFile::erase_section_key(const String &p_section, const String &p_key) { + + ERR_FAIL_COND_MSG(!values.has(p_section), "Cannot erase key from nonexistent section '" + p_section + "'."); + + values[p_section].erase(p_key); +} + Error ConfigFile::save(const String &p_path) { Error err; @@ -293,6 +300,7 @@ void ConfigFile::_bind_methods() { ClassDB::bind_method(D_METHOD("get_section_keys", "section"), &ConfigFile::_get_section_keys); ClassDB::bind_method(D_METHOD("erase_section", "section"), &ConfigFile::erase_section); + ClassDB::bind_method(D_METHOD("erase_section_key", "section", "key"), &ConfigFile::erase_section_key); ClassDB::bind_method(D_METHOD("load", "path"), &ConfigFile::load); ClassDB::bind_method(D_METHOD("save", "path"), &ConfigFile::save); diff --git a/core/io/config_file.h b/core/io/config_file.h index 3ab6fef868..d927779f9c 100644 --- a/core/io/config_file.h +++ b/core/io/config_file.h @@ -60,6 +60,7 @@ public: void get_section_keys(const String &p_section, List<String> *r_keys) const; void erase_section(const String &p_section); + void erase_section_key(const String &p_section, const String &p_key); Error save(const String &p_path); Error load(const String &p_path); diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index 54ef753b7c..34d3eb5344 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -151,6 +151,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) magic = f->get_32(); if (magic != 0x43504447) { + f->close(); memdelete(f); return false; } @@ -162,6 +163,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) magic = f->get_32(); if (magic != 0x43504447) { + f->close(); memdelete(f); return false; } @@ -172,8 +174,16 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) uint32_t ver_minor = f->get_32(); f->get_32(); // ver_rev - ERR_FAIL_COND_V_MSG(version != PACK_VERSION, false, "Pack version unsupported: " + itos(version) + "."); - ERR_FAIL_COND_V_MSG(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "."); + if (version != PACK_VERSION) { + f->close(); + memdelete(f); + ERR_FAIL_V_MSG(false, "Pack version unsupported: " + itos(version) + "."); + } + if (ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR)) { + f->close(); + memdelete(f); + ERR_FAIL_V_MSG(false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "."); + } for (int i = 0; i < 16; i++) { //reserved @@ -200,6 +210,8 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5, this, p_replace_files); }; + f->close(); + memdelete(f); return true; }; diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 0ba84d0c8f..1426dbbd4d 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -602,7 +602,16 @@ void MultiplayerAPI::_add_peer(int p_id) { void MultiplayerAPI::_del_peer(int p_id) { connected_peers.erase(p_id); - path_get_cache.erase(p_id); // I no longer need your cache, sorry. + // Cleanup get cache. + path_get_cache.erase(p_id); + // Cleanup sent cache. + // Some refactoring is needed to make this faster and do paths GC. + List<NodePath> keys; + path_send_cache.get_key_list(&keys); + for (List<NodePath>::Element *E = keys.front(); E; E = E->next()) { + PathSentCache *psc = path_send_cache.getptr(E->get()); + psc->confirmed_peers.erase(p_id); + } emit_signal("network_peer_disconnected", p_id); } diff --git a/core/list.h b/core/list.h index d1b528562d..c46888e01c 100644 --- a/core/list.h +++ b/core/list.h @@ -31,6 +31,7 @@ #ifndef GLOBALS_LIST_H #define GLOBALS_LIST_H +#include "core/error_macros.h" #include "core/os/memory.h" #include "core/sort_array.h" diff --git a/core/map.h b/core/map.h index c87ee42e1b..77e73d70cb 100644 --- a/core/map.h +++ b/core/map.h @@ -31,6 +31,7 @@ #ifndef MAP_H #define MAP_H +#include "core/error_macros.h" #include "core/set.h" // based on the very nice implementation of rb-trees by: diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index ae2b56e7b7..810e290922 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -164,23 +164,23 @@ void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) { } Segment s(p_id, p_with_id); - if (s.from == p_id) { - s.from_point = a; - s.to_point = b; - } else { - s.from_point = b; - s.to_point = a; + if (bidirectional) s.direction = Segment::BIDIRECTIONAL; + + Set<Segment>::Element *element = segments.find(s); + if (element != NULL) { + s.direction |= element->get().direction; + if (s.direction == Segment::BIDIRECTIONAL) { + // Both are neighbours of each other now + a->unlinked_neighbours.remove(b->id); + b->unlinked_neighbours.remove(a->id); + } + segments.erase(element); } segments.insert(s); } -void AStar::disconnect_points(int p_id, int p_with_id) { - - Segment s(p_id, p_with_id); - ERR_FAIL_COND(!segments.has(s)); - - segments.erase(s); +void AStar::disconnect_points(int p_id, int p_with_id, bool bidirectional) { Point *a; bool a_exists = points.lookup(p_id, a); @@ -190,10 +190,33 @@ void AStar::disconnect_points(int p_id, int p_with_id) { bool b_exists = points.lookup(p_with_id, b); CRASH_COND(!b_exists); - a->neighbours.remove(b->id); - a->unlinked_neighbours.remove(b->id); - b->neighbours.remove(a->id); - b->unlinked_neighbours.remove(a->id); + Segment s(p_id, p_with_id); + int remove_direction = bidirectional ? (int)Segment::BIDIRECTIONAL : s.direction; + + Set<Segment>::Element *element = segments.find(s); + if (element != NULL) { + // s is the new segment + // Erase the directions to be removed + s.direction = (element->get().direction & ~remove_direction); + + a->neighbours.remove(b->id); + if (bidirectional) { + b->neighbours.remove(a->id); + if (element->get().direction != Segment::BIDIRECTIONAL) { + a->unlinked_neighbours.remove(b->id); + b->unlinked_neighbours.remove(a->id); + } + } else { + if (s.direction == Segment::NONE) + b->unlinked_neighbours.remove(a->id); + else + a->unlinked_neighbours.set(b->id, b); + } + + segments.erase(element); + if (s.direction != Segment::NONE) + segments.insert(s); + } } bool AStar::has_point(int p_id) const { @@ -227,10 +250,13 @@ PoolVector<int> AStar::get_point_connections(int p_id) { return point_list; } -bool AStar::are_points_connected(int p_id, int p_with_id) const { +bool AStar::are_points_connected(int p_id, int p_with_id, bool bidirectional) const { Segment s(p_id, p_with_id); - return segments.has(s); + const Set<Segment>::Element *element = segments.find(s); + + return element != NULL && + (bidirectional || (element->get().direction & s.direction) == s.direction); } void AStar::clear() { @@ -284,13 +310,17 @@ Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const { for (const Set<Segment>::Element *E = segments.front(); E; E = E->next()) { - if (!(E->get().from_point->enabled && E->get().to_point->enabled)) { + Point *from_point = nullptr, *to_point = nullptr; + points.lookup(E->get().u, from_point); + points.lookup(E->get().v, to_point); + + if (!(from_point->enabled && to_point->enabled)) { continue; } Vector3 segment[2] = { - E->get().from_point->pos, - E->get().to_point->pos, + from_point->pos, + to_point->pos, }; Vector3 p = Geometry::get_closest_point_to_segment(p_point, segment); @@ -532,8 +562,8 @@ void AStar::_bind_methods() { ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar::is_point_disabled); ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar::connect_points, DEFVAL(true)); - ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar::disconnect_points); - ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id"), &AStar::are_points_connected); + ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id", "bidirectional"), &AStar::disconnect_points, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id", "bidirectional"), &AStar::are_points_connected, DEFVAL(true)); ClassDB::bind_method(D_METHOD("get_point_count"), &AStar::get_point_count); ClassDB::bind_method(D_METHOD("get_point_capacity"), &AStar::get_point_capacity); diff --git a/core/math/a_star.h b/core/math/a_star.h index 0a5d3e992c..8ff62e646b 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -81,24 +81,35 @@ class AStar : public Reference { struct Segment { union { struct { - int32_t from; - int32_t to; + int32_t u; + int32_t v; }; uint64_t key; }; - Point *from_point; - Point *to_point; + enum { + NONE = 0, + FORWARD = 1, + BACKWARD = 2, + BIDIRECTIONAL = FORWARD | BACKWARD + }; + unsigned char direction; bool operator<(const Segment &p_s) const { return key < p_s.key; } - Segment() { key = 0; } + Segment() { + key = 0; + direction = NONE; + } Segment(int p_from, int p_to) { - if (p_from > p_to) { - SWAP(p_from, p_to); + if (p_from < p_to) { + u = p_from; + v = p_to; + direction = FORWARD; + } else { + u = p_to; + v = p_from; + direction = BACKWARD; } - - from = p_from; - to = p_to; } }; @@ -133,8 +144,8 @@ public: bool is_point_disabled(int p_id) const; void connect_points(int p_id, int p_with_id, bool bidirectional = true); - void disconnect_points(int p_id, int p_with_id); - bool are_points_connected(int p_id, int p_with_id) const; + void disconnect_points(int p_id, int p_with_id, bool bidirectional = true); + bool are_points_connected(int p_id, int p_with_id, bool bidirectional = true) const; int get_point_count() const; int get_point_capacity() const; diff --git a/core/math/basis.h b/core/math/basis.h index 053effda69..4be4ea4cd3 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -28,13 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Circular dependency between Vector3 and Basis :/ -#include "core/math/vector3.h" - #ifndef BASIS_H #define BASIS_H #include "core/math/quat.h" +#include "core/math/vector3.h" class Basis { public: diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index f04e40cb6c..50fcdb2c13 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -30,6 +30,8 @@ #include "math_funcs.h" +#include "core/error_macros.h" + RandomPCG Math::default_rand(RandomPCG::DEFAULT_SEED, RandomPCG::DEFAULT_INC); #define PHI 0x9e3779b9 diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 9078abea68..a94b27fcc5 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -472,7 +472,7 @@ public: return p_step != 0 ? Math::stepify(p_target - p_offset, p_step) + p_offset : p_target; } - static _ALWAYS_INLINE_ float snap_scalar_seperation(float p_offset, float p_step, float p_target, float p_separation) { + static _ALWAYS_INLINE_ float snap_scalar_separation(float p_offset, float p_step, float p_target, float p_separation) { if (p_step != 0) { float a = Math::stepify(p_target - p_offset, p_step + p_separation) + p_offset; float b = a; diff --git a/core/math/plane.cpp b/core/math/plane.cpp index b01853c4ac..b6bcac4b27 100644 --- a/core/math/plane.cpp +++ b/core/math/plane.cpp @@ -91,7 +91,7 @@ bool Plane::intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r real_t denom = vec3_cross(normal0, normal1).dot(normal2); - if (ABS(denom) <= CMP_EPSILON) + if (Math::is_zero_approx(denom)) return false; if (r_result) { diff --git a/core/math/rect2.h b/core/math/rect2.h index d636aa223f..f58756ee40 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -99,8 +99,8 @@ struct Rect2 { inline bool encloses(const Rect2 &p_rect) const { return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) && - ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) && - ((p_rect.position.y + p_rect.size.y) < (position.y + size.y)); + ((p_rect.position.x + p_rect.size.x) <= (position.x + size.x)) && + ((p_rect.position.y + p_rect.size.y) <= (position.y + size.y)); } _FORCE_INLINE_ bool has_no_area() const { diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 73927821cf..ebc1599820 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -134,6 +134,21 @@ Vector3 Vector3::move_toward(const Vector3 &p_to, const real_t p_delta) const { return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta; } +Basis Vector3::outer(const Vector3 &p_b) const { + + Vector3 row0(x * p_b.x, x * p_b.y, x * p_b.z); + Vector3 row1(y * p_b.x, y * p_b.y, y * p_b.z); + Vector3 row2(z * p_b.x, z * p_b.y, z * p_b.z); + + return Basis(row0, row1, row2); +} + +Basis Vector3::to_diagonal_matrix() const { + return Basis(x, 0, 0, + 0, y, 0, + 0, 0, z); +} + Vector3::operator String() const { return (rtos(x) + ", " + rtos(y) + ", " + rtos(z)); diff --git a/core/math/vector3.h b/core/math/vector3.h index c68b075613..de1743d88f 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -96,8 +96,8 @@ struct Vector3 { _FORCE_INLINE_ Vector3 cross(const Vector3 &p_b) const; _FORCE_INLINE_ real_t dot(const Vector3 &p_b) const; - _FORCE_INLINE_ Basis outer(const Vector3 &p_b) const; - _FORCE_INLINE_ Basis to_diagonal_matrix() const; + Basis outer(const Vector3 &p_b) const; + Basis to_diagonal_matrix() const; _FORCE_INLINE_ Vector3 abs() const; _FORCE_INLINE_ Vector3 floor() const; @@ -154,9 +154,6 @@ struct Vector3 { _FORCE_INLINE_ Vector3() { x = y = z = 0; } }; -// Should be included after class definition, otherwise we get circular refs -#include "core/math/basis.h" - Vector3 Vector3::cross(const Vector3 &p_b) const { Vector3 ret( @@ -172,21 +169,6 @@ real_t Vector3::dot(const Vector3 &p_b) const { return x * p_b.x + y * p_b.y + z * p_b.z; } -Basis Vector3::outer(const Vector3 &p_b) const { - - Vector3 row0(x * p_b.x, x * p_b.y, x * p_b.z); - Vector3 row1(y * p_b.x, y * p_b.y, y * p_b.z); - Vector3 row2(z * p_b.x, z * p_b.y, z * p_b.z); - - return Basis(row0, row1, row2); -} - -Basis Vector3::to_diagonal_matrix() const { - return Basis(x, 0, 0, - 0, y, 0, - 0, 0, z); -} - Vector3 Vector3::abs() const { return Vector3(Math::abs(x), Math::abs(y), Math::abs(z)); diff --git a/core/node_path.cpp b/core/node_path.cpp index b43f76f680..970ed100fe 100644 --- a/core/node_path.cpp +++ b/core/node_path.cpp @@ -269,7 +269,7 @@ NodePath NodePath::rel_path_to(const NodePath &p_np) const { NodePath NodePath::get_as_property_path() const { - if (!data->path.size()) { + if (!data || !data->path.size()) { return *this; } else { Vector<StringName> new_path = data->subpath; diff --git a/core/object.cpp b/core/object.cpp index 6facf38733..ed3ae4f25d 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -436,7 +436,7 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid } else if (p_name == CoreStringNames::get_singleton()->_meta) { //set_meta(p_name,p_value); - metadata = p_value; + metadata = p_value.duplicate(); if (r_valid) *r_valid = true; return; diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index 30fca0c155..381ba9d010 100644 --- a/core/os/input_event.cpp +++ b/core/os/input_event.cpp @@ -557,10 +557,31 @@ InputEventMouseButton::InputEventMouseButton() { //////////////////////////////////////////// +void InputEventMouseMotion::set_tilt(const Vector2 &p_tilt) { + + tilt = p_tilt; +} + +Vector2 InputEventMouseMotion::get_tilt() const { + + return tilt; +} + +void InputEventMouseMotion::set_pressure(float p_pressure) { + + pressure = p_pressure; +} + +float InputEventMouseMotion::get_pressure() const { + + return pressure; +} + void InputEventMouseMotion::set_relative(const Vector2 &p_relative) { relative = p_relative; } + Vector2 InputEventMouseMotion::get_relative() const { return relative; @@ -570,6 +591,7 @@ void InputEventMouseMotion::set_speed(const Vector2 &p_speed) { speed = p_speed; } + Vector2 InputEventMouseMotion::get_speed() const { return speed; @@ -590,6 +612,8 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co mm->set_modifiers_from_event(this); mm->set_position(l); + mm->set_pressure(get_pressure()); + mm->set_tilt(get_tilt()); mm->set_global_position(g); mm->set_button_mask(get_button_mask()); @@ -665,17 +689,27 @@ bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) { void InputEventMouseMotion::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_tilt", "tilt"), &InputEventMouseMotion::set_tilt); + ClassDB::bind_method(D_METHOD("get_tilt"), &InputEventMouseMotion::get_tilt); + + ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventMouseMotion::set_pressure); + ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventMouseMotion::get_pressure); + ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative); ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative); ClassDB::bind_method(D_METHOD("set_speed", "speed"), &InputEventMouseMotion::set_speed); ClassDB::bind_method(D_METHOD("get_speed"), &InputEventMouseMotion::get_speed); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure"), "set_pressure", "get_pressure"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed"); } InputEventMouseMotion::InputEventMouseMotion() { + + pressure = 0; } //////////////////////////////////////// diff --git a/core/os/input_event.h b/core/os/input_event.h index 28658e3865..14649502ee 100644 --- a/core/os/input_event.h +++ b/core/os/input_event.h @@ -351,6 +351,9 @@ public: class InputEventMouseMotion : public InputEventMouse { GDCLASS(InputEventMouseMotion, InputEventMouse); + + Vector2 tilt; + float pressure; Vector2 relative; Vector2 speed; @@ -358,6 +361,12 @@ protected: static void _bind_methods(); public: + void set_tilt(const Vector2 &p_tilt); + Vector2 get_tilt() const; + + void set_pressure(float p_pressure); + float get_pressure() const; + void set_relative(const Vector2 &p_relative); Vector2 get_relative() const; diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp index 5587e827ba..146a301995 100644 --- a/core/os/main_loop.cpp +++ b/core/os/main_loop.cpp @@ -65,6 +65,8 @@ void MainLoop::_bind_methods() { BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE); BIND_CONSTANT(NOTIFICATION_APP_RESUMED); BIND_CONSTANT(NOTIFICATION_APP_PAUSED); + + ADD_SIGNAL(MethodInfo("on_request_permissions_result", PropertyInfo(Variant::STRING, "permission"), PropertyInfo(Variant::BOOL, "granted"))); }; void MainLoop::set_init_script(const Ref<Script> &p_init_script) { diff --git a/core/os/memory.h b/core/os/memory.h index 8778cb63ad..a68a359546 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -31,6 +31,7 @@ #ifndef MEMORY_H #define MEMORY_H +#include "core/error_macros.h" #include "core/safe_refcount.h" #include <stddef.h> diff --git a/core/os/os.h b/core/os/os.h index 9b46b43081..b5224c4f63 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -530,6 +530,8 @@ public: List<String> get_restart_on_exit_arguments() const; virtual bool request_permission(const String &p_name) { return true; } + virtual bool request_permissions() { return true; } + virtual Vector<String> get_granted_permissions() const { return Vector<String>(); } virtual void process_and_drop_events() {} OS(); diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp index 003e7e7428..7afaf7f0f1 100644 --- a/core/packed_data_container.cpp +++ b/core/packed_data_container.cpp @@ -137,6 +137,7 @@ uint32_t PackedDataContainer::_type_at_ofs(uint32_t p_ofs) const { int PackedDataContainer::_size(uint32_t p_ofs) const { PoolVector<uint8_t>::Read rd = data.read(); + ERR_FAIL_COND_V(!rd.ptr(), 0); const uint8_t *r = &rd[p_ofs]; uint32_t type = decode_uint32(r); diff --git a/core/pool_vector.h b/core/pool_vector.h index fbd4d630be..a698e72e18 100644 --- a/core/pool_vector.h +++ b/core/pool_vector.h @@ -385,6 +385,7 @@ public: } inline int size() const; + inline bool empty() const; T get(int p_index) const; void set(int p_index, const T &p_val); void push_back(const T &p_val); @@ -475,6 +476,12 @@ int PoolVector<T>::size() const { } template <class T> +bool PoolVector<T>::empty() const { + + return alloc ? alloc->size == 0 : true; +} + +template <class T> T PoolVector<T>::get(int p_index) const { return operator[](p_index); diff --git a/core/project_settings.cpp b/core/project_settings.cpp index c2241ed926..7704c7b377 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -107,7 +107,7 @@ String ProjectSettings::localize_path(const String &p_path) const { if (plocal == "") { return ""; }; - return plocal + path.substr(sep, path.size() - sep); + return plocal + path.substr((sep + 1), path.size() - (sep + 1)); }; } diff --git a/core/ref_ptr.cpp b/core/ref_ptr.cpp index 961f143e5c..6da73ca41a 100644 --- a/core/ref_ptr.cpp +++ b/core/ref_ptr.cpp @@ -49,6 +49,14 @@ bool RefPtr::operator==(const RefPtr &p_other) const { return *ref == *ref_other; } +bool RefPtr::operator!=(const RefPtr &p_other) const { + + Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]); + Ref<Reference> *ref_other = reinterpret_cast<Ref<Reference> *>(const_cast<char *>(&p_other.data[0])); + + return *ref != *ref_other; +} + RefPtr::RefPtr(const RefPtr &p_other) { memnew_placement(&data[0], Ref<Reference>); diff --git a/core/ref_ptr.h b/core/ref_ptr.h index f745ababa1..320cf35609 100644 --- a/core/ref_ptr.h +++ b/core/ref_ptr.h @@ -50,6 +50,7 @@ public: bool is_null() const; void operator=(const RefPtr &p_other); bool operator==(const RefPtr &p_other) const; + bool operator!=(const RefPtr &p_other) const; RID get_rid() const; void unref(); _FORCE_INLINE_ void *get_data() const { return data; } diff --git a/core/resource.cpp b/core/resource.cpp index 87c92ca5b1..e0a40b6f3c 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -365,17 +365,38 @@ bool Resource::is_translation_remapped() const { //helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored void Resource::set_id_for_path(const String &p_path, int p_id) { if (p_id == -1) { - id_for_path.erase(p_path); + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->write_lock(); + } + ResourceCache::resource_path_cache[p_path].erase(get_path()); + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->write_unlock(); + } } else { - id_for_path[p_path] = p_id; + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->write_lock(); + } + ResourceCache::resource_path_cache[p_path][get_path()] = p_id; + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->write_unlock(); + } } } int Resource::get_id_for_path(const String &p_path) const { - - if (id_for_path.has(p_path)) { - return id_for_path[p_path]; + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->read_lock(); + } + if (ResourceCache::resource_path_cache[p_path].has(get_path())) { + int result = ResourceCache::resource_path_cache[p_path][get_path()]; + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->read_unlock(); + } + return result; } else { + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->read_unlock(); + } return -1; } } @@ -430,12 +451,21 @@ Resource::~Resource() { } HashMap<String, Resource *> ResourceCache::resources; +#ifdef TOOLS_ENABLED +HashMap<String, HashMap<String, int> > ResourceCache::resource_path_cache; +#endif RWLock *ResourceCache::lock = NULL; +#ifdef TOOLS_ENABLED +RWLock *ResourceCache::path_cache_lock = NULL; +#endif void ResourceCache::setup() { lock = RWLock::create(); +#ifdef TOOLS_ENABLED + path_cache_lock = RWLock::create(); +#endif } void ResourceCache::clear() { diff --git a/core/resource.h b/core/resource.h index 038b4f6278..3e1fe07137 100644 --- a/core/resource.h +++ b/core/resource.h @@ -84,9 +84,7 @@ protected: void _set_path(const String &p_path); void _take_over_path(const String &p_path); -#ifdef TOOLS_ENABLED - Map<String, int> id_for_path; -#endif + public: static Node *(*_get_local_scene_func)(); //used by editor @@ -152,6 +150,10 @@ class ResourceCache { friend class ResourceLoader; //need the lock static RWLock *lock; static HashMap<String, Resource *> resources; +#ifdef TOOLS_ENABLED + static HashMap<String, HashMap<String, int> > resource_path_cache; // each tscn has a set of resource paths and IDs + static RWLock *path_cache_lock; +#endif // TOOLS_ENABLED friend void unregister_core_types(); static void clear(); friend void register_core_types(); diff --git a/core/script_language.cpp b/core/script_language.cpp index 7201773ea5..cbe4681eca 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -218,6 +218,7 @@ void ScriptServer::global_classes_clear() { } void ScriptServer::add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path) { + ERR_FAIL_COND_MSG(p_class == p_base || (global_classes.has(p_base) && get_global_class_native_base(p_base) == p_class), "Cyclic inheritance in script class."); GlobalScriptClass g; g.language = p_language; g.path = p_path; diff --git a/core/self_list.h b/core/self_list.h index 314d440977..07abcd1d53 100644 --- a/core/self_list.h +++ b/core/self_list.h @@ -31,6 +31,7 @@ #ifndef SELF_LIST_H #define SELF_LIST_H +#include "core/error_macros.h" #include "core/typedefs.h" template <class T> diff --git a/core/sort_array.h b/core/sort_array.h index 8660ee3333..d330e0c647 100644 --- a/core/sort_array.h +++ b/core/sort_array.h @@ -31,6 +31,7 @@ #ifndef SORT_ARRAY_H #define SORT_ARRAY_H +#include "core/error_macros.h" #include "core/typedefs.h" #define ERR_BAD_COMPARE(cond) \ diff --git a/core/string_builder.cpp b/core/string_builder.cpp index 35526e0d70..22eed70f8b 100644 --- a/core/string_builder.cpp +++ b/core/string_builder.cpp @@ -34,6 +34,9 @@ StringBuilder &StringBuilder::append(const String &p_string) { + if (p_string == String()) + return *this; + strings.push_back(p_string); appended_strings.push_back(-1); diff --git a/core/translation.cpp b/core/translation.cpp index a0902d71fc..4a1ac26433 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -986,6 +986,7 @@ Array TranslationServer::get_loaded_locales() const { for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) { const Ref<Translation> &t = E->get(); + ERR_FAIL_COND_V(t.is_null(), Array()); String l = t->get_locale(); locales.push_back(l); @@ -1057,6 +1058,7 @@ StringName TranslationServer::translate(const StringName &p_message) const { for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) { const Ref<Translation> &t = E->get(); + ERR_FAIL_COND_V(t.is_null(), StringName("")); String l = t->get_locale(); if (lptr[0] != l[0] || lptr[1] != l[1]) continue; // Language code does not match. @@ -1085,6 +1087,7 @@ StringName TranslationServer::translate(const StringName &p_message) const { for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) { const Ref<Translation> &t = E->get(); + ERR_FAIL_COND_V(t.is_null(), StringName("")); String l = t->get_locale(); if (fptr[0] != l[0] || fptr[1] != l[1]) continue; // Language code does not match. diff --git a/core/typedefs.h b/core/typedefs.h index 660139b90a..767a97ac38 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -108,7 +108,6 @@ T *_nullptr() { #include "core/int_types.h" #include "core/error_list.h" -#include "core/error_macros.h" /** Generic ABS function, for math uses please use Math::abs */ diff --git a/core/ustring.cpp b/core/ustring.cpp index 07caa3a018..7ee2fee312 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -3288,9 +3288,7 @@ String String::simplify_path() const { static int _humanize_digits(int p_num) { - if (p_num < 10) - return 2; - else if (p_num < 100) + if (p_num < 100) return 2; else if (p_num < 1024) return 1; @@ -3298,7 +3296,7 @@ static int _humanize_digits(int p_num) { return 0; } -String String::humanize_size(size_t p_size) { +String String::humanize_size(uint64_t p_size) { uint64_t _div = 1; Vector<String> prefixes; @@ -4060,6 +4058,11 @@ String itos(int64_t p_val) { return String::num_int64(p_val); } +String uitos(uint64_t p_val) { + + return String::num_uint64(p_val); +} + String rtos(double p_val) { return String::num(p_val); diff --git a/core/ustring.h b/core/ustring.h index 87a14bfad7..dfc5044942 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -322,7 +322,7 @@ public: String path_to_file(const String &p_path) const; String get_base_dir() const; String get_file() const; - static String humanize_size(size_t p_size); + static String humanize_size(uint64_t p_size); String simplify_path() const; String xml_escape(bool p_escape_quotes = false) const; @@ -369,6 +369,7 @@ String operator+(const char *p_chr, const String &p_str); String operator+(CharType p_chr, const String &p_str); String itos(int64_t p_val); +String uitos(uint64_t p_val); String rtos(double p_val); String rtoss(double p_val); //scientific version diff --git a/core/variant.cpp b/core/variant.cpp index 16bbf94c54..e0cc6685f4 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -3299,7 +3299,7 @@ String vformat(const String &p_text, const Variant &p1, const Variant &p2, const bool error = false; String fmt = p_text.sprintf(args, &error); - ERR_FAIL_COND_V(error, String()); + ERR_FAIL_COND_V_MSG(error, String(), fmt); return fmt; } diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 53f64fcde6..f7a3438d32 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -284,6 +284,7 @@ struct _VariantCall { VCALL_LOCALMEM0R(String, sha1_buffer); VCALL_LOCALMEM0R(String, sha256_buffer); VCALL_LOCALMEM0R(String, empty); + VCALL_LOCALMEM1R(String, humanize_size); VCALL_LOCALMEM0R(String, is_abs_path); VCALL_LOCALMEM0R(String, is_rel_path); VCALL_LOCALMEM0R(String, get_base_dir); @@ -315,6 +316,10 @@ struct _VariantCall { static void _call_String_to_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) { String *s = reinterpret_cast<String *>(p_self._data._mem); + if (s->empty()) { + r_ret = PoolByteArray(); + return; + } CharString charstr = s->ascii(); PoolByteArray retval; @@ -330,6 +335,10 @@ struct _VariantCall { static void _call_String_to_utf8(Variant &r_ret, Variant &p_self, const Variant **p_args) { String *s = reinterpret_cast<String *>(p_self._data._mem); + if (s->empty()) { + r_ret = PoolByteArray(); + return; + } CharString charstr = s->utf8(); PoolByteArray retval; @@ -544,7 +553,7 @@ struct _VariantCall { PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem); String s; - if (ba->size() >= 0) { + if (ba->size() > 0) { PoolByteArray::Read r = ba->read(); CharString cs; cs.resize(ba->size() + 1); @@ -560,7 +569,7 @@ struct _VariantCall { PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem); String s; - if (ba->size() >= 0) { + if (ba->size() > 0) { PoolByteArray::Read r = ba->read(); s.parse_utf8((const char *)r.ptr(), ba->size()); } @@ -571,14 +580,15 @@ struct _VariantCall { PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem); PoolByteArray compressed; - Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]); + if (ba->size() > 0) { + Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]); - compressed.resize(Compression::get_max_compressed_buffer_size(ba->size(), mode)); - int result = Compression::compress(compressed.write().ptr(), ba->read().ptr(), ba->size(), mode); - - result = result >= 0 ? result : 0; - compressed.resize(result); + compressed.resize(Compression::get_max_compressed_buffer_size(ba->size(), mode)); + int result = Compression::compress(compressed.write().ptr(), ba->read().ptr(), ba->size(), mode); + result = result >= 0 ? result : 0; + compressed.resize(result); + } r_ret = compressed; } @@ -590,9 +600,9 @@ struct _VariantCall { int buffer_size = (int)(*p_args[0]); - if (buffer_size < 0) { + if (buffer_size <= 0) { r_ret = decompressed; - ERR_FAIL_MSG("Decompression buffer size is less than zero."); + ERR_FAIL_MSG("Decompression buffer size must be greater than zero."); } decompressed.resize(buffer_size); @@ -606,12 +616,17 @@ struct _VariantCall { static void _call_PoolByteArray_hex_encode(Variant &r_ret, Variant &p_self, const Variant **p_args) { PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem); + if (ba->size() == 0) { + r_ret = String(); + return; + } PoolByteArray::Read r = ba->read(); String s = String::hex_encode_buffer(&r[0], ba->size()); r_ret = s; } VCALL_LOCALMEM0R(PoolByteArray, size); + VCALL_LOCALMEM0R(PoolByteArray, empty); VCALL_LOCALMEM2(PoolByteArray, set); VCALL_LOCALMEM1R(PoolByteArray, get); VCALL_LOCALMEM1(PoolByteArray, push_back); @@ -624,6 +639,7 @@ struct _VariantCall { VCALL_LOCALMEM2R(PoolByteArray, subarray); VCALL_LOCALMEM0R(PoolIntArray, size); + VCALL_LOCALMEM0R(PoolIntArray, empty); VCALL_LOCALMEM2(PoolIntArray, set); VCALL_LOCALMEM1R(PoolIntArray, get); VCALL_LOCALMEM1(PoolIntArray, push_back); @@ -635,6 +651,7 @@ struct _VariantCall { VCALL_LOCALMEM0(PoolIntArray, invert); VCALL_LOCALMEM0R(PoolRealArray, size); + VCALL_LOCALMEM0R(PoolRealArray, empty); VCALL_LOCALMEM2(PoolRealArray, set); VCALL_LOCALMEM1R(PoolRealArray, get); VCALL_LOCALMEM1(PoolRealArray, push_back); @@ -646,6 +663,7 @@ struct _VariantCall { VCALL_LOCALMEM0(PoolRealArray, invert); VCALL_LOCALMEM0R(PoolStringArray, size); + VCALL_LOCALMEM0R(PoolStringArray, empty); VCALL_LOCALMEM2(PoolStringArray, set); VCALL_LOCALMEM1R(PoolStringArray, get); VCALL_LOCALMEM1(PoolStringArray, push_back); @@ -658,6 +676,7 @@ struct _VariantCall { VCALL_LOCALMEM1R(PoolStringArray, join); VCALL_LOCALMEM0R(PoolVector2Array, size); + VCALL_LOCALMEM0R(PoolVector2Array, empty); VCALL_LOCALMEM2(PoolVector2Array, set); VCALL_LOCALMEM1R(PoolVector2Array, get); VCALL_LOCALMEM1(PoolVector2Array, push_back); @@ -669,6 +688,7 @@ struct _VariantCall { VCALL_LOCALMEM0(PoolVector2Array, invert); VCALL_LOCALMEM0R(PoolVector3Array, size); + VCALL_LOCALMEM0R(PoolVector3Array, empty); VCALL_LOCALMEM2(PoolVector3Array, set); VCALL_LOCALMEM1R(PoolVector3Array, get); VCALL_LOCALMEM1(PoolVector3Array, push_back); @@ -680,6 +700,7 @@ struct _VariantCall { VCALL_LOCALMEM0(PoolVector3Array, invert); VCALL_LOCALMEM0R(PoolColorArray, size); + VCALL_LOCALMEM0R(PoolColorArray, empty); VCALL_LOCALMEM2(PoolColorArray, set); VCALL_LOCALMEM1R(PoolColorArray, get); VCALL_LOCALMEM1(PoolColorArray, push_back); @@ -1561,6 +1582,7 @@ void register_variant_methods() { ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, sha1_buffer, varray()); ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, sha256_buffer, varray()); ADDFUNC0R(STRING, BOOL, String, empty, varray()); + ADDFUNC1R(STRING, STRING, String, humanize_size, INT, "size", varray()); ADDFUNC0R(STRING, BOOL, String, is_abs_path, varray()); ADDFUNC0R(STRING, BOOL, String, is_rel_path, varray()); ADDFUNC0R(STRING, STRING, String, get_base_dir, varray()); @@ -1767,6 +1789,7 @@ void register_variant_methods() { ADDFUNC0R(ARRAY, NIL, Array, min, varray()); ADDFUNC0R(POOL_BYTE_ARRAY, INT, PoolByteArray, size, varray()); + ADDFUNC0R(POOL_BYTE_ARRAY, BOOL, PoolByteArray, empty, varray()); ADDFUNC2(POOL_BYTE_ARRAY, NIL, PoolByteArray, set, INT, "idx", INT, "byte", varray()); ADDFUNC1(POOL_BYTE_ARRAY, NIL, PoolByteArray, push_back, INT, "byte", varray()); ADDFUNC1(POOL_BYTE_ARRAY, NIL, PoolByteArray, append, INT, "byte", varray()); @@ -1784,6 +1807,7 @@ void register_variant_methods() { ADDFUNC2R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0)); ADDFUNC0R(POOL_INT_ARRAY, INT, PoolIntArray, size, varray()); + ADDFUNC0R(POOL_INT_ARRAY, BOOL, PoolIntArray, empty, varray()); ADDFUNC2(POOL_INT_ARRAY, NIL, PoolIntArray, set, INT, "idx", INT, "integer", varray()); ADDFUNC1(POOL_INT_ARRAY, NIL, PoolIntArray, push_back, INT, "integer", varray()); ADDFUNC1(POOL_INT_ARRAY, NIL, PoolIntArray, append, INT, "integer", varray()); @@ -1794,6 +1818,7 @@ void register_variant_methods() { ADDFUNC0(POOL_INT_ARRAY, NIL, PoolIntArray, invert, varray()); ADDFUNC0R(POOL_REAL_ARRAY, INT, PoolRealArray, size, varray()); + ADDFUNC0R(POOL_REAL_ARRAY, BOOL, PoolRealArray, empty, varray()); ADDFUNC2(POOL_REAL_ARRAY, NIL, PoolRealArray, set, INT, "idx", REAL, "value", varray()); ADDFUNC1(POOL_REAL_ARRAY, NIL, PoolRealArray, push_back, REAL, "value", varray()); ADDFUNC1(POOL_REAL_ARRAY, NIL, PoolRealArray, append, REAL, "value", varray()); @@ -1804,6 +1829,7 @@ void register_variant_methods() { ADDFUNC0(POOL_REAL_ARRAY, NIL, PoolRealArray, invert, varray()); ADDFUNC0R(POOL_STRING_ARRAY, INT, PoolStringArray, size, varray()); + ADDFUNC0R(POOL_STRING_ARRAY, BOOL, PoolStringArray, empty, varray()); ADDFUNC2(POOL_STRING_ARRAY, NIL, PoolStringArray, set, INT, "idx", STRING, "string", varray()); ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, push_back, STRING, "string", varray()); ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, append, STRING, "string", varray()); @@ -1815,6 +1841,7 @@ void register_variant_methods() { ADDFUNC1(POOL_STRING_ARRAY, STRING, PoolStringArray, join, STRING, "delimiter", varray()); ADDFUNC0R(POOL_VECTOR2_ARRAY, INT, PoolVector2Array, size, varray()); + ADDFUNC0R(POOL_VECTOR2_ARRAY, BOOL, PoolVector2Array, empty, varray()); ADDFUNC2(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, set, INT, "idx", VECTOR2, "vector2", varray()); ADDFUNC1(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, push_back, VECTOR2, "vector2", varray()); ADDFUNC1(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, append, VECTOR2, "vector2", varray()); @@ -1825,6 +1852,7 @@ void register_variant_methods() { ADDFUNC0(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, invert, varray()); ADDFUNC0R(POOL_VECTOR3_ARRAY, INT, PoolVector3Array, size, varray()); + ADDFUNC0R(POOL_VECTOR3_ARRAY, BOOL, PoolVector3Array, empty, varray()); ADDFUNC2(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, set, INT, "idx", VECTOR3, "vector3", varray()); ADDFUNC1(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, push_back, VECTOR3, "vector3", varray()); ADDFUNC1(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, append, VECTOR3, "vector3", varray()); @@ -1835,6 +1863,7 @@ void register_variant_methods() { ADDFUNC0(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, invert, varray()); ADDFUNC0R(POOL_COLOR_ARRAY, INT, PoolColorArray, size, varray()); + ADDFUNC0R(POOL_COLOR_ARRAY, BOOL, PoolColorArray, empty, varray()); ADDFUNC2(POOL_COLOR_ARRAY, NIL, PoolColorArray, set, INT, "idx", COLOR, "color", varray()); ADDFUNC1(POOL_COLOR_ARRAY, NIL, PoolColorArray, push_back, COLOR, "color", varray()); ADDFUNC1(POOL_COLOR_ARRAY, NIL, PoolColorArray, append, COLOR, "color", varray()); diff --git a/core/vmap.h b/core/vmap.h index fde9723d71..ed66b46993 100644 --- a/core/vmap.h +++ b/core/vmap.h @@ -196,8 +196,7 @@ public: int pos = _find_exact(p_key); if (pos < 0) { - V val; - pos = insert(p_key, val); + pos = insert(p_key, V()); } return _cowdata.get_m(pos).value; |