Repository: godotengine/godot
File: editor/scene_tree_dock.cpp (C++)

Code before:
		Node *node = e->get();
		if (node) {
			_toggle_editable_children(node);

			bool placeholder = node->get_scene_instance_load_placeholder();
			placeholder = !placeholder;

			node->set_scene_instance_load_placeholder(placeholder);
			scene_tree->update_tree();
		}
	}
}

void SceneTreeDock::_update_all_gizmos(Node *p_node) {
	Node3DEditor::get_singleton()->update_all_gizmos(p_node);
}

template <class RootType>
void SceneTreeDock::_reparent_nodes_to_typed_root(RootType *p_root, List<Node *> &p_nodes, Node *p_owner) {
	for (Node *node : p_nodes) {
		node->set_owner(p_owner);
		if (node != p_root && node->get_owner() == p_owner) {
			List<Node *> owned;
			node->get_owned_by(p_owner, &owned, true);
			// For Node2D and Node3D types, we can preserve the global transform when move them to the root node
			if (typeid(RootType) == typeid(Node3D)) {
				Node3D *node_3d = Object::cast_to<Node3D>(node);
				if (node_3d) {
					Transform3D gt = node_3d->get_global_transform();
					node_3d->get_parent()->remove_child(node_3d);
					p_root->add_child(node_3d);
					node_3d->set_global_transform(gt);
				} else {
					node->get_parent()->remove_child(node);
					p_root->add_child(node);
				}
			} else if (typeid(RootType) == typeid(Node2D)) {
				Node2D *node_2d = Object::cast_to<Node2D>(node);
				if (node_2d) {
					Transform2D gt = node_2d->get_global_transform();
					node_2d->get_parent()->remove_child(node_2d);
					p_root->add_child(node_2d);
					node_2d->set_global_transform(gt);
				} else {
					node->get_parent()->remove_child(node);
					p_root->add_child(node);
				}
			} else {
				node->get_parent()->remove_child(node);
				p_root->add_child(node);
			}

Review comment (suggestion):
typeid() may introduce RTTI.

I'd suggest a compile-time check, or using a different function for each of the three cases.

Code after:

		// When edited_scene inherits from another one the root Node will be the parent Scene,
		// we don't want to consider that Node a foreign one otherwise we would not be able to
		// delete it.
		if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene == E) {
			continue;
		}

		if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E)) >= 0) {
			accept->set_text(TTR("Can't operate on nodes the current scene inherits from!"));
			accept->popup_centered();
			return false;
		}
	}

	return true;
}

bool SceneTreeDock::_validate_no_instance() {
	List<Node *> selection = editor_selection->get_selected_node_list();

	for (Node *E : selection) {
		if (E != edited_scene && !E->get_scene_file_path().is_empty()) {
			accept->set_text(TTR("This operation can't be done on instantiated scenes."));
			accept->popup_centered();
			return false;
		}
	}

	return true;
}

void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) {
	Node *new_parent = scene_root->get_node(p_path);
	ERR_FAIL_NULL(new_parent);

	List<Node *> selection = editor_selection->get_selected_node_list();

	if (selection.is_empty()) {
		return; // Nothing to reparent.
	}

	Vector<Node *> nodes;

	for (Node *E : selection) {
		nodes.push_back(E);
	}

	_do_reparent(new_parent, -1, nodes, p_keep_global_xform);
}