diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2020-06-10 10:47:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-10 10:47:17 +0200 |
commit | f25f0c54d676b72b7bbbdff2a696c45450d1bb88 (patch) | |
tree | bcdbd7a93d8829b61a7143fc7d21a121081ebcf0 | |
parent | 47f1faf51253fc6b004ee19d5c55760a634a534b (diff) | |
parent | a2392039af03a98adc4f697c0e755e952b0a6087 (diff) |
Merge pull request #39390 from mrushyendra/duplicate_signals_master
Fix signal duplication bug when duplicating node with instanced children
-rw-r--r-- | scene/main/node.cpp | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp index c9d430c656..1bf828a03b 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2238,46 +2238,53 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p // because re-targeting of connections from some descendant to another is not possible // if the emitter node comes later in tree order than the receiver void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { - if (this != p_original && (get_owner() != p_original && get_owner() != p_original->get_owner())) { + if ((this != p_original) && !(p_original->is_a_parent_of(this))) { return; } - List<Connection> conns; - get_all_signal_connections(&conns); + List<const Node *> process_list; + process_list.push_back(this); + while (!process_list.empty()) { + const Node *n = process_list.front()->get(); + process_list.pop_front(); - for (List<Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().flags & CONNECT_PERSIST) { - //user connected - NodePath p = p_original->get_path_to(this); - Node *copy = p_copy->get_node(p); + List<Connection> conns; + n->get_all_signal_connections(&conns); - Node *target = Object::cast_to<Node>(E->get().callable.get_object()); - if (!target) { - continue; - } - NodePath ptarget = p_original->get_path_to(target); + for (List<Connection>::Element *E = conns.front(); E; E = E->next()) { + if (E->get().flags & CONNECT_PERSIST) { + //user connected + NodePath p = p_original->get_path_to(n); + Node *copy = p_copy->get_node(p); - Node *copytarget = target; + Node *target = Object::cast_to<Node>(E->get().callable.get_object()); + if (!target) { + continue; + } + NodePath ptarget = p_original->get_path_to(target); - // Attempt to find a path to the duplicate target, if it seems it's not part - // of the duplicated and not yet parented hierarchy then at least try to connect - // to the same target as the original + Node *copytarget = target; - if (p_copy->has_node(ptarget)) { - copytarget = p_copy->get_node(ptarget); - } + // Attempt to find a path to the duplicate target, if it seems it's not part + // of the duplicated and not yet parented hierarchy then at least try to connect + // to the same target as the original - if (copy && copytarget) { - const Callable copy_callable = Callable(copytarget, E->get().callable.get_method()); - if (!copy->is_connected(E->get().signal.get_name(), copy_callable)) { - copy->connect(E->get().signal.get_name(), copy_callable, E->get().binds, E->get().flags); + if (p_copy->has_node(ptarget)) { + copytarget = p_copy->get_node(ptarget); + } + + if (copy && copytarget) { + const Callable copy_callable = Callable(copytarget, E->get().callable.get_method()); + if (!copy->is_connected(E->get().signal.get_name(), copy_callable)) { + copy->connect(E->get().signal.get_name(), copy_callable, E->get().binds, E->get().flags); + } } } } - } - for (int i = 0; i < get_child_count(); i++) { - get_child(i)->_duplicate_signals(p_original, p_copy); + for (int i = 0; i < n->get_child_count(); i++) { + process_list.push_back(n->get_child(i)); + } } } |