diff options
Diffstat (limited to 'core')
35 files changed, 516 insertions, 157 deletions
diff --git a/core/SCsub b/core/SCsub index da2403f1d3..02abaa2bb6 100644 --- a/core/SCsub +++ b/core/SCsub @@ -18,7 +18,7 @@ gd_cpp = '#include "global_config.h"\n' gd_cpp += gd_inc gd_cpp += "void GlobalConfig::register_global_defaults() {\n" + gd_call + "\n}\n" -f = open("global_defaults.cpp", "wb") +f = open("global_defaults.gen.cpp", "wb") f.write(gd_cpp) f.close() @@ -47,7 +47,7 @@ if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ): txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0" print("Invalid AES256 encryption key, not 64 bits hex: " + e) -f = open("script_encryption_key.cpp", "wb") +f = open("script_encryption_key.gen.cpp", "wb") f.write("#include \"global_config.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n") f.close() @@ -109,7 +109,7 @@ env.add_source_files(env.core_sources, "*.cpp") # Make binders import make_binders -env.Command(['method_bind.inc', 'method_bind_ext.inc'], 'make_binders.py', make_binders.run) +env.Command(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', make_binders.run) # Chain load SCsubs diff --git a/core/class_db.cpp b/core/class_db.cpp index 1fe02c8cd9..6b8c290a99 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -497,7 +497,7 @@ void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherit } } -void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance) { +void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) { OBJTYPE_RLOCK; @@ -528,6 +528,9 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b minfo.name = E->get(); minfo.id = method->get_method_id(); + if (p_exclude_from_properties && type->methods_in_properties.has(minfo.name)) + continue; + for (int i = 0; i < method->get_argument_count(); i++) { //Variant::Type t=method->get_argument_type(i); @@ -802,7 +805,14 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons OBJTYPE_WLOCK type->property_list.push_back(p_pinfo); - +#ifdef DEBUG_METHODS_ENABLED + if (mb_get) { + type->methods_in_properties.insert(p_getter); + } + if (mb_set) { + type->methods_in_properties.insert(p_setter); + } +#endif PropertySetGet psg; psg.setter = p_setter; psg.getter = p_getter; diff --git a/core/class_db.h b/core/class_db.h index 547068da5f..4f00a16e91 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -139,6 +139,7 @@ public: #ifdef DEBUG_METHODS_ENABLED List<StringName> constant_order; List<StringName> method_order; + Set<StringName> methods_in_properties; List<MethodInfo> virtual_methods; StringName category; #endif @@ -486,7 +487,7 @@ public: static bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false); static void set_method_flags(StringName p_class, StringName p_method, int p_flags); - static void get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false); + static void get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false); static MethodBind *get_method(StringName p_class, StringName p_name); static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true); diff --git a/core/core_string_names.cpp b/core/core_string_names.cpp index e35ac2b72c..0ed44b0cb7 100644 --- a/core/core_string_names.cpp +++ b/core/core_string_names.cpp @@ -44,4 +44,7 @@ CoreStringNames::CoreStringNames() { _iter_next = StaticCString::create("_iter_next"); _iter_get = StaticCString::create("_iter_get"); get_rid = StaticCString::create("get_rid"); +#ifdef TOOLS_ENABLED + _sections_unfolded = StaticCString::create("_sections_unfolded"); +#endif } diff --git a/core/core_string_names.h b/core/core_string_names.h index 6672772432..4b4f87a8f0 100644 --- a/core/core_string_names.h +++ b/core/core_string_names.h @@ -61,6 +61,9 @@ public: StringName _iter_next; StringName _iter_get; StringName get_rid; +#ifdef TOOLS_ENABLED + StringName _sections_unfolded; +#endif }; #endif // SCENE_STRING_NAMES_H diff --git a/core/dvector.h b/core/dvector.h index 4584a300f9..66af42f7e2 100644 --- a/core/dvector.h +++ b/core/dvector.h @@ -409,14 +409,9 @@ public: if (p_to < 0) { p_to = size() + p_to; } - if (p_from < 0 || p_from >= size()) { - PoolVector<T> &aux = *((PoolVector<T> *)0); // nullreturn - ERR_FAIL_COND_V(p_from < 0 || p_from >= size(), aux) - } - if (p_to < 0 || p_to >= size()) { - PoolVector<T> &aux = *((PoolVector<T> *)0); // nullreturn - ERR_FAIL_COND_V(p_to < 0 || p_to >= size(), aux) - } + + CRASH_BAD_INDEX(p_from, size()); + CRASH_BAD_INDEX(p_to, size()); PoolVector<T> slice; int span = 1 + p_to - p_from; @@ -506,13 +501,9 @@ void PoolVector<T>::push_back(const T &p_val) { template <class T> const T PoolVector<T>::operator[](int p_index) const { - if (p_index < 0 || p_index >= size()) { - T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux); - } + CRASH_BAD_INDEX(p_index, size()); Read r = read(); - return r[p_index]; } diff --git a/core/error_macros.h b/core/error_macros.h index 00fced3586..6c803951a1 100644 --- a/core/error_macros.h +++ b/core/error_macros.h @@ -115,6 +115,19 @@ extern bool _err_error_exists; #define FUNCTION_STR __FUNCTION__ #endif +// Don't use this directly; instead, use any of the CRASH_* macros +#ifdef _MSC_VER +#define GENERATE_TRAP \ + __debugbreak(); \ + /* Avoid warning about control paths */ \ + for (;;) { \ + } +#else +#define GENERATE_TRAP __builtin_trap(); +#endif + +// (*): See https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for + #define ERR_FAIL_INDEX(m_index, m_size) \ do { \ if ((m_index) < 0 || (m_index) >= (m_size)) { \ @@ -122,12 +135,12 @@ extern bool _err_error_exists; return; \ } else \ _err_error_exists = false; \ - } while (0); + } while (0); // (*) /** An index has failed if m_index<0 or m_index >=m_size, the function exists. - * This function returns an error value, if returning Error, please select the most - * appropriate error condition from error_macros.h - */ +* This function returns an error value, if returning Error, please select the most +* appropriate error condition from error_macros.h +*/ #define ERR_FAIL_INDEX_V(m_index, m_size, m_retval) \ do { \ @@ -136,7 +149,18 @@ extern bool _err_error_exists; return m_retval; \ } else \ _err_error_exists = false; \ - } while (0); + } while (0); // (*) + +/** Use this one if there is no sensible fallback, that is, the error is unrecoverable. +* We'll return a null reference and try to keep running. +*/ +#define CRASH_BAD_INDEX(m_index, m_size) \ + do { \ + if ((m_index) < 0 || (m_index) >= (m_size)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Index " _STR(m_index) " out of size (" _STR(m_size) ")."); \ + GENERATE_TRAP \ + } \ + } while (0); // (*) /** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert(). * the function will exit. @@ -173,6 +197,17 @@ extern bool _err_error_exists; _err_error_exists = false; \ } +/** Use this one if there is no sensible fallback, that is, the error is unrecoverable. + */ + +#define CRASH_COND(m_cond) \ + { \ + if (m_cond) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition ' " _STR(m_cond) " ' is true."); \ + GENERATE_TRAP \ + } \ + } + /** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert(). * the function will exit. * This function returns an error value, if returning Error, please select the most @@ -234,6 +269,15 @@ extern bool _err_error_exists; return m_value; \ } +/** Use this one if there is no sensible fallback, that is, the error is unrecoverable. + */ + +#define CRASH_NOW() \ + { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/Function Failed."); \ + GENERATE_TRAP \ + } + /** Print an error string. */ diff --git a/core/hash_map.h b/core/hash_map.h index 49701188ab..45e7b82d24 100644 --- a/core/hash_map.h +++ b/core/hash_map.h @@ -473,8 +473,7 @@ public: if (!e) { e = create_entry(p_key); - if (!e) - return *(TData *)NULL; /* panic! */ + CRASH_COND(!e); check_hash_table(); // perform mantenience routine } diff --git a/core/image.cpp b/core/image.cpp index ec21260b19..6ab8bb6d46 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -423,7 +423,7 @@ void Image::convert(Format p_new_format) { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { - new_img.put_pixel(i, j, get_pixel(i, j)); + new_img.set_pixel(i, j, get_pixel(i, j)); } } @@ -1325,19 +1325,19 @@ void Image::create(const char **p_xpm) { line++; } } -#define DETECT_ALPHA_MAX_TRESHOLD 254 -#define DETECT_ALPHA_MIN_TRESHOLD 2 - -#define DETECT_ALPHA(m_value) \ - { \ - uint8_t value = m_value; \ - if (value < DETECT_ALPHA_MIN_TRESHOLD) \ - bit = true; \ - else if (value < DETECT_ALPHA_MAX_TRESHOLD) { \ - \ - detected = true; \ - break; \ - } \ +#define DETECT_ALPHA_MAX_THRESHOLD 254 +#define DETECT_ALPHA_MIN_THRESHOLD 2 + +#define DETECT_ALPHA(m_value) \ + { \ + uint8_t value = m_value; \ + if (value < DETECT_ALPHA_MIN_THRESHOLD) \ + bit = true; \ + else if (value < DETECT_ALPHA_MAX_THRESHOLD) { \ + \ + detected = true; \ + break; \ + } \ } #define DETECT_NON_ALPHA(m_value) \ @@ -1646,6 +1646,62 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po } } +void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) { + + ERR_FAIL_COND(p_src.is_null()); + ERR_FAIL_COND(p_mask.is_null()); + int dsize = data.size(); + int srcdsize = p_src->data.size(); + int maskdsize = p_mask->data.size(); + ERR_FAIL_COND(dsize == 0); + ERR_FAIL_COND(srcdsize == 0); + ERR_FAIL_COND(maskdsize == 0); + ERR_FAIL_COND(p_src->width != p_mask->width); + ERR_FAIL_COND(p_src->height != p_mask->height); + ERR_FAIL_COND(format != p_src->format); + + Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect); + if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) + return; + + Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size)); + + PoolVector<uint8_t>::Write wp = data.write(); + uint8_t *dst_data_ptr = wp.ptr(); + + PoolVector<uint8_t>::Read rp = p_src->data.read(); + const uint8_t *src_data_ptr = rp.ptr(); + + int pixel_size = get_format_pixel_size(format); + + Ref<Image> msk = p_mask; + msk->lock(); + + for (int i = 0; i < dest_rect.size.y; i++) { + + for (int j = 0; j < dest_rect.size.x; j++) { + + int src_x = clipped_src_rect.position.x + j; + int src_y = clipped_src_rect.position.y + i; + + if (msk->get_pixel(src_x, src_y).a != 0) { + + int dst_x = dest_rect.position.x + j; + int dst_y = dest_rect.position.y + i; + + const uint8_t *src = &src_data_ptr[(src_y * p_src->width + src_x) * pixel_size]; + uint8_t *dst = &dst_data_ptr[(dst_y * width + dst_x) * pixel_size]; + + for (int k = 0; k < pixel_size; k++) { + dst[k] = src[k]; + } + } + } + } + + msk->unlock(); +} + void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) { ERR_FAIL_COND(p_src.is_null()); @@ -1681,7 +1737,7 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P dc.g = (double)(sc.a * sc.g + dc.a * (1.0 - sc.a) * dc.g); dc.b = (double)(sc.a * sc.b + dc.a * (1.0 - sc.a) * dc.b); dc.a = (double)(sc.a + dc.a * (1.0 - sc.a)); - put_pixel(dst_x, dst_y, dc); + set_pixel(dst_x, dst_y, dc); } } @@ -1736,7 +1792,7 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c dc.g = (double)(sc.a * sc.g + dc.a * (1.0 - sc.a) * dc.g); dc.b = (double)(sc.a * sc.b + dc.a * (1.0 - sc.a) * dc.b); dc.a = (double)(sc.a + dc.a * (1.0 - sc.a)); - put_pixel(dst_x, dst_y, dc); + set_pixel(dst_x, dst_y, dc); } } } @@ -1756,7 +1812,7 @@ void Image::fill(const Color &c) { int pixel_size = get_format_pixel_size(format); // put first pixel with the format-aware API - put_pixel(0, 0, c); + set_pixel(0, 0, c); for (int y = 0; y < height; y++) { @@ -1985,12 +2041,12 @@ Color Image::get_pixel(int p_x, int p_y) const { return Color(); } -void Image::put_pixel(int p_x, int p_y, const Color &p_color) { +void Image::set_pixel(int p_x, int p_y, const Color &p_color) { uint8_t *ptr = write_lock.ptr(); #ifdef DEBUG_ENABLED if (!ptr) { - ERR_EXPLAIN("Image must be locked with 'lock()' before using put_pixel()"); + ERR_EXPLAIN("Image must be locked with 'lock()' before using set_pixel()"); ERR_FAIL_COND(!ptr); } @@ -2104,7 +2160,7 @@ void Image::put_pixel(int p_x, int p_y, const Color &p_color) { } break; default: { - ERR_EXPLAIN("Can't put_pixel() on compressed image, sorry."); + ERR_EXPLAIN("Can't set_pixel() on compressed image, sorry."); ERR_FAIL(); } } @@ -2167,7 +2223,7 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("get_mipmap_offset", "mipmap"), &Image::get_mipmap_offset); - ClassDB::bind_method(D_METHOD("resize_to_po2", "square"), &Image::resize_to_po2, DEFVAL("false")); + ClassDB::bind_method(D_METHOD("resize_to_po2", "square"), &Image::resize_to_po2, DEFVAL(false)); ClassDB::bind_method(D_METHOD("resize", "width", "height", "interpolation"), &Image::resize, DEFVAL(INTERPOLATE_BILINEAR)); ClassDB::bind_method(D_METHOD("shrink_x2"), &Image::shrink_x2); ClassDB::bind_method(D_METHOD("expand_x2_hq2x"), &Image::expand_x2_hq2x); @@ -2199,6 +2255,7 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("normalmap_to_xy"), &Image::normalmap_to_xy); ClassDB::bind_method(D_METHOD("blit_rect", "src:Image", "src_rect", "dst"), &Image::blit_rect); + ClassDB::bind_method(D_METHOD("blit_rect_mask", "src:Image", "mask:Image", "src_rect", "dst"), &Image::blit_rect_mask); ClassDB::bind_method(D_METHOD("blend_rect", "src:Image", "src_rect", "dst"), &Image::blend_rect); ClassDB::bind_method(D_METHOD("blend_rect_mask", "src:Image", "mask:Image", "src_rect", "dst"), &Image::blend_rect_mask); ClassDB::bind_method(D_METHOD("fill", "color"), &Image::fill); @@ -2213,7 +2270,7 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("lock"), &Image::lock); ClassDB::bind_method(D_METHOD("unlock"), &Image::unlock); - ClassDB::bind_method(D_METHOD("put_pixel", "x", "y", "color"), &Image::put_pixel); + ClassDB::bind_method(D_METHOD("set_pixel", "x", "y", "color"), &Image::set_pixel); ClassDB::bind_method(D_METHOD("get_pixel", "x", "y"), &Image::get_pixel); ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data"); @@ -2377,7 +2434,7 @@ void Image::fix_alpha_edges() { unsigned char *data_ptr = wp.ptr(); const int max_radius = 4; - const int alpha_treshold = 20; + const int alpha_threshold = 20; const int max_dist = 0x7FFFFFFF; for (int i = 0; i < height; i++) { @@ -2386,7 +2443,7 @@ void Image::fix_alpha_edges() { const uint8_t *rptr = &srcptr[(i * width + j) * 4]; uint8_t *wptr = &data_ptr[(i * width + j) * 4]; - if (rptr[3] >= alpha_treshold) + if (rptr[3] >= alpha_threshold) continue; int closest_dist = max_dist; @@ -2408,7 +2465,7 @@ void Image::fix_alpha_edges() { const uint8_t *rp = &srcptr[(k * width + l) << 2]; - if (rp[3] < alpha_treshold) + if (rp[3] < alpha_threshold) continue; closest_color[0] = rp[0]; diff --git a/core/image.h b/core/image.h index 3323afdc4b..7acc4744e9 100644 --- a/core/image.h +++ b/core/image.h @@ -283,6 +283,7 @@ public: void normalmap_to_xy(); void blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest); + void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest); void blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest); void blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest); void fill(const Color &c); @@ -314,7 +315,7 @@ public: DetectChannels get_detected_channels(); Color get_pixel(int p_x, int p_y) const; - void put_pixel(int p_x, int p_y, const Color &p_color); + void set_pixel(int p_x, int p_y, const Color &p_color); void copy_internals_from(const Ref<Image> &p_image) { ERR_FAIL_COND(p_image.is_null()); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 0373176cd2..b474c2e078 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -689,6 +689,7 @@ Error ResourceInteractiveLoaderBinary::poll() { f->close(); resource = res; + resource->set_as_translation_remapped(translation_remapped); error = ERR_FILE_EOF; } else { @@ -706,6 +707,11 @@ int ResourceInteractiveLoaderBinary::get_stage_count() const { return external_resources.size() + internal_resources.size(); } +void ResourceInteractiveLoaderBinary::set_translation_remapped(bool p_remapped) { + + translation_remapped = p_remapped; +} + static void save_ustring(FileAccess *f, const String &p_string) { CharString utf8 = p_string.utf8(); @@ -920,6 +926,7 @@ ResourceInteractiveLoaderBinary::ResourceInteractiveLoaderBinary() { endian_swap = false; use_real64 = false; error = OK; + translation_remapped = false; } ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() { diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 59b9d66d8f..5da5a0fc37 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -36,6 +36,7 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader { + bool translation_remapped; String local_path; String res_path; String type; @@ -87,6 +88,7 @@ public: virtual Error poll(); virtual int get_stage() const; virtual int get_stage_count() const; + virtual void set_translation_remapped(bool p_remapped); void set_remaps(const Map<String, String> &p_remaps) { remaps = p_remaps; } void open(FileAccess *p_f); diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 234d71cb68..bb7be38413 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -29,10 +29,12 @@ /*************************************************************************/ #include "resource_loader.h" #include "global_config.h" +#include "io/resource_import.h" #include "os/file_access.h" #include "os/os.h" #include "path_remap.h" #include "print_string.h" +#include "translation.h" ResourceFormatLoader *ResourceLoader::loader[MAX_LOADERS]; int ResourceLoader::loader_count = 0; @@ -102,6 +104,7 @@ public: virtual Error poll() { return ERR_FILE_EOF; } virtual int get_stage() const { return 1; } virtual int get_stage_count() const { return 1; } + virtual void set_translation_remapped(bool p_remapped) { resource->set_as_translation_remapped(p_remapped); } ResourceInteractiveLoaderDefault() {} }; @@ -165,38 +168,45 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p else local_path = GlobalConfig::get_singleton()->localize_path(p_path); - ERR_FAIL_COND_V(local_path == "", RES()); + bool xl_remapped = false; + String path = _path_remap(local_path, &xl_remapped); - if (!p_no_cache && ResourceCache::has(local_path)) { + ERR_FAIL_COND_V(path == "", RES()); + + if (!p_no_cache && ResourceCache::has(path)) { if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + local_path + " (cached)"); + print_line("load resource: " + path + " (cached)"); - return RES(ResourceCache::get(local_path)); + return RES(ResourceCache::get(path)); } if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + local_path); + print_line("load resource: " + path); bool found = false; // Try all loaders and pick the first match for the type hint for (int i = 0; i < loader_count; i++) { - if (!loader[i]->recognize_path(local_path, p_type_hint)) { + if (!loader[i]->recognize_path(path, p_type_hint)) { continue; } found = true; - RES res = loader[i]->load(local_path, local_path, r_error); + RES res = loader[i]->load(path, path, r_error); if (res.is_null()) { continue; } if (!p_no_cache) res->set_path(local_path); + + if (xl_remapped) + res->set_as_translation_remapped(true); + #ifdef TOOLS_ENABLED res->set_edited(false); if (timestamp_on_load) { - uint64_t mt = FileAccess::get_modified_time(local_path); + uint64_t mt = FileAccess::get_modified_time(path); //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt); res->set_last_modified_time(mt); } @@ -206,9 +216,9 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p } if (found) { - ERR_EXPLAIN("Failed loading resource: " + p_path); + ERR_EXPLAIN("Failed loading resource: " + path); } else { - ERR_EXPLAIN("No loader found for resource: " + p_path); + ERR_EXPLAIN("No loader found for resource: " + path); } ERR_FAIL_V(RES()); return RES(); @@ -225,14 +235,17 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ else local_path = GlobalConfig::get_singleton()->localize_path(p_path); - ERR_FAIL_COND_V(local_path == "", Ref<ResourceInteractiveLoader>()); + bool xl_remapped = false; + String path = _path_remap(local_path, &xl_remapped); + + ERR_FAIL_COND_V(path == "", Ref<ResourceInteractiveLoader>()); - if (!p_no_cache && ResourceCache::has(local_path)) { + if (!p_no_cache && ResourceCache::has(path)) { if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + local_path + " (cached)"); + print_line("load resource: " + path + " (cached)"); - Ref<Resource> res_cached = ResourceCache::get(local_path); + Ref<Resource> res_cached = ResourceCache::get(path); Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault)); ril->resource = res_cached; @@ -246,22 +259,24 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ for (int i = 0; i < loader_count; i++) { - if (!loader[i]->recognize_path(local_path, p_type_hint)) + if (!loader[i]->recognize_path(path, p_type_hint)) continue; found = true; - Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(local_path, r_error); + Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, r_error); if (ril.is_null()) continue; if (!p_no_cache) ril->set_local_path(local_path); + if (xl_remapped) + ril->set_translation_remapped(true); return ril; } if (found) { - ERR_EXPLAIN("Failed loading resource: " + p_path); + ERR_EXPLAIN("Failed loading resource: " + path); } else { - ERR_EXPLAIN("No loader found for resource: " + p_path); + ERR_EXPLAIN("No loader found for resource: " + path); } ERR_FAIL_V(Ref<ResourceInteractiveLoader>()); return Ref<ResourceInteractiveLoader>(); @@ -283,11 +298,13 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { + String path = _path_remap(p_path); + String local_path; - if (p_path.is_rel_path()) - local_path = "res://" + p_path; + if (path.is_rel_path()) + local_path = "res://" + path; else - local_path = GlobalConfig::get_singleton()->localize_path(p_path); + local_path = GlobalConfig::get_singleton()->localize_path(path); for (int i = 0; i < loader_count; i++) { @@ -304,11 +321,13 @@ void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_depe Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) { + String path = _path_remap(p_path); + String local_path; - if (p_path.is_rel_path()) - local_path = "res://" + p_path; + if (path.is_rel_path()) + local_path = "res://" + path; else - local_path = GlobalConfig::get_singleton()->localize_path(p_path); + local_path = GlobalConfig::get_singleton()->localize_path(path); for (int i = 0; i < loader_count; i++) { @@ -342,6 +361,95 @@ String ResourceLoader::get_resource_type(const String &p_path) { return ""; } + +String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_remapped) { + + if (translation_remaps.has(p_path)) { + + Vector<String> &v = *translation_remaps.getptr(p_path); + String locale = TranslationServer::get_singleton()->get_locale(); + if (r_translation_remapped) { + *r_translation_remapped = true; + } + for (int i = 0; i < v.size(); i++) { + + int split = v[i].find_last(":"); + if (split == -1) + continue; + String l = v[i].right(split + 1).strip_edges(); + if (l == String()) + continue; + + if (l.begins_with(locale)) { + return v[i].left(split); + } + } + } + + return p_path; +} + +String ResourceLoader::import_remap(const String &p_path) { + + if (ResourceFormatImporter::get_singleton()->recognize_path(p_path)) { + + return ResourceFormatImporter::get_singleton()->get_internal_resource_path(p_path); + } + + return p_path; +} + +String ResourceLoader::path_remap(const String &p_path) { + return _path_remap(p_path); +} + +void ResourceLoader::reload_translation_remaps() { + + if (ResourceCache::lock) { + ResourceCache::lock->read_lock(); + } + + List<Resource *> to_reload; + SelfList<Resource> *E = remapped_list.first(); + + while (E) { + to_reload.push_back(E->self()); + E = E->next(); + } + + if (ResourceCache::lock) { + ResourceCache::lock->read_unlock(); + } + + //now just make sure to not delete any of these resources while changing locale.. + while (to_reload.front()) { + to_reload.front()->get()->reload_from_file(); + to_reload.pop_front(); + } +} + +void ResourceLoader::load_translation_remaps() { + + Dictionary remaps = GlobalConfig::get_singleton()->get("locale/translation_remaps"); + List<Variant> keys; + remaps.get_key_list(&keys); + for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + + Array langs = remaps[E->get()]; + Vector<String> lang_remaps; + lang_remaps.resize(langs.size()); + for (int i = 0; i < langs.size(); i++) { + lang_remaps[i] = langs[i]; + } + + translation_remaps[String(E->get())] = lang_remaps; + } +} + +void ResourceLoader::clear_translation_remaps() { + translation_remaps.clear(); +} + ResourceLoadErrorNotify ResourceLoader::err_notify = NULL; void *ResourceLoader::err_notify_ud = NULL; @@ -350,3 +458,6 @@ void *ResourceLoader::dep_err_notify_ud = NULL; bool ResourceLoader::abort_on_missing_resource = true; bool ResourceLoader::timestamp_on_load = false; + +SelfList<Resource>::List ResourceLoader::remapped_list; +HashMap<String, Vector<String> > ResourceLoader::translation_remaps; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 54b62f6916..e6687800d7 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -49,6 +49,7 @@ public: virtual Error poll() = 0; virtual int get_stage() const = 0; virtual int get_stage_count() const = 0; + virtual void set_translation_remapped(bool p_remapped) = 0; virtual Error wait(); ResourceInteractiveLoader() {} @@ -87,6 +88,12 @@ class ResourceLoader { static void *dep_err_notify_ud; static DependencyErrorNotify dep_err_notify; static bool abort_on_missing_resource; + static HashMap<String, Vector<String> > translation_remaps; + + static String _path_remap(const String &p_path, bool *r_translation_remapped = NULL); + friend class Resource; + + static SelfList<Resource>::List remapped_list; public: static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL); @@ -118,6 +125,13 @@ public: static void set_abort_on_missing_resources(bool p_abort) { abort_on_missing_resource = p_abort; } static bool get_abort_on_missing_resources() { return abort_on_missing_resource; } + + static String path_remap(const String &p_path); + static String import_remap(const String &p_path); + + static void reload_translation_remaps(); + static void load_translation_remaps(); + static void clear_translation_remaps(); }; #endif diff --git a/core/list.h b/core/list.h index 4390cb65fc..df69b1dc40 100644 --- a/core/list.h +++ b/core/list.h @@ -398,10 +398,7 @@ public: T &operator[](int p_index) { - if (p_index < 0 || p_index >= size()) { - T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux); - } + CRASH_BAD_INDEX(p_index, size()); Element *I = front(); int c = 0; @@ -415,15 +412,12 @@ public: c++; } - ERR_FAIL_V(*((T *)0)); // bug!! + CRASH_NOW(); // bug!! } const T &operator[](int p_index) const { - if (p_index < 0 || p_index >= size()) { - T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux); - } + CRASH_BAD_INDEX(p_index, size()); const Element *I = front(); int c = 0; @@ -437,7 +431,7 @@ public: c++; } - ERR_FAIL_V(*((T *)0)); // bug! + CRASH_NOW(); // bug!! } void move_to_back(Element *p_I) { diff --git a/core/map.h b/core/map.h index acf1d608d8..ef0f75fc9b 100644 --- a/core/map.h +++ b/core/map.h @@ -599,9 +599,9 @@ public: const V &operator[](const K &p_key) const { - ERR_FAIL_COND_V(!_data._root, *(V *)NULL); // crash on purpose + CRASH_COND(!_data._root); const Element *e = find(p_key); - ERR_FAIL_COND_V(!e, *(V *)NULL); // crash on purpose + CRASH_COND(!e); return e->_value; } V &operator[](const K &p_key) { @@ -613,7 +613,7 @@ public: if (!e) e = insert(p_key, V()); - ERR_FAIL_COND_V(!e, *(V *)NULL); // crash on purpose + CRASH_COND(!e); return e->_value; } diff --git a/core/math/face3.cpp b/core/math/face3.cpp index 5b66e1999a..0e292500bf 100644 --- a/core/math/face3.cpp +++ b/core/math/face3.cpp @@ -272,8 +272,8 @@ void Face3::project_range(const Vector3 &p_normal, const Transform &p_transform, void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const { -#define _FACE_IS_VALID_SUPPORT_TRESHOLD 0.98 -#define _EDGE_IS_VALID_SUPPORT_TRESHOLD 0.05 +#define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.98 +#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.05 if (p_max <= 0) return; @@ -281,7 +281,7 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V Vector3 n = p_transform.basis.xform_inv(p_normal); /** TEST FACE AS SUPPORT **/ - if (get_plane().normal.dot(n) > _FACE_IS_VALID_SUPPORT_TRESHOLD) { + if (get_plane().normal.dot(n) > _FACE_IS_VALID_SUPPORT_THRESHOLD) { *p_count = MIN(3, p_max); @@ -318,7 +318,7 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V // check if edge is valid as a support real_t dot = (vertex[i] - vertex[(i + 1) % 3]).normalized().dot(n); dot = ABS(dot); - if (dot < _EDGE_IS_VALID_SUPPORT_TRESHOLD) { + if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { *p_count = MIN(2, p_max); diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp index c733251c3c..b59fecc196 100644 --- a/core/math/matrix3.cpp +++ b/core/math/matrix3.cpp @@ -451,9 +451,10 @@ Basis::operator String() const { } Basis::operator Quat() const { -#ifdef MATH_CHECKS - ERR_FAIL_COND_V(is_rotation() == false, Quat()); -#endif + //commenting this check because precision issues cause it to fail when it shouldn't + //#ifdef MATH_CHECKS + //ERR_FAIL_COND_V(is_rotation() == false, Quat()); + //#endif real_t trace = elements[0][0] + elements[1][1] + elements[2][2]; real_t temp[4]; diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index 9f594ba4fa..54b97ac38c 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -58,7 +58,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me for (int i = 0; i < p_points.size(); i++) { - Vector3 sp = p_points[i].snapped(0.0001); + Vector3 sp = p_points[i].snapped(Vector3(0.0001, 0.0001, 0.0001)); if (valid_cache.has(sp)) { valid_points[i] = false; //print_line("INVALIDATED: "+itos(i)); diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 08ac08d776..1df3c8c298 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -117,7 +117,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) { for (int j = 0; j < 3; j++) { int vidx = -1; - Vector3 vs = v[j].snapped(0.0001); + Vector3 vs = v[j].snapped(Vector3(0.0001, 0.0001, 0.0001)); Map<Vector3, int>::Element *E = db.find(vs); if (E) { vidx = E->get(); diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index e413cc147d..efffacb36e 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -61,13 +61,13 @@ int Vector3::max_axis() const { return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0); } -void Vector3::snap(real_t p_val) { +void Vector3::snap(Vector3 p_val) { - x = Math::stepify(x, p_val); - y = Math::stepify(y, p_val); - z = Math::stepify(z, p_val); + x = Math::stepify(x, p_val.x); + y = Math::stepify(y, p_val.y); + z = Math::stepify(z, p_val.z); } -Vector3 Vector3::snapped(real_t p_val) const { +Vector3 Vector3::snapped(Vector3 p_val) const { Vector3 v = *this; v.snap(p_val); diff --git a/core/math/vector3.h b/core/math/vector3.h index 5f4390fbd1..7dfcedd0da 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -81,8 +81,8 @@ struct Vector3 { _FORCE_INLINE_ void zero(); - void snap(real_t p_val); - Vector3 snapped(real_t p_val) const; + void snap(Vector3 p_val); + Vector3 snapped(Vector3 p_val) const; void rotate(const Vector3 &p_axis, real_t p_phi); Vector3 rotated(const Vector3 &p_axis, real_t p_phi) const; diff --git a/core/method_bind.h b/core/method_bind.h index 8d72c8573a..dbc9cca082 100644 --- a/core/method_bind.h +++ b/core/method_bind.h @@ -343,6 +343,6 @@ MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, i // if you declare an nonexistent class.. class __UnexistingClass; -#include "method_bind.inc" +#include "method_bind.gen.inc" #endif diff --git a/core/object.cpp b/core/object.cpp index f20e93f9d7..3416cd8c5a 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -419,6 +419,16 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid if (r_valid) *r_valid = true; return; +#ifdef TOOLS_ENABLED + } else if (p_name == CoreStringNames::get_singleton()->_sections_unfolded) { + Array arr = p_value; + for (int i = 0; i < arr.size(); i++) { + editor_section_folding.insert(arr[i]); + } + if (r_valid) + *r_valid = true; + return; +#endif } else { //something inside the object... :| bool success = _setv(p_name, p_value); @@ -464,6 +474,16 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const { if (r_valid) *r_valid = true; return ret; +#ifdef TOOLS_ENABLED + } else if (p_name == CoreStringNames::get_singleton()->_sections_unfolded) { + Array array; + for (Set<String>::Element *E = editor_section_folding.front(); E; E = E->next()) { + array.push_back(E->get()); + } + if (r_valid) + *r_valid = true; + return array; +#endif } else { //something inside the object... :| bool success = _getv(p_name, ret); @@ -516,6 +536,11 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons if (!is_class("Script")) // can still be set, but this is for userfriendlyness p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NONZERO)); +#ifdef TOOLS_ENABLED + if (editor_section_folding.size()) { + p_list->push_back(PropertyInfo(Variant::ARRAY, CoreStringNames::get_singleton()->_sections_unfolded, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + } +#endif if (!metadata.empty()) p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_STORE_IF_NONZERO)); if (script_instance && !p_reversed) { @@ -1332,6 +1357,21 @@ Array Object::_get_signal_connection_list(const String &p_signal) const { return ret; } +Array Object::_get_incoming_connections() const { + + Array ret; + int connections_amount = connections.size(); + for (int idx_conn = 0; idx_conn < connections_amount; idx_conn++) { + Dictionary conn_data; + conn_data["source"] = connections[idx_conn].source; + conn_data["signal_name"] = connections[idx_conn].signal; + conn_data["method_name"] = connections[idx_conn].method; + ret.push_back(conn_data); + } + + return ret; +} + void Object::get_signal_list(List<MethodInfo> *p_signals) const { if (!script.is_null()) { @@ -1571,6 +1611,23 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) { } } +#ifdef TOOLS_ENABLED +void Object::editor_set_section_unfold(const String &p_section, bool p_unfolded) { + + set_edited(true); + if (p_unfolded) + editor_section_folding.insert(p_section); + else + editor_section_folding.erase(p_section); +} + +bool Object::editor_is_section_unfolded(const String &p_section) { + + return editor_section_folding.has(p_section); +} + +#endif + void Object::clear_internal_resource_paths() { List<PropertyInfo> pinfo; @@ -1641,6 +1698,7 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("get_signal_list"), &Object::_get_signal_list); ClassDB::bind_method(D_METHOD("get_signal_connection_list", "signal"), &Object::_get_signal_connection_list); + ClassDB::bind_method(D_METHOD("get_incoming_connections"), &Object::_get_incoming_connections); ClassDB::bind_method(D_METHOD("connect", "signal", "target:Object", "method", "binds", "flags"), &Object::connect, DEFVAL(Array()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("disconnect", "signal", "target:Object", "method"), &Object::disconnect); diff --git a/core/object.h b/core/object.h index 83b03b9239..f87705c48b 100644 --- a/core/object.h +++ b/core/object.h @@ -430,6 +430,7 @@ private: #ifdef TOOLS_ENABLED bool _edited; uint32_t _edited_version; + Set<String> editor_section_folding; #endif ScriptInstance *script_instance; RefPtr script; @@ -442,6 +443,7 @@ private: Variant _emit_signal(const Variant **p_args, int p_argcount, Variant::CallError &r_error); Array _get_signal_list() const; Array _get_signal_connection_list(const String &p_signal) const; + Array _get_incoming_connections() const; void _set_bind(const String &p_set, const Variant &p_value); Variant _get_bind(const String &p_name) const; @@ -531,6 +533,12 @@ public: void add_change_receptor(Object *p_receptor); void remove_change_receptor(Object *p_receptor); +// TODO: ensure 'this' is never NULL since it's UB, but by now, avoid warning flood +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundefined-bool-conversion" +#endif + template <class T> T *cast_to() { @@ -561,6 +569,10 @@ public: #endif } +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + enum { NOTIFICATION_POSTINITIALIZE = 0, @@ -666,6 +678,11 @@ public: _FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate = p_enable; } _FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; } +#ifdef TOOLS_ENABLED + void editor_set_section_unfold(const String &p_section, bool p_unfolded); + bool editor_is_section_unfolded(const String &p_section); +#endif + void clear_internal_resource_paths(); Object(); diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index e60f588be3..1c575aa970 100644 --- a/core/os/input_event.cpp +++ b/core/os/input_event.cpp @@ -140,6 +140,8 @@ void InputEvent::_bind_methods() { ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type); ClassDB::bind_method(D_METHOD("xformed_by:InputEvent", "xform", "local_ofs"), &InputEvent::xformed_by, DEFVAL(Vector2())); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "device"), "set_device", "get_device"); } InputEvent::InputEvent() { diff --git a/core/resource.cpp b/core/resource.cpp index 559d4c1201..a7a5498ef6 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -31,9 +31,9 @@ #include "core_string_names.h" #include "io/resource_loader.h" +#include "io/resource_loader.h" #include "os/file_access.h" #include "script_language.h" - #include <stdio.h> void Resource::emit_changed() { @@ -127,7 +127,7 @@ void Resource::reload_from_file() { if (!path.is_resource_file()) return; - Ref<Resource> s = ResourceLoader::load(path, get_class(), true); + Ref<Resource> s = ResourceLoader::load(ResourceLoader::path_remap(path), get_class(), true); if (!s.is_valid()) return; @@ -302,6 +302,31 @@ void Resource::setup_local_to_scene() { Node *(*Resource::_get_local_scene_func)() = NULL; +void Resource::set_as_translation_remapped(bool p_remapped) { + + if (remapped_list.in_list() == p_remapped) + return; + + if (ResourceCache::lock) { + ResourceCache::lock->write_lock(); + } + + if (p_remapped) { + ResourceLoader::remapped_list.add(&remapped_list); + } else { + ResourceLoader::remapped_list.remove(&remapped_list); + } + + if (ResourceCache::lock) { + ResourceCache::lock->write_unlock(); + } +} + +bool Resource::is_translation_remapped() const { + + return remapped_list.in_list(); +} + void Resource::_bind_methods() { ClassDB::bind_method(D_METHOD("set_path", "path"), &Resource::_set_path); @@ -325,7 +350,8 @@ void Resource::_bind_methods() { BIND_VMETHOD(MethodInfo("_setup_local_to_scene")); } -Resource::Resource() { +Resource::Resource() + : remapped_list(this) { #ifdef TOOLS_ENABLED last_modified_time = 0; diff --git a/core/resource.h b/core/resource.h index 903edeff52..5a4e45da36 100644 --- a/core/resource.h +++ b/core/resource.h @@ -35,6 +35,7 @@ #include "ref_ptr.h" #include "reference.h" #include "safe_refcount.h" +#include "self_list.h" /** @author Juan Linietsky <reduzio@gmail.com> @@ -74,6 +75,8 @@ class Resource : public Reference { friend class SceneState; Node *local_scene; + SelfList<Resource> remapped_list; + protected: void emit_changed(); @@ -127,6 +130,9 @@ public: #endif + void set_as_translation_remapped(bool p_remapped); + bool is_translation_remapped() const; + virtual RID get_rid() const; // some resources may offer conversion to RID Resource(); @@ -137,6 +143,7 @@ typedef Ref<Resource> RES; class ResourceCache { friend class Resource; + friend class ResourceLoader; //need the lock static RWLock *lock; static HashMap<String, Resource *> resources; friend void unregister_core_types(); diff --git a/core/sort.h b/core/sort.h index a45eb8865a..06c427f61e 100644 --- a/core/sort.h +++ b/core/sort.h @@ -46,7 +46,7 @@ class SortArray { enum { - INTROSORT_TRESHOLD = 16 + INTROSORT_THRESHOLD = 16 }; public: @@ -180,7 +180,7 @@ public: inline void introsort(int p_first, int p_last, T *p_array, int p_max_depth) const { - while (p_last - p_first > INTROSORT_TRESHOLD) { + while (p_last - p_first > INTROSORT_THRESHOLD) { if (p_max_depth == 0) { partial_sort(p_first, p_last, p_last, p_array); @@ -273,9 +273,9 @@ public: inline void final_insertion_sort(int p_first, int p_last, T *p_array) const { - if (p_last - p_first > INTROSORT_TRESHOLD) { - insertion_sort(p_first, p_first + INTROSORT_TRESHOLD, p_array); - unguarded_insertion_sort(p_first + INTROSORT_TRESHOLD, p_last, p_array); + if (p_last - p_first > INTROSORT_THRESHOLD) { + insertion_sort(p_first, p_first + INTROSORT_THRESHOLD, p_array); + unguarded_insertion_sort(p_first + INTROSORT_THRESHOLD, p_last, p_array); } else { insertion_sort(p_first, p_last, p_array); diff --git a/core/translation.cpp b/core/translation.cpp index bd670167f9..72231ef295 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -870,6 +870,10 @@ void Translation::set_locale(const String &p_locale) { } else { locale = univ_locale; } + + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); + } } void Translation::add_message(const StringName &p_src_text, const StringName &p_xlated_text) { @@ -945,6 +949,8 @@ void TranslationServer::set_locale(const String &p_locale) { if (OS::get_singleton()->get_main_loop()) { OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); } + + ResourceLoader::reload_translation_remaps(); } String TranslationServer::get_locale() const { diff --git a/core/ustring.cpp b/core/ustring.cpp index 7ccf7fd209..ab4528e495 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -96,6 +96,12 @@ const char *CharString::get_data() const { void String::copy_from(const char *p_cstr) { + if (!p_cstr) { + + resize(0); + return; + } + int len = 0; const char *ptr = p_cstr; while (*(ptr++) != 0) @@ -119,6 +125,12 @@ void String::copy_from(const char *p_cstr) { void String::copy_from(const CharType *p_cstr, int p_clip_to) { + if (!p_cstr) { + + resize(0); + return; + } + int len = 0; const CharType *ptr = p_cstr; while (*(ptr++) != 0) diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 7b2d0f6886..5fda6b1473 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -1109,11 +1109,11 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) const String *str = reinterpret_cast<const String *>(p_index._data._mem); Vector2 *v = reinterpret_cast<Vector2 *>(_data._mem); - if (*str == "x" || *str == "width") { + if (*str == "x") { valid = true; v->x = p_value; return; - } else if (*str == "y" || *str == "height") { + } else if (*str == "y") { valid = true; v->y = p_value; return; @@ -1177,7 +1177,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) valid = true; v->elements[1] = p_value; return; - } else if (*str == "o") { + } else if (*str == "origin") { valid = true; v->elements[2] = p_value; return; @@ -1572,10 +1572,10 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const { const String *str = reinterpret_cast<const String *>(p_index._data._mem); const Vector2 *v = reinterpret_cast<const Vector2 *>(_data._mem); - if (*str == "x" || *str == "width") { + if (*str == "x") { valid = true; return v->x; - } else if (*str == "y" || *str == "height") { + } else if (*str == "y") { valid = true; return v->y; } @@ -1657,7 +1657,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const { } else if (*str == "y") { valid = true; return v->elements[1]; - } else if (*str == "o") { + } else if (*str == "origin") { valid = true; return v->elements[2]; } @@ -2105,8 +2105,6 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::REAL, "x")); p_list->push_back(PropertyInfo(Variant::REAL, "y")); - p_list->push_back(PropertyInfo(Variant::REAL, "width")); - p_list->push_back(PropertyInfo(Variant::REAL, "height")); } break; // 5 case RECT2: { @@ -2127,7 +2125,7 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::VECTOR2, "x")); p_list->push_back(PropertyInfo(Variant::VECTOR2, "y")); - p_list->push_back(PropertyInfo(Variant::VECTOR2, "o")); + p_list->push_back(PropertyInfo(Variant::VECTOR2, "origin")); } break; case PLANE: { @@ -2148,7 +2146,7 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { } break; // 10 case RECT3: { - p_list->push_back(PropertyInfo(Variant::VECTOR3, "pos")); + p_list->push_back(PropertyInfo(Variant::VECTOR3, "position")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "size")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "end")); } break; @@ -2236,30 +2234,30 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { return _data._int > 0; } break; case REAL: { - r_iter = 0.0; + r_iter = 0; return _data._real > 0.0; } break; case VECTOR2: { - real_t from = reinterpret_cast<const Vector2 *>(_data._mem)->x; - real_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y; + int64_t from = reinterpret_cast<const Vector2 *>(_data._mem)->x; + int64_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y; r_iter = from; return from < to; } break; case VECTOR3: { - real_t from = reinterpret_cast<const Vector3 *>(_data._mem)->x; - real_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; - real_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; + int64_t from = reinterpret_cast<const Vector3 *>(_data._mem)->x; + int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; + int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; r_iter = from; if (from == to) { return false; } else if (from < to) { - return step > 0.0; + return step > 0; } else { - return step < 0.0; + return step < 0; } //return true; } break; @@ -2387,7 +2385,6 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { valid = true; switch (type) { case INT: { - int64_t idx = r_iter; idx++; if (idx >= _data._int) @@ -2396,33 +2393,36 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { return true; } break; case REAL: { - - double idx = r_iter; - idx += 1.0; + int64_t idx = r_iter; + idx++; if (idx >= _data._real) return false; r_iter = idx; return true; } break; case VECTOR2: { - real_t idx = r_iter; - idx += 1.0; - if (idx >= reinterpret_cast<const Vector2 *>(_data._mem)->y) + int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; + + int64_t idx = r_iter; + idx++; + + if (idx >= to) return false; + r_iter = idx; return true; } break; case VECTOR3: { - real_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; - real_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; + int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; + int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; - real_t idx = r_iter; + int64_t idx = r_iter; idx += step; - if (step < 0.0 && idx <= to) + if (step < 0 && idx <= to) return false; - if (step > 0.0 && idx >= to) + if (step > 0 && idx >= to) return false; r_iter = idx; diff --git a/core/vector.h b/core/vector.h index fe1c1b05dd..5eed8dce96 100644 --- a/core/vector.h +++ b/core/vector.h @@ -134,10 +134,7 @@ public: inline T &operator[](int p_index) { - if (p_index < 0 || p_index >= size()) { - T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux); - } + CRASH_BAD_INDEX(p_index, size()); _copy_on_write(); // wants to write, so copy on write. @@ -146,10 +143,8 @@ public: inline const T &operator[](int p_index) const { - if (p_index < 0 || p_index >= size()) { - const T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux); - } + CRASH_BAD_INDEX(p_index, size()); + // no cow needed, since it's reading return _get_data()[p_index]; } diff --git a/core/version.h b/core/version.h index 80e50e51b9..43f6f1bbf9 100644 --- a/core/version.h +++ b/core/version.h @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "version_generated.h" +#include "version_generated.gen.h" #ifdef VERSION_PATCH #define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_PATCH) "." _MKSTR(VERSION_STATUS) "." _MKSTR(VERSION_REVISION) diff --git a/core/vmap.h b/core/vmap.h index ad07973308..66f935f58d 100644 --- a/core/vmap.h +++ b/core/vmap.h @@ -180,10 +180,8 @@ public: inline const V &operator[](const T &p_key) const { int pos = _find_exact(p_key); - if (pos < 0) { - const T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(pos < 1, aux); - } + + CRASH_COND(pos < 0); return _data[pos].value; } |