summaryrefslogtreecommitdiffstats
path: root/scene/main/node.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main/node.cpp')
-rw-r--r--scene/main/node.cpp137
1 files changed, 60 insertions, 77 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 5c5049759f..884fc6de07 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -31,7 +31,6 @@
#include "node.h"
#include "core/config/project_settings.h"
-#include "core/core_string_names.h"
#include "core/io/resource_loader.h"
#include "core/object/message_queue.h"
#include "core/object/script_language.h"
@@ -42,7 +41,6 @@
#include "scene/main/multiplayer_api.h"
#include "scene/main/window.h"
#include "scene/resources/packed_scene.h"
-#include "scene/scene_string_names.h"
#include "viewport.h"
#include <stdint.h>
@@ -266,7 +264,7 @@ void Node::_propagate_ready() {
if (data.ready_first) {
data.ready_first = false;
notification(NOTIFICATION_READY);
- emit_signal(SceneStringNames::get_singleton()->ready);
+ emit_signal(SceneStringName(ready));
}
}
@@ -295,7 +293,7 @@ void Node::_propagate_enter_tree() {
GDVIRTUAL_CALL(_enter_tree);
- emit_signal(SceneStringNames::get_singleton()->tree_entered);
+ emit_signal(SceneStringName(tree_entered));
data.tree->node_added(this);
@@ -350,7 +348,7 @@ void Node::_propagate_after_exit_tree() {
data.blocked--;
- emit_signal(SceneStringNames::get_singleton()->tree_exited);
+ emit_signal(SceneStringName(tree_exited));
}
void Node::_propagate_exit_tree() {
@@ -372,7 +370,7 @@ void Node::_propagate_exit_tree() {
GDVIRTUAL_CALL(_exit_tree);
- emit_signal(SceneStringNames::get_singleton()->tree_exiting);
+ emit_signal(SceneStringName(tree_exiting));
notification(NOTIFICATION_EXIT_TREE, true);
if (data.tree) {
@@ -1738,12 +1736,10 @@ Node *Node::get_node_or_null(const NodePath &p_path) const {
StringName name = p_path.get_name(i);
Node *next = nullptr;
- if (name == SceneStringNames::get_singleton()->dot) { // .
-
+ if (name == SNAME(".")) {
next = current;
- } else if (name == SceneStringNames::get_singleton()->doubledot) { // ..
-
+ } else if (name == SNAME("..")) {
if (current == nullptr || !current->data.parent) {
return nullptr;
}
@@ -2667,8 +2663,6 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c
node->data.editable_instance = data.editable_instance;
}
- StringName script_property_name = CoreStringNames::get_singleton()->_script;
-
List<const Node *> hidden_roots;
List<const Node *> node_tree;
node_tree.push_front(this);
@@ -2770,45 +2764,6 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c
parent->move_child(dup, pos);
}
}
-
- for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
- Node *current_node = node->get_node(get_path_to(N->get()));
- ERR_CONTINUE(!current_node);
-
- if (p_flags & DUPLICATE_SCRIPTS) {
- bool is_valid = false;
- Variant scr = N->get()->get(script_property_name, &is_valid);
- if (is_valid) {
- current_node->set(script_property_name, scr);
- }
- }
-
- List<PropertyInfo> plist;
- N->get()->get_property_list(&plist);
-
- for (const PropertyInfo &E : plist) {
- if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
- continue;
- }
- String name = E.name;
- if (name == script_property_name) {
- continue;
- }
-
- Variant value = N->get()->get(name).duplicate(true);
-
- if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) {
- Resource *res = Object::cast_to<Resource>(value);
- if (res) { // Duplicate only if it's a resource
- current_node->set(name, res->duplicate());
- }
-
- } else {
- current_node->set(name, value);
- }
- }
- }
-
return node;
}
@@ -2820,7 +2775,7 @@ Node *Node::duplicate(int p_flags) const {
_duplicate_signals(this, dupe);
}
- _duplicate_properties_node(this, this, dupe);
+ _duplicate_properties(this, this, dupe, p_flags);
return dupe;
}
@@ -2831,7 +2786,8 @@ 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_INSTANTIATION | DUPLICATE_FROM_EDITOR, &r_duplimap);
+ int flags = DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR;
+ Node *dupe = _duplicate(flags, &r_duplimap);
// This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated.
if (!p_resource_remap.is_empty()) {
@@ -2843,7 +2799,7 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, con
// if the emitter node comes later in tree order than the receiver
_duplicate_signals(this, dupe);
- _duplicate_properties_node(this, this, dupe);
+ _duplicate_properties(this, this, dupe, flags);
return dupe;
}
@@ -2897,41 +2853,67 @@ void Node::remap_nested_resources(Ref<Resource> p_resource, const HashMap<Ref<Re
}
#endif
-// Duplicates properties that store a Node.
-// This has to be called after nodes have been duplicated since
-// only then do we get a full picture of how the duplicated node tree looks like.
-void Node::_duplicate_properties_node(const Node *p_root, const Node *p_original, Node *p_copy) const {
+// Duplicate node's properties.
+// This has to be called after nodes have been duplicated since there might be properties
+// of type Node that can be updated properly only if duplicated node tree is complete.
+void Node::_duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const {
List<PropertyInfo> props;
- p_copy->get_property_list(&props);
+ p_original->get_property_list(&props);
+ const StringName &script_property_name = CoreStringName(script);
+ if (p_flags & DUPLICATE_SCRIPTS) {
+ bool is_valid = false;
+ Variant scr = p_original->get(script_property_name, &is_valid);
+ if (is_valid) {
+ p_copy->set(script_property_name, scr);
+ }
+ }
for (const PropertyInfo &E : props) {
if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
continue;
}
- String name = E.name;
+ const StringName name = E.name;
+
+ if (name == script_property_name) {
+ continue;
+ }
+
Variant value = p_original->get(name).duplicate(true);
- if (value.get_type() == Variant::OBJECT) {
- Node *property_node = Object::cast_to<Node>(value);
- if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) {
- value = p_copy->get_node_or_null(p_original->get_path_to(property_node));
- p_copy->set(name, value);
+
+ if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) {
+ Resource *res = Object::cast_to<Resource>(value);
+ if (res) { // Duplicate only if it's a resource
+ p_copy->set(name, res->duplicate());
}
- } else if (value.get_type() == Variant::ARRAY) {
- Array arr = value;
- if (arr.get_typed_builtin() == Variant::OBJECT) {
- for (int i = 0; i < arr.size(); i++) {
- Node *property_node = Object::cast_to<Node>(arr[i]);
- if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) {
- arr[i] = p_copy->get_node_or_null(p_original->get_path_to(property_node));
+ } else {
+ if (value.get_type() == Variant::OBJECT) {
+ Node *property_node = Object::cast_to<Node>(value);
+ Variant out_value = value;
+ if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) {
+ out_value = p_copy->get_node_or_null(p_original->get_path_to(property_node));
+ }
+ p_copy->set(name, out_value);
+ } else if (value.get_type() == Variant::ARRAY) {
+ Array arr = value;
+ if (arr.get_typed_builtin() == Variant::OBJECT) {
+ for (int i = 0; i < arr.size(); i++) {
+ Node *property_node = Object::cast_to<Node>(arr[i]);
+ if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) {
+ arr[i] = p_copy->get_node_or_null(p_original->get_path_to(property_node));
+ }
}
+ value = arr;
+ p_copy->set(name, value);
}
- value = arr;
+ } else {
p_copy->set(name, value);
}
}
}
- for (int i = 0; i < p_copy->get_child_count(); i++) {
- _duplicate_properties_node(p_root, p_original->get_child(i), p_copy->get_child(i));
+ for (int i = 0; i < p_original->get_child_count(); i++) {
+ Node *copy_child = p_copy->get_child(i);
+ ERR_FAIL_NULL_MSG(copy_child, "Child node disappeared while duplicating.");
+ _duplicate_properties(p_root, p_original->get_child(i), copy_child, p_flags);
}
}
@@ -3231,7 +3213,7 @@ void Node::print_orphan_nodes() {
ObjectDB::debug_objects(_print_orphan_nodes_routine);
for (const KeyValue<ObjectID, List<String>> &E : _print_orphan_nodes_map) {
- print_line(itos(E.key) + " - Stray Node: " + E.value[0] + " (Type: " + E.value[1] + ")");
+ print_line(itos(E.key) + " - Stray Node: " + E.value.get(0) + " (Type: " + E.value.get(1) + ")");
}
// Flush it after use.
@@ -3321,7 +3303,7 @@ void Node::update_configuration_warnings() {
return;
}
if (get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root() == this || get_tree()->get_edited_scene_root()->is_ancestor_of(this))) {
- get_tree()->emit_signal(SceneStringNames::get_singleton()->node_configuration_warning_changed, this);
+ get_tree()->emit_signal(SceneStringName(node_configuration_warning_changed), this);
}
#endif
}
@@ -3520,6 +3502,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_node_and_resource", "path"), &Node::_get_node_and_resource);
ClassDB::bind_method(D_METHOD("is_inside_tree"), &Node::is_inside_tree);
+ ClassDB::bind_method(D_METHOD("is_part_of_edited_scene"), &Node::is_part_of_edited_scene);
ClassDB::bind_method(D_METHOD("is_ancestor_of", "node"), &Node::is_ancestor_of);
ClassDB::bind_method(D_METHOD("is_greater_than", "node"), &Node::is_greater_than);
ClassDB::bind_method(D_METHOD("get_path"), &Node::get_path);