summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/multiplayer_peer.cpp4
-rw-r--r--scene/main/node.cpp5
-rw-r--r--scene/main/node.h1
-rw-r--r--scene/main/viewport.cpp118
-rw-r--r--scene/main/viewport.h5
5 files changed, 111 insertions, 22 deletions
diff --git a/scene/main/multiplayer_peer.cpp b/scene/main/multiplayer_peer.cpp
index f3e56a1455..8c9eeea027 100644
--- a/scene/main/multiplayer_peer.cpp
+++ b/scene/main/multiplayer_peer.cpp
@@ -201,6 +201,9 @@ void MultiplayerPeerExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_packet_script)
GDVIRTUAL_BIND(_put_packet_script, "p_buffer");
+ GDVIRTUAL_BIND(_get_packet_channel);
+ GDVIRTUAL_BIND(_get_packet_mode);
+
GDVIRTUAL_BIND(_set_transfer_channel, "p_channel");
GDVIRTUAL_BIND(_get_transfer_channel);
@@ -217,6 +220,7 @@ void MultiplayerPeerExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_unique_id);
GDVIRTUAL_BIND(_set_refuse_new_connections, "p_enable");
GDVIRTUAL_BIND(_is_refusing_new_connections);
+ GDVIRTUAL_BIND(_is_server_relay_supported);
GDVIRTUAL_BIND(_get_connection_status);
ADD_PROPERTY_DEFAULT("transfer_mode", TRANSFER_MODE_RELIABLE);
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 52c1df8110..057fd15f1b 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2759,6 +2759,10 @@ bool Node::is_displayed_folded() const {
return data.display_folded;
}
+bool Node::is_ready() const {
+ return !data.ready_first;
+}
+
void Node::request_ready() {
data.ready_first = true;
}
@@ -2897,6 +2901,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("queue_free"), &Node::queue_free);
ClassDB::bind_method(D_METHOD("request_ready"), &Node::request_ready);
+ ClassDB::bind_method(D_METHOD("is_node_ready"), &Node::is_ready);
ClassDB::bind_method(D_METHOD("set_multiplayer_authority", "id", "recursive"), &Node::set_multiplayer_authority, DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_multiplayer_authority"), &Node::get_multiplayer_authority);
diff --git a/scene/main/node.h b/scene/main/node.h
index 493578bc5b..4a606538a8 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -455,6 +455,7 @@ public:
bool can_process_notification(int p_what) const;
bool is_enabled() const;
+ bool is_ready() const;
void request_ready();
static void print_orphan_nodes();
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 8cd57536bf..4aaa2e8f5b 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -61,6 +61,10 @@
#include "servers/rendering/rendering_server_globals.h"
void ViewportTexture::setup_local_to_scene() {
+ if (vp_pending) {
+ return;
+ }
+
Node *loc_scene = get_local_scene();
if (!loc_scene) {
return;
@@ -68,26 +72,14 @@ void ViewportTexture::setup_local_to_scene() {
if (vp) {
vp->viewport_textures.erase(this);
+ vp = nullptr;
}
- vp = nullptr;
-
- Node *vpn = loc_scene->get_node(path);
- ERR_FAIL_COND_MSG(!vpn, "ViewportTexture: Path to node is invalid.");
-
- vp = Object::cast_to<Viewport>(vpn);
-
- ERR_FAIL_COND_MSG(!vp, "ViewportTexture: Path to node does not point to a viewport.");
-
- vp->viewport_textures.insert(this);
-
- ERR_FAIL_NULL(RenderingServer::get_singleton());
- if (proxy_ph.is_valid()) {
- RS::get_singleton()->texture_proxy_update(proxy, vp->texture_rid);
- RS::get_singleton()->free(proxy_ph);
+ if (loc_scene->is_ready()) {
+ _setup_local_to_scene(loc_scene);
} else {
- ERR_FAIL_COND(proxy.is_valid()); // Should be invalid.
- proxy = RS::get_singleton()->texture_proxy_create(vp->texture_rid);
+ loc_scene->connect(SNAME("ready"), callable_mp(this, &ViewportTexture::_setup_local_to_scene).bind(loc_scene), CONNECT_ONE_SHOT);
+ vp_pending = true;
}
}
@@ -98,8 +90,24 @@ void ViewportTexture::set_viewport_path_in_scene(const NodePath &p_path) {
path = p_path;
- if (get_local_scene()) {
+ if (vp) {
+ vp->viewport_textures.erase(this);
+ vp = nullptr;
+ }
+
+ if (proxy_ph.is_valid()) {
+ RS::get_singleton()->free(proxy_ph);
+ }
+ if (proxy.is_valid()) {
+ RS::get_singleton()->free(proxy);
+ }
+ proxy_ph = RID();
+ proxy = RID();
+
+ if (get_local_scene() && !path.is_empty()) {
setup_local_to_scene();
+ } else {
+ emit_changed();
}
}
@@ -108,17 +116,32 @@ NodePath ViewportTexture::get_viewport_path_in_scene() const {
}
int ViewportTexture::get_width() const {
- ERR_FAIL_COND_V_MSG(!vp, 0, "Viewport Texture must be set to use it.");
+ if (!vp) {
+ if (!vp_pending) {
+ ERR_PRINT("Viewport Texture must be set to use it.");
+ }
+ return 0;
+ }
return vp->size.width;
}
int ViewportTexture::get_height() const {
- ERR_FAIL_COND_V_MSG(!vp, 0, "Viewport Texture must be set to use it.");
+ if (!vp) {
+ if (!vp_pending) {
+ ERR_PRINT("Viewport Texture must be set to use it.");
+ }
+ return 0;
+ }
return vp->size.height;
}
Size2 ViewportTexture::get_size() const {
- ERR_FAIL_COND_V_MSG(!vp, Size2(), "Viewport Texture must be set to use it.");
+ if (!vp) {
+ if (!vp_pending) {
+ ERR_PRINT("Viewport Texture must be set to use it.");
+ }
+ return Size2();
+ }
return vp->size;
}
@@ -135,10 +158,38 @@ bool ViewportTexture::has_alpha() const {
}
Ref<Image> ViewportTexture::get_image() const {
- ERR_FAIL_COND_V_MSG(!vp, Ref<Image>(), "Viewport Texture must be set to use it.");
+ if (!vp) {
+ if (!vp_pending) {
+ ERR_PRINT("Viewport Texture must be set to use it.");
+ }
+ return Ref<Image>();
+ }
return RS::get_singleton()->texture_2d_get(vp->texture_rid);
}
+void ViewportTexture::_setup_local_to_scene(const Node *p_loc_scene) {
+ Node *vpn = p_loc_scene->get_node(path);
+ ERR_FAIL_COND_MSG(!vpn, "ViewportTexture: Path to node is invalid.");
+
+ vp = Object::cast_to<Viewport>(vpn);
+
+ ERR_FAIL_COND_MSG(!vp, "ViewportTexture: Path to node does not point to a viewport.");
+
+ vp->viewport_textures.insert(this);
+
+ ERR_FAIL_NULL(RenderingServer::get_singleton());
+ if (proxy_ph.is_valid()) {
+ RS::get_singleton()->texture_proxy_update(proxy, vp->texture_rid);
+ RS::get_singleton()->free(proxy_ph);
+ } else {
+ ERR_FAIL_COND(proxy.is_valid()); // Should be invalid.
+ proxy = RS::get_singleton()->texture_proxy_create(vp->texture_rid);
+ }
+ vp_pending = false;
+
+ emit_changed();
+}
+
void ViewportTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_viewport_path_in_scene", "path"), &ViewportTexture::set_viewport_path_in_scene);
ClassDB::bind_method(D_METHOD("get_viewport_path_in_scene"), &ViewportTexture::get_viewport_path_in_scene);
@@ -374,9 +425,28 @@ int Viewport::_sub_window_find(Window *p_window) {
return -1;
}
+void Viewport::_update_viewport_path() {
+ if (viewport_textures.is_empty()) {
+ return;
+ }
+
+ Node *scene_root = get_scene_file_path().is_empty() ? get_owner() : this;
+ if (!scene_root && is_inside_tree()) {
+ scene_root = get_tree()->get_edited_scene_root();
+ }
+ if (scene_root && (scene_root == this || scene_root->is_ancestor_of(this))) {
+ NodePath path_in_scene = scene_root->get_path_to(this);
+ for (ViewportTexture *E : viewport_textures) {
+ E->path = path_in_scene;
+ }
+ }
+}
+
void Viewport::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
+ _update_viewport_path();
+
if (get_parent()) {
parent = get_parent()->get_viewport();
RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, parent->get_viewport_rid());
@@ -469,6 +539,10 @@ void Viewport::_notification(int p_what) {
RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, RID());
} break;
+ case NOTIFICATION_PATH_RENAMED: {
+ _update_viewport_path();
+ } break;
+
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (!get_tree()) {
return;
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 5213c0db01..de0abec052 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -59,6 +59,9 @@ class ViewportTexture : public Texture2D {
friend class Viewport;
Viewport *vp = nullptr;
+ bool vp_pending = false;
+
+ void _setup_local_to_scene(const Node *p_loc_scene);
mutable RID proxy_ph;
mutable RID proxy;
@@ -314,6 +317,8 @@ private:
Ref<ViewportTexture> default_texture;
HashSet<ViewportTexture *> viewport_textures;
+ void _update_viewport_path();
+
SDFOversize sdf_oversize = SDF_OVERSIZE_120_PERCENT;
SDFScale sdf_scale = SDF_SCALE_50_PERCENT;