You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-30 18:30:54 +00:00
Merge pull request #110432 from KoBeWi/signal_lost
Fix lost connections when saving branch as scene
This commit is contained in:
@@ -439,9 +439,9 @@ void SceneTreeDock::_perform_create_audio_stream_players(const Vector<String> &p
|
||||
undo_redo->commit_action();
|
||||
}
|
||||
|
||||
void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) {
|
||||
void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *p_base) {
|
||||
// `move_child` + `get_index` doesn't really work for internal nodes.
|
||||
ERR_FAIL_COND_MSG(base->is_internal(), "Trying to replace internal node, this is not supported.");
|
||||
ERR_FAIL_COND_MSG(p_base->is_internal(), "Trying to replace internal node, this is not supported.");
|
||||
|
||||
Ref<PackedScene> sdata = ResourceLoader::load(p_file);
|
||||
if (sdata.is_null()) {
|
||||
@@ -457,10 +457,10 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base)
|
||||
return;
|
||||
}
|
||||
|
||||
instantiated_scene->set_unique_name_in_owner(base->is_unique_name_in_owner());
|
||||
instantiated_scene->set_unique_name_in_owner(p_base->is_unique_name_in_owner());
|
||||
|
||||
Node2D *copy_2d = Object::cast_to<Node2D>(instantiated_scene);
|
||||
Node2D *base_2d = Object::cast_to<Node2D>(base);
|
||||
Node2D *base_2d = Object::cast_to<Node2D>(p_base);
|
||||
if (copy_2d && base_2d) {
|
||||
copy_2d->set_position(base_2d->get_position());
|
||||
copy_2d->set_rotation(base_2d->get_rotation());
|
||||
@@ -468,27 +468,55 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base)
|
||||
}
|
||||
|
||||
Node3D *copy_3d = Object::cast_to<Node3D>(instantiated_scene);
|
||||
Node3D *base_3d = Object::cast_to<Node3D>(base);
|
||||
Node3D *base_3d = Object::cast_to<Node3D>(p_base);
|
||||
if (copy_3d && base_3d) {
|
||||
copy_3d->set_position(base_3d->get_position());
|
||||
copy_3d->set_rotation(base_3d->get_rotation());
|
||||
copy_3d->set_scale(base_3d->get_scale());
|
||||
}
|
||||
|
||||
// Ensure that local signals are still connected.
|
||||
List<MethodInfo> signal_list;
|
||||
p_base->get_signal_list(&signal_list);
|
||||
for (const MethodInfo &meth : signal_list) {
|
||||
List<Object::Connection> connection_list;
|
||||
p_base->get_signal_connection_list(meth.name, &connection_list);
|
||||
|
||||
List<Object::Connection> other;
|
||||
instantiated_scene->get_signal_connection_list(meth.name, &other);
|
||||
|
||||
for (const Object::Connection &con : connection_list) {
|
||||
if (!(con.flags & Object::CONNECT_PERSIST)) {
|
||||
continue;
|
||||
}
|
||||
// May be already connected if the connection was saved with the scene.
|
||||
bool already_connected = false; // Can't use is_connected(), because of different targets.
|
||||
for (const Object::Connection &otcon : other) {
|
||||
if (otcon.signal.get_name() == con.signal.get_name() && otcon.callable.get_method() == con.callable.get_method()) {
|
||||
already_connected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!already_connected) {
|
||||
instantiated_scene->connect(con.signal.get_name(), con.callable, con.flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
||||
undo_redo->create_action(TTR("Replace with Branch Scene"));
|
||||
|
||||
Node *parent = base->get_parent();
|
||||
int pos = base->get_index(false);
|
||||
undo_redo->add_do_method(parent, "remove_child", base);
|
||||
Node *parent = p_base->get_parent();
|
||||
int pos = p_base->get_index(false);
|
||||
undo_redo->add_do_method(parent, "remove_child", p_base);
|
||||
undo_redo->add_undo_method(parent, "remove_child", instantiated_scene);
|
||||
undo_redo->add_do_method(parent, "add_child", instantiated_scene, true);
|
||||
undo_redo->add_undo_method(parent, "add_child", base, true);
|
||||
undo_redo->add_undo_method(parent, "add_child", p_base, true);
|
||||
undo_redo->add_do_method(parent, "move_child", instantiated_scene, pos);
|
||||
undo_redo->add_undo_method(parent, "move_child", base, pos);
|
||||
undo_redo->add_undo_method(parent, "move_child", p_base, pos);
|
||||
|
||||
List<Node *> owned;
|
||||
base->get_owned_by(base->get_owner(), &owned);
|
||||
p_base->get_owned_by(p_base->get_owner(), &owned);
|
||||
Array owners;
|
||||
for (Node *F : owned) {
|
||||
owners.push_back(F);
|
||||
@@ -499,12 +527,12 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base)
|
||||
undo_redo->add_do_method(editor_selection, "clear");
|
||||
undo_redo->add_undo_method(editor_selection, "clear");
|
||||
undo_redo->add_do_method(editor_selection, "add_node", instantiated_scene);
|
||||
undo_redo->add_undo_method(editor_selection, "add_node", base);
|
||||
undo_redo->add_undo_method(editor_selection, "add_node", p_base);
|
||||
undo_redo->add_do_property(scene_tree, "set_selected", instantiated_scene);
|
||||
undo_redo->add_undo_property(scene_tree, "set_selected", base);
|
||||
undo_redo->add_undo_property(scene_tree, "set_selected", p_base);
|
||||
|
||||
undo_redo->add_do_reference(instantiated_scene);
|
||||
undo_redo->add_undo_reference(base);
|
||||
undo_redo->add_undo_reference(p_base);
|
||||
undo_redo->commit_action();
|
||||
}
|
||||
|
||||
@@ -3242,7 +3270,7 @@ void SceneTreeDock::_replace_node(Node *p_node, Node *p_by_node, bool p_keep_pro
|
||||
if (!(c.flags & Object::CONNECT_PERSIST)) {
|
||||
continue;
|
||||
}
|
||||
newnode->connect(c.signal.get_name(), c.callable, Object::CONNECT_PERSIST);
|
||||
newnode->connect(c.signal.get_name(), c.callable, c.flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -276,7 +276,7 @@ class SceneTreeDock : public EditorDock {
|
||||
|
||||
void _perform_instantiate_scenes(const Vector<String> &p_files, Node *p_parent, int p_pos);
|
||||
void _perform_create_audio_stream_players(const Vector<String> &p_files, Node *p_parent, int p_pos);
|
||||
void _replace_with_branch_scene(const String &p_file, Node *base);
|
||||
void _replace_with_branch_scene(const String &p_file, Node *p_base);
|
||||
|
||||
void _remote_tree_selected();
|
||||
void _local_tree_selected();
|
||||
|
||||
Reference in New Issue
Block a user