Skip to content

Commit 019cf2b

Browse files
committed
Merge pull request #94984 from Faless/mp/fix_safer_cache_cleanup
[MP] Partially revert cache cleanup, track paths as fallback
2 parents 8460a72 + 90d5d26 commit 019cf2b

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

modules/multiplayer/scene_cache_interface.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,14 @@ void SceneCacheInterface::_remove_node_cache(ObjectID p_oid) {
5454
if (nc->cache_id) {
5555
assigned_ids.erase(nc->cache_id);
5656
}
57+
#if 0
58+
// TODO: Find a way to cleanup recv_nodes without breaking visibility and RPCs interactions.
5759
for (KeyValue<int, int> &E : nc->recv_ids) {
5860
PeerInfo *pinfo = peers_info.getptr(E.key);
5961
ERR_CONTINUE(!pinfo);
6062
pinfo->recv_nodes.erase(E.value);
6163
}
64+
#endif
6265
for (KeyValue<int, bool> &E : nc->confirmed_peers) {
6366
PeerInfo *pinfo = peers_info.getptr(E.key);
6467
ERR_CONTINUE(!pinfo);
@@ -73,9 +76,12 @@ void SceneCacheInterface::on_peer_change(int p_id, bool p_connected) {
7376
} else {
7477
PeerInfo *pinfo = peers_info.getptr(p_id);
7578
ERR_FAIL_NULL(pinfo); // Bug.
76-
for (KeyValue<int, ObjectID> E : pinfo->recv_nodes) {
77-
NodeCache *nc = nodes_cache.getptr(E.value);
78-
ERR_CONTINUE(!nc);
79+
for (KeyValue<int, RecvNode> E : pinfo->recv_nodes) {
80+
NodeCache *nc = nodes_cache.getptr(E.value.oid);
81+
if (!nc) {
82+
// Node might have already been deleted locally.
83+
continue;
84+
}
7985
nc->recv_ids.erase(p_id);
8086
}
8187
for (const ObjectID &oid : pinfo->sent_nodes) {
@@ -115,7 +121,7 @@ void SceneCacheInterface::process_simplify_path(int p_from, const uint8_t *p_pac
115121
ERR_PRINT("The rpc node checksum failed. Make sure to have the same methods on both nodes. Node path: " + path);
116122
}
117123

118-
peers_info[p_from].recv_nodes.insert(id, node->get_instance_id());
124+
peers_info[p_from].recv_nodes.insert(id, RecvNode(node->get_instance_id(), path));
119125
NodeCache &cache = _track(node);
120126
cache.recv_ids.insert(p_from, id);
121127

@@ -269,14 +275,21 @@ bool SceneCacheInterface::send_object_cache(Object *p_obj, int p_peer_id, int &r
269275
}
270276

271277
Object *SceneCacheInterface::get_cached_object(int p_from, uint32_t p_cache_id) {
272-
Node *root_node = SceneTree::get_singleton()->get_root()->get_node(multiplayer->get_root_path());
273-
ERR_FAIL_NULL_V(root_node, nullptr);
274278
PeerInfo *pinfo = peers_info.getptr(p_from);
275279
ERR_FAIL_NULL_V(pinfo, nullptr);
276280

277-
const ObjectID *oid = pinfo->recv_nodes.getptr(p_cache_id);
278-
ERR_FAIL_NULL_V_MSG(oid, nullptr, vformat("ID %d not found in cache of peer %d.", p_cache_id, p_from));
279-
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(*oid));
281+
RecvNode *recv_node = pinfo->recv_nodes.getptr(p_cache_id);
282+
ERR_FAIL_NULL_V_MSG(recv_node, nullptr, vformat("ID %d not found in cache of peer %d.", p_cache_id, p_from));
283+
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(recv_node->oid));
284+
if (!node) {
285+
// Fallback to path lookup.
286+
Node *root_node = SceneTree::get_singleton()->get_root()->get_node(multiplayer->get_root_path());
287+
ERR_FAIL_NULL_V(root_node, nullptr);
288+
node = root_node->get_node(recv_node->path);
289+
if (node) {
290+
recv_node->oid = node->get_instance_id();
291+
}
292+
}
280293
ERR_FAIL_NULL_V_MSG(node, nullptr, vformat("Failed to get cached node from peer %d with cache ID %d.", p_from, p_cache_id));
281294
return node;
282295
}

modules/multiplayer/scene_cache_interface.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,18 @@ class SceneCacheInterface : public RefCounted {
4949
HashMap<int, bool> confirmed_peers; // peer id, confirmed
5050
};
5151

52+
struct RecvNode {
53+
ObjectID oid;
54+
NodePath path;
55+
56+
RecvNode(const ObjectID &p_oid, const NodePath &p_path) {
57+
oid = p_oid;
58+
path = p_path;
59+
}
60+
};
61+
5262
struct PeerInfo {
53-
HashMap<int, ObjectID> recv_nodes; // remote cache id, ObjectID
63+
HashMap<int, RecvNode> recv_nodes; // remote cache id, (ObjectID, NodePath)
5464
HashSet<ObjectID> sent_nodes;
5565
};
5666

0 commit comments

Comments
 (0)