Browse Source

-convert to subscene keeps signal connections, fixes #1863

Juan Linietsky 10 years ago
parent
commit
9b692b174b
4 changed files with 55 additions and 0 deletions
  1. 17 0
      core/object.cpp
  2. 1 0
      core/object.h
  3. 36 0
      scene/main/node.cpp
  4. 1 0
      scene/main/node.h

+ 17 - 0
core/object.cpp

@@ -1282,6 +1282,23 @@ void Object::get_signal_list(List<MethodInfo> *p_signals ) const {
 	}
 	}
 }
 }
 
 
+
+void Object::get_all_signal_connections(List<Connection> *p_connections) const {
+
+	const StringName *S=NULL;
+
+	while((S=signal_map.next(S))) {
+
+		const Signal *s=&signal_map[*S];
+
+		for(int i=0;i<s->slot_map.size();i++) {
+
+			p_connections->push_back(s->slot_map.getv(i).conn);
+		}
+	}
+
+}
+
 void Object::get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const {
 void Object::get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const {
 
 
 	const Signal *s=signal_map.getptr(p_signal);
 	const Signal *s=signal_map.getptr(p_signal);

+ 1 - 0
core/object.h

@@ -574,6 +574,7 @@ public:
 	void emit_signal(const StringName& p_name,VARIANT_ARG_LIST);
 	void emit_signal(const StringName& p_name,VARIANT_ARG_LIST);
 	void get_signal_list(List<MethodInfo> *p_signals ) const;
 	void get_signal_list(List<MethodInfo> *p_signals ) const;
 	void get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const;
 	void get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const;
+	void get_all_signal_connections(List<Connection> *p_connections) const;
 
 
 	Error connect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method,const Vector<Variant>& p_binds=Vector<Variant>(),uint32_t p_flags=0);
 	Error connect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method,const Vector<Variant>& p_binds=Vector<Variant>(),uint32_t p_flags=0);
 	void disconnect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method);
 	void disconnect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method);

+ 36 - 0
scene/main/node.cpp

@@ -1417,6 +1417,41 @@ void Node::_duplicate_and_reown(Node* p_new_parent, const Map<Node*,Node*>& p_re
 
 
 }
 }
 
 
+
+void Node::_duplicate_signals(const Node* p_original,Node* p_copy) const {
+
+	if (this!=p_original && get_owner()!=p_original)
+		return;
+
+	List<Connection> conns;
+	get_all_signal_connections(&conns);
+
+	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);
+
+			Node *target = E->get().target->cast_to<Node>();
+			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<get_child_count();i++) {
+		get_child(i)->_duplicate_signals(p_original,p_copy);
+	}
+
+}
+
+
 Node *Node::duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const {
 Node *Node::duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const {
 
 
 
 
@@ -1455,6 +1490,7 @@ Node *Node::duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const {
 		get_child(i)->_duplicate_and_reown(node,p_reown_map);
 		get_child(i)->_duplicate_and_reown(node,p_reown_map);
 	}
 	}
 
 
+	_duplicate_signals(this,node);
 	return node;
 	return node;
 
 
 }
 }

+ 1 - 0
scene/main/node.h

@@ -126,6 +126,7 @@ private:
 	void _propagate_pause_owner(Node*p_owner);
 	void _propagate_pause_owner(Node*p_owner);
 	Array _get_node_and_resource(const NodePath& p_path);
 	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<Node*,Node*>& p_reown_map) const;
 	void _duplicate_and_reown(Node* p_new_parent, const Map<Node*,Node*>& p_reown_map) const;
 	Array _get_children() const;
 	Array _get_children() const;
 	Array _get_groups() const;
 	Array _get_groups() const;