diff --git a/core/object.cpp b/core/object.cpp index 07e24655c2a..c1904d05d76 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1282,6 +1282,23 @@ void Object::get_signal_list(List *p_signals ) const { } } + +void Object::get_all_signal_connections(List *p_connections) const { + + const StringName *S=NULL; + + while((S=signal_map.next(S))) { + + const Signal *s=&signal_map[*S]; + + for(int i=0;islot_map.size();i++) { + + p_connections->push_back(s->slot_map.getv(i).conn); + } + } + +} + void Object::get_signal_connection_list(const StringName& p_signal,List *p_connections) const { const Signal *s=signal_map.getptr(p_signal); diff --git a/core/object.h b/core/object.h index 44464ab1999..fc64b91412c 100644 --- a/core/object.h +++ b/core/object.h @@ -574,6 +574,7 @@ public: void emit_signal(const StringName& p_name,VARIANT_ARG_LIST); void get_signal_list(List *p_signals ) const; void get_signal_connection_list(const StringName& p_signal,List *p_connections) const; + void get_all_signal_connections(List *p_connections) const; Error connect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method,const Vector& p_binds=Vector(),uint32_t p_flags=0); void disconnect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index e0181b92385..5c60b9fbff5 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1417,6 +1417,41 @@ void Node::_duplicate_and_reown(Node* p_new_parent, const Map& p_re } + +void Node::_duplicate_signals(const Node* p_original,Node* p_copy) const { + + if (this!=p_original && get_owner()!=p_original) + return; + + List conns; + get_all_signal_connections(&conns); + + for (List::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); + + Node *target = E->get().target->cast_to(); + if (!target) + continue; + NodePath ptarget = p_original->get_path_to(target); + Node *copytarget = p_copy->get_node(ptarget); + + if (copy && copytarget) { + copy->connect(E->get().signal,copytarget,E->get().method,E->get().binds,CONNECT_PERSIST); + } + } + } + + for(int i=0;i_duplicate_signals(p_original,p_copy); + } + +} + + Node *Node::duplicate_and_reown(const Map& p_reown_map) const { @@ -1455,6 +1490,7 @@ Node *Node::duplicate_and_reown(const Map& p_reown_map) const { get_child(i)->_duplicate_and_reown(node,p_reown_map); } + _duplicate_signals(this,node); return node; } diff --git a/scene/main/node.h b/scene/main/node.h index 4d0a84d3472..be32c4e7261 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -126,6 +126,7 @@ private: void _propagate_pause_owner(Node*p_owner); Array _get_node_and_resource(const NodePath& p_path); + void _duplicate_signals(const Node* p_original,Node* p_copy) const; void _duplicate_and_reown(Node* p_new_parent, const Map& p_reown_map) const; Array _get_children() const; Array _get_groups() const;