diff options
Diffstat (limited to 'core')
36 files changed, 241 insertions, 103 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 34bbdb2c75..b41b84ab1e 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -2941,6 +2941,10 @@ float _Engine::get_physics_jitter_fix() const { return Engine::get_singleton()->get_physics_jitter_fix(); } +float _Engine::get_physics_interpolation_fraction() const { + return Engine::get_singleton()->get_physics_interpolation_fraction(); +} + void _Engine::set_target_fps(int p_fps) { Engine::get_singleton()->set_target_fps(p_fps); } @@ -3029,6 +3033,7 @@ void _Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("get_iterations_per_second"), &_Engine::get_iterations_per_second); ClassDB::bind_method(D_METHOD("set_physics_jitter_fix", "physics_jitter_fix"), &_Engine::set_physics_jitter_fix); ClassDB::bind_method(D_METHOD("get_physics_jitter_fix"), &_Engine::get_physics_jitter_fix); + ClassDB::bind_method(D_METHOD("get_physics_interpolation_fraction"), &_Engine::get_physics_interpolation_fraction); ClassDB::bind_method(D_METHOD("set_target_fps", "target_fps"), &_Engine::set_target_fps); ClassDB::bind_method(D_METHOD("get_target_fps"), &_Engine::get_target_fps); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 3be5a08752..f0f86e003f 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -746,6 +746,7 @@ public: void set_physics_jitter_fix(float p_threshold); float get_physics_jitter_fix() const; + float get_physics_interpolation_fraction() const; void set_target_fps(int p_fps); int get_target_fps() const; diff --git a/core/class_db.cpp b/core/class_db.cpp index 794d990083..49e3f94d8f 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -480,6 +480,7 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { PropertySetGet *psg = t->property_setget.getptr(F->get()); + ERR_FAIL_COND_V(!psg, 0); hash = hash_djb2_one_64(F->get().hash(), hash); hash = hash_djb2_one_64(psg->setter.hash(), hash); diff --git a/core/engine.cpp b/core/engine.cpp index 2d8473fbd9..0dd0459403 100644 --- a/core/engine.cpp +++ b/core/engine.cpp @@ -227,6 +227,7 @@ Engine::Engine() { frames_drawn = 0; ips = 60; physics_jitter_fix = 0.5; + _physics_interpolation_fraction = 0.0f; _frame_delay = 0; _fps = 1; _target_fps = 0; diff --git a/core/engine.h b/core/engine.h index 15665fee29..192e8e67a0 100644 --- a/core/engine.h +++ b/core/engine.h @@ -63,6 +63,7 @@ private: float _time_scale; bool _pixel_snap; uint64_t _physics_frames; + float _physics_interpolation_fraction; uint64_t _idle_frames; bool _in_physics; @@ -95,6 +96,7 @@ public: bool is_in_physics_frame() const { return _in_physics; } uint64_t get_idle_frame_ticks() const { return _frame_ticks; } float get_idle_frame_step() const { return _frame_step; } + float get_physics_interpolation_fraction() const { return _physics_interpolation_fraction; } void set_time_scale(float p_scale); float get_time_scale() const; diff --git a/core/image.cpp b/core/image.cpp index a88395204a..10778eced6 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -240,27 +240,27 @@ int Image::get_format_block_size(Format p_format) { case FORMAT_RGTC_RG: { //bc5 case case FORMAT_DXT1: return 4; - } break; + } case FORMAT_PVRTC2: case FORMAT_PVRTC2A: { return 4; - } break; + } case FORMAT_PVRTC4A: case FORMAT_PVRTC4: { return 4; - } break; + } case FORMAT_ETC: { return 4; - } break; + } case FORMAT_BPTC_RGBA: case FORMAT_BPTC_RGBF: case FORMAT_BPTC_RGBFU: { return 4; - } break; + } case FORMAT_ETC2_R11: //etc2 case FORMAT_ETC2_R11S: //signed: NOT srgb. case FORMAT_ETC2_RG11: @@ -270,7 +270,7 @@ int Image::get_format_block_size(Format p_format) { case FORMAT_ETC2_RGB8A1: { return 4; - } break; + } default: { } } @@ -852,7 +852,7 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict static void _overlay(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, float p_alpha, uint32_t p_width, uint32_t p_height, uint32_t p_pixel_size) { - uint16_t alpha = CLAMP((uint16_t)(p_alpha * 256.0f), 0, 256); + uint16_t alpha = MIN((uint16_t)(p_alpha * 256.0f), 256); for (uint32_t i = 0; i < p_width * p_height * p_pixel_size; i++) { @@ -2421,38 +2421,36 @@ Color Image::get_pixel(int p_x, int p_y) const { case FORMAT_L8: { float l = ptr[ofs] / 255.0; return Color(l, l, l, 1); - } break; + } case FORMAT_LA8: { float l = ptr[ofs * 2 + 0] / 255.0; float a = ptr[ofs * 2 + 1] / 255.0; return Color(l, l, l, a); - } break; + } case FORMAT_R8: { float r = ptr[ofs] / 255.0; return Color(r, 0, 0, 1); - } break; + } case FORMAT_RG8: { float r = ptr[ofs * 2 + 0] / 255.0; float g = ptr[ofs * 2 + 1] / 255.0; return Color(r, g, 0, 1); - } break; + } case FORMAT_RGB8: { float r = ptr[ofs * 3 + 0] / 255.0; float g = ptr[ofs * 3 + 1] / 255.0; float b = ptr[ofs * 3 + 2] / 255.0; return Color(r, g, b, 1); - - } break; + } case FORMAT_RGBA8: { float r = ptr[ofs * 4 + 0] / 255.0; float g = ptr[ofs * 4 + 1] / 255.0; float b = ptr[ofs * 4 + 2] / 255.0; float a = ptr[ofs * 4 + 3] / 255.0; return Color(r, g, b, a); - - } break; + } case FORMAT_RGBA4444: { uint16_t u = ((uint16_t *)ptr)[ofs]; float r = (u & 0xF) / 15.0; @@ -2460,8 +2458,7 @@ Color Image::get_pixel(int p_x, int p_y) const { float b = ((u >> 8) & 0xF) / 15.0; float a = ((u >> 12) & 0xF) / 15.0; return Color(r, g, b, a); - - } break; + } case FORMAT_RGBA5551: { uint16_t u = ((uint16_t *)ptr)[ofs]; @@ -2470,25 +2467,25 @@ Color Image::get_pixel(int p_x, int p_y) const { float b = ((u >> 10) & 0x1F) / 15.0; float a = ((u >> 15) & 0x1) / 1.0; return Color(r, g, b, a); - } break; + } case FORMAT_RF: { float r = ((float *)ptr)[ofs]; return Color(r, 0, 0, 1); - } break; + } case FORMAT_RGF: { float r = ((float *)ptr)[ofs * 2 + 0]; float g = ((float *)ptr)[ofs * 2 + 1]; return Color(r, g, 0, 1); - } break; + } case FORMAT_RGBF: { float r = ((float *)ptr)[ofs * 3 + 0]; float g = ((float *)ptr)[ofs * 3 + 1]; float b = ((float *)ptr)[ofs * 3 + 2]; return Color(r, g, b, 1); - } break; + } case FORMAT_RGBAF: { float r = ((float *)ptr)[ofs * 4 + 0]; @@ -2496,25 +2493,25 @@ Color Image::get_pixel(int p_x, int p_y) const { float b = ((float *)ptr)[ofs * 4 + 2]; float a = ((float *)ptr)[ofs * 4 + 3]; return Color(r, g, b, a); - } break; + } case FORMAT_RH: { uint16_t r = ((uint16_t *)ptr)[ofs]; return Color(Math::half_to_float(r), 0, 0, 1); - } break; + } case FORMAT_RGH: { uint16_t r = ((uint16_t *)ptr)[ofs * 2 + 0]; uint16_t g = ((uint16_t *)ptr)[ofs * 2 + 1]; return Color(Math::half_to_float(r), Math::half_to_float(g), 0, 1); - } break; + } case FORMAT_RGBH: { uint16_t r = ((uint16_t *)ptr)[ofs * 3 + 0]; uint16_t g = ((uint16_t *)ptr)[ofs * 3 + 1]; uint16_t b = ((uint16_t *)ptr)[ofs * 3 + 2]; return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), 1); - } break; + } case FORMAT_RGBAH: { uint16_t r = ((uint16_t *)ptr)[ofs * 4 + 0]; @@ -2522,18 +2519,15 @@ Color Image::get_pixel(int p_x, int p_y) const { uint16_t b = ((uint16_t *)ptr)[ofs * 4 + 2]; uint16_t a = ((uint16_t *)ptr)[ofs * 4 + 3]; return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), Math::half_to_float(a)); - } break; + } case FORMAT_RGBE9995: { return Color::from_rgbe9995(((uint32_t *)ptr)[ofs]); - - } break; + } default: { ERR_EXPLAIN("Can't get_pixel() on compressed image, sorry."); ERR_FAIL_V(Color()); } } - - return Color(); } void Image::set_pixelv(const Point2 &p_dst, const Color &p_color) { diff --git a/core/input_map.cpp b/core/input_map.cpp index 04911787a8..165999f081 100644 --- a/core/input_map.cpp +++ b/core/input_map.cpp @@ -202,7 +202,7 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str if (p_pressed != NULL) *p_pressed = input_event_action->is_pressed(); if (p_strength != NULL) - *p_strength = (*p_pressed) ? input_event_action->get_strength() : 0.0f; + *p_strength = (p_pressed != NULL && *p_pressed) ? input_event_action->get_strength() : 0.0f; return input_event_action->get_action() == p_action; } diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 6c4310a572..102cd9cf6c 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -208,7 +208,8 @@ void FileAccessCompressed::seek(size_t p_position) { if (p_position == read_total) { at_end = true; } else { - + at_end = false; + read_eof = false; int block_idx = p_position / block_size; if (block_idx != read_block) { diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index c77c81f9e2..1e4ea715b3 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -110,10 +110,11 @@ Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) { Variant PacketPeer::_bnd_get_var(bool p_allow_objects) { Variant var; - get_var(var, p_allow_objects); + Error err = get_var(var, p_allow_objects); + ERR_FAIL_COND_V(err != OK, Variant()); return var; -}; +} Error PacketPeer::_put_packet(const PoolVector<uint8_t> &p_buffer) { return put_packet_buffer(p_buffer); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 861e34e415..146480e5a2 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -712,14 +712,14 @@ Error ResourceInteractiveLoaderBinary::poll() { if (!obj) { error = ERR_FILE_CORRUPT; ERR_EXPLAIN(local_path + ":Resource of unrecognized type in file: " + t); + ERR_FAIL_V(ERR_FILE_CORRUPT); } - ERR_FAIL_COND_V(!obj, ERR_FILE_CORRUPT); Resource *r = Object::cast_to<Resource>(obj); if (!r) { error = ERR_FILE_CORRUPT; - memdelete(obj); //bye ERR_EXPLAIN(local_path + ":Resource type in resource field not a resource, type is: " + obj->get_class()); + memdelete(obj); //bye ERR_FAIL_V(ERR_FILE_CORRUPT); } diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index 0cecca904d..e2c1c3402a 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -137,7 +137,6 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t save_callback(p_resource, p_path); return OK; - } else { } } diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index acf72dbba5..84b8554d54 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -369,7 +369,9 @@ Variant StreamPeer::get_var(bool p_allow_objects) { ERR_FAIL_COND_V(err != OK, Variant()); Variant ret; - decode_variant(ret, var.ptr(), len, NULL, p_allow_objects); + err = decode_variant(ret, var.ptr(), len, NULL, p_allow_objects); + ERR_FAIL_COND_V(err != OK, Variant()); + return ret; } diff --git a/core/make_binders.py b/core/make_binders.py index 24901c42a1..c38db5cef4 100644 --- a/core/make_binders.py +++ b/core/make_binders.py @@ -334,9 +334,6 @@ def make_version(template, nargs, argmax, const, ret): elif (cmd == "noarg"): for i in range(nargs + 1, argmax + 1): outtext += data.replace("@", str(i)) - elif (cmd == "noarg"): - for i in range(nargs + 1, argmax + 1): - outtext += data.replace("@", str(i)) from_pos = end + 1 diff --git a/core/map.h b/core/map.h index a701ba36f7..c8197639f2 100644 --- a/core/map.h +++ b/core/map.h @@ -38,7 +38,7 @@ */ // based on the very nice implementation of rb-trees by: -// http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html +// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html template <class K, class V, class C = Comparator<K>, class A = DefaultAllocator> class Map { diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp index a12f9fee2e..cfa698282e 100644 --- a/core/math/bsp_tree.cpp +++ b/core/math/bsp_tree.cpp @@ -192,7 +192,7 @@ int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) cons #ifdef DEBUG_ENABLED int plane_count = planes.size(); uint16_t plane = nodesptr[idx].plane; - ERR_FAIL_INDEX_V(plane, plane_count, false); + ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, false); #endif idx = planesptr[nodesptr[idx].plane].is_point_over(point) ? nodes[idx].over : nodes[idx].under; @@ -258,7 +258,7 @@ bool BSP_Tree::point_is_inside(const Vector3 &p_point) const { #ifdef DEBUG_ENABLED int plane_count = planes.size(); uint16_t plane = nodesptr[idx].plane; - ERR_FAIL_INDEX_V(plane, plane_count, false); + ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, false); #endif bool over = planesptr[nodesptr[idx].plane].is_point_over(p_point); diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 8b3b6c82f3..30c0cab909 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -302,8 +302,8 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform &p_transform) /** Fast Plane Extraction from combined modelview/projection matrices. * References: - * http://www.markmorley.com/opengl/frustumculling.html - * http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf + * https://web.archive.org/web/20011221205252/http://www.markmorley.com/opengl/frustumculling.html + * https://web.archive.org/web/20061020020112/http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf */ Vector<Plane> planes; diff --git a/core/math/expression.cpp b/core/math/expression.cpp index b52658e2cf..15eea1d308 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -52,6 +52,7 @@ const char *Expression::func_name[Expression::FUNC_MAX] = { "sqrt", "fmod", "fposmod", + "posmod", "floor", "ceil", "round", @@ -67,6 +68,7 @@ const char *Expression::func_name[Expression::FUNC_MAX] = { "step_decimals", "stepify", "lerp", + "lerp_angle", "inverse_lerp", "range_lerp", "smoothstep", @@ -175,6 +177,7 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) { case MATH_ATAN2: case MATH_FMOD: case MATH_FPOSMOD: + case MATH_POSMOD: case MATH_POW: case MATH_EASE: case MATH_STEPIFY: @@ -188,6 +191,7 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) { case COLORN: return 2; case MATH_LERP: + case MATH_LERP_ANGLE: case MATH_INVERSE_LERP: case MATH_SMOOTHSTEP: case MATH_MOVE_TOWARD: @@ -283,6 +287,12 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant VALIDATE_ARG_NUM(1); *r_return = Math::fposmod((double)*p_inputs[0], (double)*p_inputs[1]); } break; + case MATH_POSMOD: { + + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + *r_return = Math::posmod((int)*p_inputs[0], (int)*p_inputs[1]); + } break; case MATH_FLOOR: { VALIDATE_ARG_NUM(0); @@ -387,6 +397,13 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant VALIDATE_ARG_NUM(2); *r_return = Math::lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); } break; + case MATH_LERP_ANGLE: { + + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + VALIDATE_ARG_NUM(2); + *r_return = Math::lerp_angle((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); + } break; case MATH_INVERSE_LERP: { VALIDATE_ARG_NUM(0); @@ -793,17 +810,13 @@ Error Expression::_get_token(Token &r_token) { #define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++]) CharType cchar = GET_CHAR(); - if (cchar == 0) { - r_token.type = TK_EOF; - return OK; - } switch (cchar) { case 0: { r_token.type = TK_EOF; return OK; - } break; + }; case '{': { r_token.type = TK_CURLY_BRACKET_OPEN; diff --git a/core/math/expression.h b/core/math/expression.h index 1113bb6587..833220592c 100644 --- a/core/math/expression.h +++ b/core/math/expression.h @@ -51,6 +51,7 @@ public: MATH_SQRT, MATH_FMOD, MATH_FPOSMOD, + MATH_POSMOD, MATH_FLOOR, MATH_CEIL, MATH_ROUND, @@ -66,6 +67,7 @@ public: MATH_STEP_DECIMALS, MATH_STEPIFY, MATH_LERP, + MATH_LERP_ANGLE, MATH_INVERSE_LERP, MATH_RANGE_LERP, MATH_SMOOTHSTEP, diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index 7a2e74a413..f04e40cb6c 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -79,6 +79,15 @@ int Math::step_decimals(double p_step) { return 0; } +// Only meant for editor usage in float ranges, where a step of 0 +// means that decimal digits should not be limited in String::num. +int Math::range_step_decimals(double p_step) { + if (p_step < 0.0000000000001) { + return 16; // Max value hardcoded in String::num + } + return step_decimals(p_step); +} + double Math::dectime(double p_value, double p_amount, double p_step) { double sgn = p_value < 0 ? -1.0 : 1.0; double val = Math::abs(p_value); diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 0e3bd8a318..af845ca01e 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -198,6 +198,13 @@ public: value += 0.0; return value; } + static _ALWAYS_INLINE_ int posmod(int p_x, int p_y) { + int value = p_x % p_y; + if ((value < 0 && p_y > 0) || (value > 0 && p_y < 0)) { + value += p_y; + } + return value; + } static _ALWAYS_INLINE_ double deg2rad(double p_y) { return p_y * Math_PI / 180.0; } static _ALWAYS_INLINE_ float deg2rad(float p_y) { return p_y * Math_PI / 180.0; } @@ -208,6 +215,17 @@ public: static _ALWAYS_INLINE_ double lerp(double p_from, double p_to, double p_weight) { return p_from + (p_to - p_from) * p_weight; } static _ALWAYS_INLINE_ float lerp(float p_from, float p_to, float p_weight) { return p_from + (p_to - p_from) * p_weight; } + static _ALWAYS_INLINE_ double lerp_angle(double p_from, double p_to, double p_weight) { + double difference = fmod(p_to - p_from, Math_TAU); + double distance = fmod(2.0 * difference, Math_TAU) - difference; + return p_from + distance * p_weight; + } + static _ALWAYS_INLINE_ float lerp_angle(float p_from, float p_to, float p_weight) { + float difference = fmod(p_to - p_from, (float)Math_TAU); + float distance = fmod(2.0f * difference, (float)Math_TAU) - difference; + return p_from + distance * p_weight; + } + static _ALWAYS_INLINE_ double inverse_lerp(double p_from, double p_to, double p_value) { return (p_value - p_from) / (p_to - p_from); } static _ALWAYS_INLINE_ float inverse_lerp(float p_from, float p_to, float p_value) { return (p_value - p_from) / (p_to - p_from); } @@ -237,21 +255,22 @@ public: static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); } static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) { - int64_t rng = max - min; - return (rng != 0) ? min + ((((value - min) % rng) + rng) % rng) : min; + int64_t range = max - min; + return range == 0 ? min : min + ((((value - min) % range) + range) % range); } static _ALWAYS_INLINE_ double wrapf(double value, double min, double max) { - double rng = max - min; - return (!is_equal_approx(rng, 0.0)) ? value - (rng * Math::floor((value - min) / rng)) : min; + double range = max - min; + return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range)); } static _ALWAYS_INLINE_ float wrapf(float value, float min, float max) { - float rng = max - min; - return (!is_equal_approx(rng, 0.0f)) ? value - (rng * Math::floor((value - min) / rng)) : min; + float range = max - min; + return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range)); } // double only, as these functions are mainly used by the editor and not performance-critical, static double ease(double p_x, double p_c); static int step_decimals(double p_step); + static int range_step_decimals(double p_step); static double stepify(double p_value, double p_step); static double dectime(double p_value, double p_amount, double p_step); diff --git a/core/object.h b/core/object.h index 1e0b22c086..dce1cc74ae 100644 --- a/core/object.h +++ b/core/object.h @@ -58,7 +58,7 @@ enum PropertyHint { PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc" PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout") PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer) - PROPERTY_HINT_SPRITE_FRAME, + PROPERTY_HINT_SPRITE_FRAME, // FIXME: Obsolete: drop whenever we can break compat. Keeping now for GDNative compat. PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer) PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags) PROPERTY_HINT_LAYERS_2D_RENDER, @@ -104,7 +104,8 @@ enum PropertyUsageFlags { PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor PROPERTY_USAGE_CATEGORY = 256, - //those below are deprecated thanks to ClassDB's now class value cache + // FIXME: Drop in 4.0, possibly reorder other flags? + // Those below are deprecated thanks to ClassDB's now class value cache //PROPERTY_USAGE_STORE_IF_NONZERO = 512, //only store if nonzero //PROPERTY_USAGE_STORE_IF_NONONE = 1024, //only store if false PROPERTY_USAGE_NO_INSTANCE_STATE = 2048, @@ -121,6 +122,7 @@ enum PropertyUsageFlags { PROPERTY_USAGE_HIGH_END_GFX = 1 << 22, PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 23, PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 24, + PROPERTY_USAGE_KEYING_INCREMENTS = 1 << 25, // Used in inspector to increment property when keyed in animation player PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK, PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED, @@ -179,6 +181,15 @@ struct PropertyInfo { usage(PROPERTY_USAGE_DEFAULT) { } + bool operator==(const PropertyInfo &p_info) const { + return ((type == p_info.type) && + (name == p_info.name) && + (class_name == p_info.class_name) && + (hint == p_info.hint) && + (hint_string == p_info.hint_string) && + (usage == p_info.usage)); + } + bool operator<(const PropertyInfo &p_info) const { return name < p_info.name; } diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp index 0cdb5b41b7..b444f0ae1e 100644 --- a/core/os/dir_access.cpp +++ b/core/os/dir_access.cpp @@ -179,14 +179,6 @@ Error DirAccess::make_dir_recursive(String p_dir) { return OK; } -String DirAccess::get_next(bool *p_is_dir) { - - String next = get_next(); - if (p_is_dir) - *p_is_dir = current_is_dir(); - return next; -} - String DirAccess::fix_path(String p_path) const { switch (_access_type) { diff --git a/core/os/dir_access.h b/core/os/dir_access.h index bde19bd5ae..704eedae5b 100644 --- a/core/os/dir_access.h +++ b/core/os/dir_access.h @@ -71,7 +71,6 @@ protected: public: virtual Error list_dir_begin() = 0; ///< This starts dir listing - virtual String get_next(bool *p_is_dir); // compatibility virtual String get_next() = 0; virtual bool current_is_dir() const = 0; virtual bool current_is_hidden() const = 0; diff --git a/core/pool_allocator.cpp b/core/pool_allocator.cpp index 094352b5cc..9b342ef913 100644 --- a/core/pool_allocator.cpp +++ b/core/pool_allocator.cpp @@ -611,7 +611,7 @@ PoolAllocator::PoolAllocator(void *p_mem, int p_size, int p_align, bool p_needs_ PoolAllocator::PoolAllocator(int p_align, int p_size, bool p_needs_locking, int p_max_entries) { ERR_FAIL_COND(p_align < 1); - mem_ptr = Memory::alloc_static(p_size + p_align, "PoolAllocator()"); + mem_ptr = Memory::alloc_static(p_size + p_align, true); uint8_t *mem8 = (uint8_t *)mem_ptr; uint64_t ofs = (uint64_t)mem8; if (ofs % p_align) diff --git a/core/pool_vector.h b/core/pool_vector.h index 98a52c6938..3d28d86803 100644 --- a/core/pool_vector.h +++ b/core/pool_vector.h @@ -458,7 +458,7 @@ public: bool is_locked() const { return alloc && alloc->lock > 0; } - inline const T operator[](int p_index) const; + inline T operator[](int p_index) const; Error resize(int p_size); @@ -502,7 +502,7 @@ void PoolVector<T>::push_back(const T &p_val) { } template <class T> -const T PoolVector<T>::operator[](int p_index) const { +T PoolVector<T>::operator[](int p_index) const { CRASH_BAD_INDEX(p_index, size()); diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index e7ff7a3aef..5f01e043c4 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -357,10 +357,11 @@ void ScriptDebuggerRemote::_get_output() { locking = false; } - if (n_errors_dropped > 0) { + if (n_errors_dropped == 1) { + // Only print one message about dropping per second OutputError oe; oe.error = "TOO_MANY_ERRORS"; - oe.error_descr = "Too many errors! " + String::num_int64(n_errors_dropped) + " errors were dropped."; + oe.error_descr = "Too many errors! Ignoring errors for up to 1 second."; oe.warning = false; uint64_t time = OS::get_singleton()->get_ticks_msec(); oe.hr = time / 3600000; @@ -368,7 +369,20 @@ void ScriptDebuggerRemote::_get_output() { oe.sec = (time / 1000) % 60; oe.msec = time % 1000; errors.push_back(oe); - n_errors_dropped = 0; + } + + if (n_warnings_dropped == 1) { + // Only print one message about dropping per second + OutputError oe; + oe.error = "TOO_MANY_WARNINGS"; + oe.error_descr = "Too many warnings! Ignoring warnings for up to 1 second."; + oe.warning = true; + uint64_t time = OS::get_singleton()->get_ticks_msec(); + oe.hr = time / 3600000; + oe.min = (time / 60000) % 60; + oe.sec = (time / 1000) % 60; + oe.msec = time % 1000; + errors.push_back(oe); } while (errors.size()) { @@ -934,6 +948,19 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file oe.msec = time % 1000; Array cstack; + uint64_t ticks = OS::get_singleton()->get_ticks_usec() / 1000; + msec_count += ticks - last_msec; + last_msec = ticks; + + if (msec_count > 1000) { + msec_count = 0; + + err_count = 0; + n_errors_dropped = 0; + warn_count = 0; + n_warnings_dropped = 0; + } + cstack.resize(p_stack_info.size() * 3); for (int i = 0; i < p_stack_info.size(); i++) { cstack[i * 3 + 0] = p_stack_info[i].file; @@ -942,15 +969,28 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file } oe.callstack = cstack; + if (oe.warning) { + warn_count++; + } else { + err_count++; + } mutex->lock(); if (!locking && tcp_client->is_connected_to_host()) { - if (errors.size() >= max_errors_per_frame) { - n_errors_dropped++; + if (oe.warning) { + if (warn_count > max_warnings_per_second) { + n_warnings_dropped++; + } else { + errors.push_back(oe); + } } else { - errors.push_back(oe); + if (err_count > max_errors_per_second) { + n_errors_dropped++; + } else { + errors.push_back(oe); + } } } @@ -1070,10 +1110,13 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() : mutex(Mutex::create()), max_messages_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_messages_per_frame")), n_messages_dropped(0), - max_errors_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_frame")), + max_errors_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_second")), + max_warnings_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_warnings_per_second")), n_errors_dropped(0), max_cps(GLOBAL_GET("network/limits/debugger_stdout/max_chars_per_second")), char_count(0), + err_count(0), + warn_count(0), last_msec(0), msec_count(0), locking(false), diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h index 1fc9d7c7f1..a5bfd7a32d 100644 --- a/core/script_debugger_remote.h +++ b/core/script_debugger_remote.h @@ -91,11 +91,15 @@ class ScriptDebuggerRemote : public ScriptDebugger { int max_messages_per_frame; int n_messages_dropped; List<OutputError> errors; - int max_errors_per_frame; + int max_errors_per_second; + int max_warnings_per_second; int n_errors_dropped; + int n_warnings_dropped; int max_cps; int char_count; + int err_count; + int warn_count; uint64_t last_msec; uint64_t msec_count; diff --git a/core/set.h b/core/set.h index 81250068af..b2c717880d 100644 --- a/core/set.h +++ b/core/set.h @@ -39,7 +39,7 @@ */ // based on the very nice implementation of rb-trees by: -// http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html +// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html template <class T, class C = Comparator<T>, class A = DefaultAllocator> class Set { diff --git a/core/string_name.cpp b/core/string_name.cpp index 10b71ad3ac..b1a8bfb849 100644 --- a/core/string_name.cpp +++ b/core/string_name.cpp @@ -205,7 +205,6 @@ StringName::StringName(const char *p_name) { // exists lock->unlock(); return; - } else { } } @@ -253,7 +252,6 @@ StringName::StringName(const StaticCString &p_static_string) { // exists lock->unlock(); return; - } else { } } @@ -301,7 +299,6 @@ StringName::StringName(const String &p_name) { // exists lock->unlock(); return; - } else { } } diff --git a/core/type_info.h b/core/type_info.h index d85a63ee42..61ec7b2f20 100644 --- a/core/type_info.h +++ b/core/type_info.h @@ -83,15 +83,13 @@ enum Metadata { }; } +// If the compiler fails because it's trying to instantiate the primary 'GetTypeInfo' template +// instead of one of the specializations, it's most likely because the type 'T' is not supported. +// If 'T' is a class that inherits 'Object', make sure it can see the actual class declaration +// instead of a forward declaration. You can always forward declare 'T' in a header file, and then +// include the actual declaration of 'T' in the source file where 'GetTypeInfo<T>' is instantiated. template <class T, typename = void> -struct GetTypeInfo { - static const Variant::Type VARIANT_TYPE = Variant::NIL; - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; - static inline PropertyInfo get_class_info() { - ERR_PRINT("GetTypeInfo fallback. Bug!"); - return PropertyInfo(); // Not "Nil", this is an error - } -}; +struct GetTypeInfo; #define MAKE_TYPE_INFO(m_type, m_var_type) \ template <> \ @@ -283,10 +281,7 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) { return GetTypeInfo<T>::get_class_info().class_name; } -#define CLASS_INFO(m_type) \ - (GetTypeInfo<m_type *>::VARIANT_TYPE != Variant::NIL ? \ - GetTypeInfo<m_type *>::get_class_info() : \ - GetTypeInfo<m_type>::get_class_info()) +#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info()) #else diff --git a/core/ustring.cpp b/core/ustring.cpp index 75e3b6f22e..ed401c3763 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -2729,6 +2729,51 @@ bool String::is_quoted() const { return is_enclosed_in("\"") || is_enclosed_in("'"); } +int String::_count(const String &p_string, int p_from, int p_to, bool p_case_insensitive) const { + if (p_string.empty()) { + return 0; + } + int len = length(); + int slen = p_string.length(); + if (len < slen) { + return 0; + } + String str; + if (p_from >= 0 && p_to >= 0) { + if (p_to == 0) { + p_to = len; + } else if (p_from >= p_to) { + return 0; + } + if (p_from == 0 && p_to == len) { + str = String(); + str.copy_from_unchecked(&c_str()[0], len); + } else { + str = substr(p_from, p_to - p_from); + } + } else { + return 0; + } + int c = 0; + int idx = -1; + do { + idx = p_case_insensitive ? str.findn(p_string) : str.find(p_string); + if (idx != -1) { + str = str.substr(idx + slen, str.length() - slen); + ++c; + } + } while (idx != -1); + return c; +} + +int String::count(const String &p_string, int p_from, int p_to) const { + return _count(p_string, p_from, p_to, false); +} + +int String::countn(const String &p_string, int p_from, int p_to) const { + return _count(p_string, p_from, p_to, true); +} + bool String::_base_is_subsequence_of(const String &p_string, bool case_insensitive) const { int len = length(); diff --git a/core/ustring.h b/core/ustring.h index 8a52c53238..3eb5c47b3a 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -137,6 +137,7 @@ class String { void copy_from(const CharType &p_char); void copy_from_unchecked(const CharType *p_char, const int p_length); bool _base_is_subsequence_of(const String &p_string, bool case_insensitive) const; + int _count(const String &p_string, int p_from, int p_to, bool p_case_insensitive) const; public: enum { @@ -279,6 +280,9 @@ public: String to_upper() const; String to_lower() const; + int count(const String &p_string, int p_from = 0, int p_to = 0) const; + int countn(const String &p_string, int p_from = 0, int p_to = 0) const; + String left(int p_pos) const; String right(int p_pos) const; String dedent() const; diff --git a/core/variant.cpp b/core/variant.cpp index fe9623d068..1574af5239 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -1834,8 +1834,6 @@ inline DA _convert_array_from_variant(const Variant &p_variant) { return DA(); } } - - return DA(); } Variant::operator Array() const { @@ -2299,7 +2297,7 @@ Variant::Variant(const Object *p_object) { Variant::Variant(const Dictionary &p_dictionary) { type = DICTIONARY; - memnew_placement(_data._mem, (Dictionary)(p_dictionary)); + memnew_placement(_data._mem, Dictionary(p_dictionary)); } Variant::Variant(const Array &p_array) { diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 3fdd18a630..1f6e5bb653 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -70,7 +70,7 @@ struct _VariantCall { for (int i = 0; i < arg_count; i++) { - if (!tptr[i] || tptr[i] == p_args[i]->type) + if (tptr[i] == Variant::NIL || tptr[i] == p_args[i]->type) continue; // all good if (!Variant::can_convert(p_args[i]->type, tptr[i])) { r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; @@ -237,6 +237,8 @@ struct _VariantCall { VCALL_LOCALMEM1R(String, casecmp_to); VCALL_LOCALMEM1R(String, nocasecmp_to); VCALL_LOCALMEM0R(String, length); + VCALL_LOCALMEM3R(String, count); + VCALL_LOCALMEM3R(String, countn); VCALL_LOCALMEM2R(String, substr); VCALL_LOCALMEM2R(String, find); VCALL_LOCALMEM1R(String, find_last); @@ -912,7 +914,7 @@ struct _VariantCall { static void Quat_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Quat(((Vector3)(*p_args[0])), ((float)(*p_args[1]))); + r_ret = Quat(((Vector3)(*p_args[0])), ((real_t)(*p_args[1]))); } static void Quat_init3(Variant &r_ret, const Variant **p_args) { @@ -1502,6 +1504,9 @@ void register_variant_methods() { ADDFUNC2R(STRING, INT, String, find, STRING, "what", INT, "from", varray(0)); + ADDFUNC3R(STRING, INT, String, count, STRING, "what", INT, "from", INT, "to", varray(0, 0)); + ADDFUNC3R(STRING, INT, String, countn, STRING, "what", INT, "from", INT, "to", varray(0, 0)); + ADDFUNC1R(STRING, INT, String, find_last, STRING, "what", varray()); ADDFUNC2R(STRING, INT, String, findn, STRING, "what", INT, "from", varray(0)); ADDFUNC2R(STRING, INT, String, rfind, STRING, "what", INT, "from", varray(-1)); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index d677c7776a..ea9e29e744 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -2613,7 +2613,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const { if (r_valid) { *r_valid = false; } - return "Attempted get on stray pointer."; + return true; // Attempted get on stray pointer. } } #endif diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index d5513bc2d7..07212ec669 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -1537,8 +1537,6 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r Token token; get_token(p_stream, token, line, r_err_str); Error err = parse_value(token, r_value, p_stream, line, r_err_str, p_res_parser); - if (err) { - } return err; } } else if (c == '\n') { |