diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/main/canvas_item.cpp | 35 | ||||
-rw-r--r-- | scene/main/canvas_item.h | 4 | ||||
-rw-r--r-- | scene/main/canvas_layer.cpp | 2 | ||||
-rw-r--r-- | scene/multiplayer/scene_cache_interface.cpp | 122 | ||||
-rw-r--r-- | scene/multiplayer/scene_cache_interface.h | 2 | ||||
-rw-r--r-- | scene/multiplayer/scene_replication_interface.cpp | 3 | ||||
-rw-r--r-- | scene/resources/tile_set.cpp | 4 |
7 files changed, 96 insertions, 76 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 9ad711c596..26b67b763c 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -56,19 +56,21 @@ Transform2D CanvasItem::_edit_get_transform() const { #endif bool CanvasItem::is_visible_in_tree() const { - return visible && visible_in_tree; + return visible && parent_visible_in_tree; } -void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_was_visible) { - if (p_visible && first_draw) { //avoid propagating it twice +void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_is_source) { + if (p_visible && first_draw) { // Avoid propagating it twice. first_draw = false; } - visible_in_tree = p_visible; + if (!p_is_source) { + parent_visible_in_tree = p_visible; + } notification(NOTIFICATION_VISIBILITY_CHANGED); if (visible && p_visible) { update(); - } else if (!p_visible && (visible || p_was_visible)) { + } else if (!p_visible && (visible || p_is_source)) { emit_signal(SceneStringNames::get_singleton()->hidden); } _block(); @@ -76,8 +78,12 @@ void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_was_visibl for (int i = 0; i < get_child_count(); i++) { CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i)); - if (c && c->visible) { //should the top_levels stop propagation? i think so but.. - c->_propagate_visibility_changed(p_visible); + if (c) { // Should the top_levels stop propagation? I think so, but... + if (c->visible) { + c->_propagate_visibility_changed(p_visible); + } else { + c->parent_visible_in_tree = p_visible; + } } } @@ -92,11 +98,12 @@ void CanvasItem::set_visible(bool p_visible) { visible = p_visible; RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, p_visible); - if (!is_inside_tree()) { + if (!parent_visible_in_tree) { + notification(NOTIFICATION_VISIBILITY_CHANGED); return; } - _propagate_visibility_changed(p_visible, !p_visible); + _propagate_visibility_changed(p_visible, true); } void CanvasItem::show() { @@ -264,13 +271,13 @@ void CanvasItem::_notification(int p_what) { CanvasItem *ci = Object::cast_to<CanvasItem>(parent); if (ci) { - visible_in_tree = ci->is_visible_in_tree(); + parent_visible_in_tree = ci->is_visible_in_tree(); C = ci->children_items.push_back(this); } else { CanvasLayer *cl = Object::cast_to<CanvasLayer>(parent); if (cl) { - visible_in_tree = cl->is_visible(); + parent_visible_in_tree = cl->is_visible(); } else { // Look for a window. Viewport *viewport = nullptr; @@ -288,9 +295,9 @@ void CanvasItem::_notification(int p_what) { window = Object::cast_to<Window>(viewport); if (window) { window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); - visible_in_tree = window->is_visible(); + parent_visible_in_tree = window->is_visible(); } else { - visible_in_tree = true; + parent_visible_in_tree = true; } } } @@ -333,7 +340,7 @@ void CanvasItem::_notification(int p_what) { window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); } global_invalid = true; - visible_in_tree = false; + parent_visible_in_tree = false; } break; case NOTIFICATION_VISIBILITY_CHANGED: { diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 2a9e7bac3d..c0558b6be2 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -85,7 +85,7 @@ private: Window *window = nullptr; bool first_draw = false; bool visible = true; - bool visible_in_tree = false; + bool parent_visible_in_tree = false; bool clip_children = false; bool pending_update = false; bool top_level = false; @@ -108,7 +108,7 @@ private: void _top_level_raise_self(); - void _propagate_visibility_changed(bool p_visible, bool p_was_visible = false); + void _propagate_visibility_changed(bool p_visible, bool p_is_source = false); void _update_callback(); diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 6c627857fa..be24620904 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -61,7 +61,7 @@ void CanvasLayer::set_visible(bool p_visible) { if (c->is_visible()) { c->_propagate_visibility_changed(p_visible); } else { - c->notification(CanvasItem::NOTIFICATION_VISIBILITY_CHANGED); + c->parent_visible_in_tree = p_visible; } } } diff --git a/scene/multiplayer/scene_cache_interface.cpp b/scene/multiplayer/scene_cache_interface.cpp index 2f278ed864..f05dc5a2da 100644 --- a/scene/multiplayer/scene_cache_interface.cpp +++ b/scene/multiplayer/scene_cache_interface.cpp @@ -139,74 +139,46 @@ void SceneCacheInterface::process_confirm_path(int p_from, const uint8_t *p_pack E->get() = true; } -bool SceneCacheInterface::_send_confirm_path(Node *p_node, NodePath p_path, PathSentCache *psc, int p_target) { - bool has_all_peers = true; - List<int> peers_to_add; // If one is missing, take note to add it. - - for (const Set<int>::Element *E = multiplayer->get_connected_peers().front(); E; E = E->next()) { - if (p_target < 0 && E->get() == -p_target) { - continue; // Continue, excluded. - } - - if (p_target > 0 && E->get() != p_target) { - continue; // Continue, not for this peer. - } - - Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get()); - - if (!F || !F->get()) { - // Path was not cached, or was cached but is unconfirmed. - if (!F) { - // Not cached at all, take note. - peers_to_add.push_back(E->get()); - } +Error SceneCacheInterface::_send_confirm_path(Node *p_node, NodePath p_path, PathSentCache *psc, const List<int> &p_peers) { + // Encode function name. + const CharString path = String(p_path).utf8(); + const int path_len = encode_cstring(path.get_data(), nullptr); - has_all_peers = false; - } - } - - if (peers_to_add.size() > 0) { - // Those that need to be added, send a message for this. - - // Encode function name. - const CharString path = String(p_path).utf8(); - const int path_len = encode_cstring(path.get_data(), nullptr); + // Extract MD5 from rpc methods list. + const String methods_md5 = multiplayer->get_rpc_md5(p_node); + const int methods_md5_len = 33; // 32 + 1 for the `0` that is added by the encoder. - // Extract MD5 from rpc methods list. - const String methods_md5 = multiplayer->get_rpc_md5(p_node); - const int methods_md5_len = 33; // 32 + 1 for the `0` that is added by the encoder. - - Vector<uint8_t> packet; - packet.resize(1 + 4 + path_len + methods_md5_len); - int ofs = 0; + Vector<uint8_t> packet; + packet.resize(1 + 4 + path_len + methods_md5_len); + int ofs = 0; - packet.write[ofs] = MultiplayerAPI::NETWORK_COMMAND_SIMPLIFY_PATH; - ofs += 1; + packet.write[ofs] = MultiplayerAPI::NETWORK_COMMAND_SIMPLIFY_PATH; + ofs += 1; - ofs += encode_cstring(methods_md5.utf8().get_data(), &packet.write[ofs]); + ofs += encode_cstring(methods_md5.utf8().get_data(), &packet.write[ofs]); - ofs += encode_uint32(psc->id, &packet.write[ofs]); + ofs += encode_uint32(psc->id, &packet.write[ofs]); - ofs += encode_cstring(path.get_data(), &packet.write[ofs]); + ofs += encode_cstring(path.get_data(), &packet.write[ofs]); - Ref<MultiplayerPeer> multiplayer_peer = multiplayer->get_multiplayer_peer(); - ERR_FAIL_COND_V(multiplayer_peer.is_null(), false); + Ref<MultiplayerPeer> multiplayer_peer = multiplayer->get_multiplayer_peer(); + ERR_FAIL_COND_V(multiplayer_peer.is_null(), ERR_BUG); #ifdef DEBUG_ENABLED - multiplayer->profile_bandwidth("out", packet.size() * peers_to_add.size()); + multiplayer->profile_bandwidth("out", packet.size() * p_peers.size()); #endif - for (int &E : peers_to_add) { - multiplayer_peer->set_target_peer(E); // To all of you. - multiplayer_peer->set_transfer_channel(0); - multiplayer_peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_RELIABLE); - multiplayer_peer->put_packet(packet.ptr(), packet.size()); - - psc->confirmed_peers.insert(E, false); // Insert into confirmed, but as false since it was not confirmed. - } + Error err = OK; + for (int peer_id : p_peers) { + multiplayer_peer->set_target_peer(peer_id); + multiplayer_peer->set_transfer_channel(0); + multiplayer_peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_RELIABLE); + err = multiplayer_peer->put_packet(packet.ptr(), packet.size()); + ERR_FAIL_COND_V(err != OK, err); + // Insert into confirmed, but as false since it was not confirmed. + psc->confirmed_peers.insert(peer_id, false); } - - return has_all_peers; + return err; } bool SceneCacheInterface::is_cache_confirmed(NodePath p_path, int p_peer) { @@ -230,7 +202,43 @@ bool SceneCacheInterface::send_object_cache(Object *p_obj, NodePath p_path, int } r_id = psc->id; - return _send_confirm_path(node, p_path, psc, p_peer_id); + bool has_all_peers = true; + List<int> peers_to_add; // If one is missing, take note to add it. + + if (p_peer_id > 0) { + // Fast single peer check. + Map<int, bool>::Element *F = psc->confirmed_peers.find(p_peer_id); + if (!F) { + peers_to_add.push_back(p_peer_id); // Need to also be notified. + has_all_peers = false; + } else if (!F->get()) { + has_all_peers = false; + } + } else { + // Long and painful. + for (const Set<int>::Element *E = multiplayer->get_connected_peers().front(); E; E = E->next()) { + if (p_peer_id < 0 && E->get() == -p_peer_id) { + continue; // Continue, excluded. + } + if (p_peer_id > 0 && E->get() != p_peer_id) { + continue; // Continue, not for this peer. + } + + Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get()); + if (!F) { + peers_to_add.push_back(E->get()); // Need to also be notified. + has_all_peers = false; + } else if (!F->get()) { + has_all_peers = false; + } + } + } + + if (peers_to_add.size()) { + _send_confirm_path(node, p_path, psc, peers_to_add); + } + + return has_all_peers; } Object *SceneCacheInterface::get_cached_object(int p_from, uint32_t p_cache_id) { diff --git a/scene/multiplayer/scene_cache_interface.h b/scene/multiplayer/scene_cache_interface.h index 91a53cb948..c709d26b51 100644 --- a/scene/multiplayer/scene_cache_interface.h +++ b/scene/multiplayer/scene_cache_interface.h @@ -60,7 +60,7 @@ private: int last_send_cache_id = 1; protected: - bool _send_confirm_path(Node *p_node, NodePath p_path, PathSentCache *psc, int p_target); + Error _send_confirm_path(Node *p_node, NodePath p_path, PathSentCache *psc, const List<int> &p_peers); static MultiplayerCacheInterface *_create(MultiplayerAPI *p_multiplayer); public: diff --git a/scene/multiplayer/scene_replication_interface.cpp b/scene/multiplayer/scene_replication_interface.cpp index 25a704b37e..0764f136e4 100644 --- a/scene/multiplayer/scene_replication_interface.cpp +++ b/scene/multiplayer/scene_replication_interface.cpp @@ -350,11 +350,12 @@ void SceneReplicationInterface::_send_sync(int p_peer, uint64_t p_msec) { } if (size) { uint32_t net_id = rep_state->get_net_id(oid); - if (net_id == 0) { + if (net_id == 0 || (net_id & 0x80000000)) { // First time path based ID. NodePath rel_path = multiplayer->get_root_path().rel_path_to(sync->get_path()); int path_id = 0; multiplayer->send_object_cache(sync, rel_path, p_peer, path_id); + ERR_CONTINUE_MSG(net_id && net_id != (uint32_t(path_id) | 0x80000000), "This should never happen!"); net_id = path_id; rep_state->set_net_id(oid, net_id | 0x80000000); } diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 1e84947b87..1174117028 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -4432,6 +4432,10 @@ void TileSetAtlasSource::_update_padded_texture() { Ref<Image> src = texture->get_image(); + if (!src.is_valid()) { + return; + } + Ref<Image> image; image.instantiate(); image->create(size.x, size.y, false, src->get_format()); |