diff options
Diffstat (limited to 'scene/main')
-rw-r--r-- | scene/main/http_request.cpp | 49 | ||||
-rw-r--r-- | scene/main/multiplayer_api.cpp | 2 | ||||
-rw-r--r-- | scene/main/node.cpp | 22 | ||||
-rw-r--r-- | scene/main/node.h | 2 | ||||
-rw-r--r-- | scene/main/scene_tree.cpp | 21 | ||||
-rw-r--r-- | scene/main/scene_tree.h | 2 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 89 | ||||
-rw-r--r-- | scene/main/viewport.h | 1 | ||||
-rw-r--r-- | scene/main/window.cpp | 2 |
9 files changed, 112 insertions, 78 deletions
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 2c395ec07d..62f362553f 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -276,10 +276,10 @@ bool HTTPRequest::_handle_response(bool *ret_value) { } if (content_encoding == "gzip") { decompressor.instantiate(); - decompressor->start_decompression(false, get_download_chunk_size() * 2); + decompressor->start_decompression(false, get_download_chunk_size()); } else if (content_encoding == "deflate") { decompressor.instantiate(); - decompressor->start_decompression(true, get_download_chunk_size() * 2); + decompressor->start_decompression(true, get_download_chunk_size()); } return false; @@ -390,19 +390,38 @@ bool HTTPRequest::_update_connection() { return false; } - PackedByteArray chunk = client->read_response_body_chunk(); - downloaded.add(chunk.size()); - - // Decompress chunk if needed. - if (decompressor.is_valid()) { - Error err = decompressor->put_data(chunk.ptr(), chunk.size()); - if (err == OK) { - chunk.resize(decompressor->get_available_bytes()); - err = decompressor->get_data(chunk.ptrw(), chunk.size()); - } - if (err != OK) { - _defer_done(RESULT_BODY_DECOMPRESS_FAILED, response_code, response_headers, PackedByteArray()); - return true; + PackedByteArray chunk; + if (decompressor.is_null()) { + // Chunk can be read directly. + chunk = client->read_response_body_chunk(); + downloaded.add(chunk.size()); + } else { + // Chunk is the result of decompression. + PackedByteArray compressed = client->read_response_body_chunk(); + downloaded.add(compressed.size()); + + int pos = 0; + int left = compressed.size(); + while (left) { + int w = 0; + Error err = decompressor->put_partial_data(compressed.ptr() + pos, left, w); + if (err == OK) { + PackedByteArray dc; + dc.resize(decompressor->get_available_bytes()); + err = decompressor->get_data(dc.ptrw(), dc.size()); + chunk.append_array(dc); + } + if (err != OK) { + _defer_done(RESULT_BODY_DECOMPRESS_FAILED, response_code, response_headers, PackedByteArray()); + return true; + } + // We need this check here because a "zip bomb" could result in a chunk of few kilos decompressing into gigabytes of data. + if (body_size_limit >= 0 && final_body_size.get() + chunk.size() > body_size_limit) { + _defer_done(RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PackedByteArray()); + return true; + } + pos += w; + left -= w; } } final_body_size.add(chunk.size()); diff --git a/scene/main/multiplayer_api.cpp b/scene/main/multiplayer_api.cpp index 946929aa89..8b4b98c172 100644 --- a/scene/main/multiplayer_api.cpp +++ b/scene/main/multiplayer_api.cpp @@ -39,7 +39,7 @@ #include "core/os/os.h" #endif -StringName MultiplayerAPI::default_interface = StringName(); +StringName MultiplayerAPI::default_interface; void MultiplayerAPI::set_default_interface(const StringName &p_interface) { ERR_FAIL_COND_MSG(!ClassDB::is_parent_class(p_interface, MultiplayerAPI::get_class_static()), vformat("Can't make %s the default multiplayer interface since it does not extend MultiplayerAPI.", p_interface)); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 304504a82e..f88fdb3ac1 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1759,11 +1759,11 @@ void Node::add_to_group(const StringName &p_identifier, bool p_persistent) { } void Node::remove_from_group(const StringName &p_identifier) { - ERR_FAIL_COND(!data.grouped.has(p_identifier)); - HashMap<StringName, GroupData>::Iterator E = data.grouped.find(p_identifier); - ERR_FAIL_COND(!E); + if (!E) { + return; + } if (data.tree) { data.tree->remove_from_group(E->key, this); @@ -2060,7 +2060,7 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c nip->set_instance_path(ip->get_instance_path()); node = nip; - } else if ((p_flags & DUPLICATE_USE_INSTANCING) && !get_scene_file_path().is_empty()) { + } else if ((p_flags & DUPLICATE_USE_INSTANTIATION) && !get_scene_file_path().is_empty()) { Ref<PackedScene> res = ResourceLoader::load(get_scene_file_path()); ERR_FAIL_COND_V(res.is_null(), nullptr); PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED; @@ -2246,7 +2246,7 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap) con } Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const { - Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANCING | DUPLICATE_FROM_EDITOR, &r_duplimap); + Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR, &r_duplimap); // This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated. if (!p_resource_remap.is_empty()) { @@ -2581,10 +2581,14 @@ void Node::print_orphan_nodes() { } void Node::queue_free() { + // There are users which instantiate multiple scene trees for their games. + // Use the node's own tree to handle its deletion when relevant. if (is_inside_tree()) { get_tree()->queue_delete(this); } else { - SceneTree::get_singleton()->queue_delete(this); + SceneTree *tree = SceneTree::get_singleton(); + ERR_FAIL_NULL_MSG(tree, "Can't queue free a node when no SceneTree is available."); + tree->queue_delete(this); } } @@ -2652,7 +2656,7 @@ PackedStringArray Node::get_configuration_warnings() const { String Node::get_configuration_warnings_as_string() const { PackedStringArray warnings = get_configuration_warnings(); - String all_warnings = String(); + String all_warnings; for (int i = 0; i < warnings.size(); i++) { if (i > 0) { all_warnings += "\n\n"; @@ -2812,7 +2816,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tree"), &Node::get_tree); ClassDB::bind_method(D_METHOD("create_tween"), &Node::create_tween); - ClassDB::bind_method(D_METHOD("duplicate", "flags"), &Node::duplicate, DEFVAL(DUPLICATE_USE_INSTANCING | DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS)); + ClassDB::bind_method(D_METHOD("duplicate", "flags"), &Node::duplicate, DEFVAL(DUPLICATE_USE_INSTANTIATION | DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS)); ClassDB::bind_method(D_METHOD("replace_by", "node", "keep_groups"), &Node::replace_by, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_scene_instance_load_placeholder", "load_placeholder"), &Node::set_scene_instance_load_placeholder); @@ -2918,7 +2922,7 @@ void Node::_bind_methods() { BIND_ENUM_CONSTANT(DUPLICATE_SIGNALS); BIND_ENUM_CONSTANT(DUPLICATE_GROUPS); BIND_ENUM_CONSTANT(DUPLICATE_SCRIPTS); - BIND_ENUM_CONSTANT(DUPLICATE_USE_INSTANCING); + BIND_ENUM_CONSTANT(DUPLICATE_USE_INSTANTIATION); BIND_ENUM_CONSTANT(INTERNAL_MODE_DISABLED); BIND_ENUM_CONSTANT(INTERNAL_MODE_FRONT); diff --git a/scene/main/node.h b/scene/main/node.h index 4a3ec253b1..5e51ec6b0e 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -57,7 +57,7 @@ public: DUPLICATE_SIGNALS = 1, DUPLICATE_GROUPS = 2, DUPLICATE_SCRIPTS = 4, - DUPLICATE_USE_INSTANCING = 8, + DUPLICATE_USE_INSTANTIATION = 8, #ifdef TOOLS_ENABLED DUPLICATE_FROM_EDITOR = 16, #endif diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 41eefe0f85..81a4e3073b 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -123,6 +123,9 @@ void SceneTree::tree_changed() { void SceneTree::node_added(Node *p_node) { emit_signal(node_added_name, p_node); + if (call_lock > 0) { + call_skip.erase(p_node->get_instance_id()); + } } void SceneTree::node_removed(Node *p_node) { @@ -131,7 +134,7 @@ void SceneTree::node_removed(Node *p_node) { } emit_signal(node_removed_name, p_node); if (call_lock > 0) { - call_skip.insert(p_node); + call_skip.insert(p_node->get_instance_id()); } } @@ -261,7 +264,7 @@ void SceneTree::call_group_flagsp(uint32_t p_call_flags, const StringName &p_gro if (p_call_flags & GROUP_CALL_REVERSE) { for (int i = gr_node_count - 1; i >= 0; i--) { - if (call_lock && call_skip.has(gr_nodes[i])) { + if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) { continue; } @@ -275,7 +278,7 @@ void SceneTree::call_group_flagsp(uint32_t p_call_flags, const StringName &p_gro } else { for (int i = 0; i < gr_node_count; i++) { - if (call_lock && call_skip.has(gr_nodes[i])) { + if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) { continue; } @@ -314,7 +317,7 @@ void SceneTree::notify_group_flags(uint32_t p_call_flags, const StringName &p_gr if (p_call_flags & GROUP_CALL_REVERSE) { for (int i = gr_node_count - 1; i >= 0; i--) { - if (call_lock && call_skip.has(gr_nodes[i])) { + if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) { continue; } @@ -327,7 +330,7 @@ void SceneTree::notify_group_flags(uint32_t p_call_flags, const StringName &p_gr } else { for (int i = 0; i < gr_node_count; i++) { - if (call_lock && call_skip.has(gr_nodes[i])) { + if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) { continue; } @@ -365,7 +368,7 @@ void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group if (p_call_flags & GROUP_CALL_REVERSE) { for (int i = gr_node_count - 1; i >= 0; i--) { - if (call_lock && call_skip.has(gr_nodes[i])) { + if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) { continue; } @@ -378,7 +381,7 @@ void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group } else { for (int i = 0; i < gr_node_count; i++) { - if (call_lock && call_skip.has(gr_nodes[i])) { + if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) { continue; } @@ -854,7 +857,7 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio for (int i = 0; i < gr_node_count; i++) { Node *n = gr_nodes[i]; - if (call_lock && call_skip.has(n)) { + if (call_lock && call_skip.has(n->get_instance_id())) { continue; } @@ -904,7 +907,7 @@ void SceneTree::_call_input_pause(const StringName &p_group, CallInputType p_cal } Node *n = gr_nodes[i]; - if (call_lock && call_skip.has(n)) { + if (call_lock && call_skip.has(n->get_instance_id())) { continue; } diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index a460e40597..d4fcb288ae 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -135,7 +135,7 @@ private: // Safety for when a node is deleted while a group is being called. int call_lock = 0; - HashSet<Node *> call_skip; // Skip erased nodes. + HashSet<ObjectID> call_skip; // Skip erased nodes. Store ID instead of pointer to avoid false positives when node is freed and a new node is allocated at the pointed address. List<ObjectID> delete_queue; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index f8b0a66a71..345d5de937 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -362,6 +362,7 @@ void Viewport::_notification(int p_what) { current_canvas = find_world_2d()->get_canvas(); RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas); + RenderingServer::get_singleton()->viewport_set_canvas_transform(viewport, current_canvas, canvas_transform); RenderingServer::get_singleton()->viewport_set_canvas_cull_mask(viewport, canvas_cull_mask); _update_audio_listener_2d(); #ifndef _3D_DISABLED @@ -1561,44 +1562,15 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { set_input_as_handled(); } - if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MouseButton::LEFT) { + if (gui.dragging && mb->get_button_index() == MouseButton::LEFT) { // Alternate drop use (when using force_drag(), as proposed by #5342). - gui.drag_successful = false; - if (gui.mouse_focus) { - gui.drag_successful = _gui_drop(gui.mouse_focus, pos, false); - } - - gui.drag_data = Variant(); - gui.dragging = false; - - Control *drag_preview = _gui_get_drag_preview(); - if (drag_preview) { - memdelete(drag_preview); - gui.drag_preview_id = ObjectID(); - } - _propagate_viewport_notification(this, NOTIFICATION_DRAG_END); - get_base_window()->update_mouse_cursor_shape(); + _perform_drop(gui.mouse_focus, pos); } _gui_cancel_tooltip(); } else { - if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MouseButton::LEFT) { - gui.drag_successful = false; - if (gui.drag_mouse_over) { - gui.drag_successful = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, false); - } - - Control *drag_preview = _gui_get_drag_preview(); - if (drag_preview) { - memdelete(drag_preview); - gui.drag_preview_id = ObjectID(); - } - - gui.drag_data = Variant(); - gui.dragging = false; - gui.drag_mouse_over = nullptr; - _propagate_viewport_notification(this, NOTIFICATION_DRAG_END); - get_base_window()->update_mouse_cursor_shape(); + if (gui.dragging && mb->get_button_index() == MouseButton::LEFT) { + _perform_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos); } gui.mouse_focus_mask &= ~mouse_button_to_mask(mb->get_button_index()); // Remove from mask. @@ -1652,7 +1624,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Control *control = Object::cast_to<Control>(ci); if (control) { gui.dragging = true; - gui.drag_data = control->get_drag_data(control->get_global_transform_with_canvas().affine_inverse().xform(mpos) - gui.drag_accum); + gui.drag_data = control->get_drag_data(control->get_global_transform_with_canvas().affine_inverse().xform(mpos - gui.drag_accum)); if (gui.drag_data.get_type() != Variant::NIL) { gui.mouse_focus = nullptr; gui.forced_mouse_focus = false; @@ -1682,7 +1654,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } gui.drag_attempted = true; - if (gui.drag_data.get_type() != Variant::NIL) { + if (gui.dragging) { _propagate_viewport_notification(this, NOTIFICATION_DRAG_BEGIN); } } @@ -1698,6 +1670,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { _gui_cancel_tooltip(); if (over) { + if (!gui.mouse_over) { + _drop_physics_mouseover(); + } _gui_call_notification(over, Control::NOTIFICATION_MOUSE_ENTER); gui.mouse_over = over; } @@ -1795,7 +1770,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } - if (gui.drag_data.get_type() != Variant::NIL) { + if (gui.dragging) { // Handle drag & drop. Control *drag_preview = _gui_get_drag_preview(); @@ -1997,6 +1972,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } if (mm.is_null() && mb.is_null() && p_event->is_action_type()) { + if (gui.dragging && p_event->is_action_pressed("ui_cancel") && Input::get_singleton()->is_action_just_pressed("ui_cancel")) { + _perform_drop(); + set_input_as_handled(); + return; + } + if (gui.key_focus && !gui.key_focus->is_visible_in_tree()) { gui.key_focus->release_focus(); } @@ -2078,6 +2059,27 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } +void Viewport::_perform_drop(Control *p_control, Point2 p_pos) { + // Without any arguments, simply cancel Drag and Drop. + if (p_control) { + gui.drag_successful = _gui_drop(p_control, p_pos, false); + } else { + gui.drag_successful = false; + } + + Control *drag_preview = _gui_get_drag_preview(); + if (drag_preview) { + memdelete(drag_preview); + gui.drag_preview_id = ObjectID(); + } + + gui.drag_data = Variant(); + gui.dragging = false; + gui.drag_mouse_over = nullptr; + _propagate_viewport_notification(this, NOTIFICATION_DRAG_END); + get_base_window()->update_mouse_cursor_shape(); +} + void Viewport::_gui_cleanup_internal_state(Ref<InputEvent> p_event) { ERR_FAIL_COND(p_event.is_null()); @@ -2662,6 +2664,11 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) { } else { gui.subwindow_resize_mode = _sub_window_get_resize_margin(sw.window, mb->get_position()); if (gui.subwindow_resize_mode != SUB_WINDOW_RESIZE_DISABLED) { + if (gui.subwindow_focused != sw.window) { + // Refocus. + _sub_window_grab_focus(sw.window); + } + gui.subwindow_resize_from_rect = r; gui.subwindow_drag_from = mb->get_position(); gui.subwindow_drag = SUB_WINDOW_DRAG_RESIZE; @@ -3041,8 +3048,6 @@ bool Viewport::gui_is_drag_successful() const { } void Viewport::set_input_as_handled() { - _drop_physics_mouseover(); - if (!handle_input_locally) { ERR_FAIL_COND(!is_inside_tree()); Viewport *vp = this; @@ -4161,7 +4166,7 @@ DisplayServer::WindowID SubViewport::get_window_id() const { } Transform2D SubViewport::_stretch_transform() { - Transform2D transform = Transform2D(); + Transform2D transform; Size2i view_size_2d_override = _get_size_2d_override(); if (size_2d_override_stretch && view_size_2d_override.width > 0 && view_size_2d_override.height > 0) { Size2 scale = Size2(_get_size()) / Size2(view_size_2d_override); @@ -4172,7 +4177,7 @@ Transform2D SubViewport::_stretch_transform() { } Transform2D SubViewport::get_screen_transform() const { - Transform2D container_transform = Transform2D(); + Transform2D container_transform; SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent()); if (c) { if (c->is_stretch_enabled()) { @@ -4231,6 +4236,8 @@ void SubViewport::_bind_methods() { BIND_ENUM_CONSTANT(UPDATE_ALWAYS); } -SubViewport::SubViewport() {} +SubViewport::SubViewport() { + RS::get_singleton()->viewport_set_size(get_viewport_rid(), get_size().width, get_size().height); +} SubViewport::~SubViewport() {} diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 8911aea335..dc69ec24d8 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -405,6 +405,7 @@ private: Control *_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_global, const Transform2D &p_xform, Transform2D &r_inv_xform); void _gui_input_event(Ref<InputEvent> p_event); + void _perform_drop(Control *p_control = nullptr, Point2 p_pos = Point2()); void _gui_cleanup_internal_state(Ref<InputEvent> p_event); _FORCE_INLINE_ Transform2D _get_input_pre_xform() const; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index ebb11ecee8..aff2c594d9 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -1633,7 +1633,7 @@ void Window::_validate_property(PropertyInfo &p_property) const { } Transform2D Window::get_screen_transform() const { - Transform2D embedder_transform = Transform2D(); + Transform2D embedder_transform; if (_get_embedder()) { embedder_transform.translate_local(get_position()); embedder_transform = _get_embedder()->get_screen_transform() * embedder_transform; |