Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions editor/editor_file_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3140,6 +3140,13 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {

EditorProgress *ep = memnew(EditorProgress("reimport", TTR("(Re)Importing Assets"), p_files.size()));

if (!p_files.is_empty()) {
// Imported resources can be relatively large, so check if there is enough disk space.
// We perform the check here so it's performed only one for all files to be reimported,
// instead of once for each file.
EditorNode::get_singleton()->check_disk_space(p_files[0], 2.0, TTR("Importing resources will fail if the disk runs out of space."));
}

// The method reimport_files runs on the main thread, and if VSync is enabled
// or Update Continuously is disabled, Main::Iteration takes longer each frame.
// Each EditorProgress::step can trigger a redraw, and when there are many files to import,
Expand Down
20 changes: 20 additions & 0 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1800,6 +1800,11 @@ void EditorNode::_find_node_types(Node *p_node, int &count_2d, int &count_3d) {
}

void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
// Scene files are typically less than 1 MB, but text-based scenes with large amounts of embedded binary data
// can be much larger (sometimes 100 MB or more). Consider a buffer of 1 GiB to be safe, since there are
// also temporary files and thumbnails that come into play.
check_disk_space(p_file, 1.0, TTR("Saving scenes will fail if the disk runs out of space."));

save_scene_progress = memnew(EditorProgress("save", TTR("Saving Scene"), 4));

if (editor_data.get_edited_scene_root() != nullptr) {
Expand Down Expand Up @@ -6788,6 +6793,21 @@ bool EditorNode::call_build() {
return builds_successful;
}

// Check for available disk space on the target disk and warn the user if needed according to a set threshold.
// The threshold (set in GiB) should be set to cover most use cases for the file being written.
void EditorNode::check_disk_space(const String &p_target_path, float p_size_gib, const String &p_rationale) const {
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
String path = p_target_path;
if (path.is_relative_path()) {
path = "res://" + path;
}
dir->open(path);
if (dir->get_space_left() < p_size_gib * Math::pow(1024.0, 3.0)) {
// Less than `p_size_gib` GiB available.
WARN_PRINT_ED(vformat(TTR("%s: Current available space on target disk is low (%s)."), path, String::humanize_size(dir->get_space_left())) + " " + p_rationale);
}
}

void EditorNode::_inherit_imported(const String &p_action) {
open_imported->hide();
load_scene(open_import_request, true, true);
Expand Down
2 changes: 2 additions & 0 deletions editor/editor_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,8 @@ class EditorNode : public Node {
static void add_init_callback(EditorNodeInitCallback p_callback) { _init_callbacks.push_back(p_callback); }
static void add_build_callback(EditorBuildCallback p_callback);

void check_disk_space(const String &p_target_path, float p_size_gib, const String &p_rationale) const;

static bool immediate_confirmation_dialog(const String &p_text, const String &p_ok_text = TTR("Ok"), const String &p_cancel_text = TTR("Cancel"), uint32_t p_wrap_width = 0);

static void cleanup();
Expand Down
9 changes: 9 additions & 0 deletions editor/export/editor_export_platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err)
return has_messages;
}

void EditorExportPlatform::check_disk_space(const String &p_path) const {
// Project files can grow quite large, so check for a reasonable amount of available space before exporting.
EditorNode::get_singleton()->check_disk_space(p_path, 10.0, TTR("Exporting the project will fail if the disk runs out of space."));
}

bool EditorExportPlatform::_check_hash(const uint8_t *p_hash, const Vector<uint8_t> &p_data) {
if (p_hash == nullptr) {
return false;
Expand Down Expand Up @@ -2186,11 +2191,13 @@ Error EditorExportPlatform::save_zip_patch(const Ref<EditorExportPreset> &p_pres

Error EditorExportPlatform::export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
check_disk_space(p_path);
return save_pack(p_preset, p_debug, p_path);
}

Error EditorExportPlatform::export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
check_disk_space(p_path);
return save_zip(p_preset, p_debug, p_path);
}

Expand All @@ -2200,6 +2207,7 @@ Error EditorExportPlatform::export_pack_patch(const Ref<EditorExportPreset> &p_p
if (err != OK) {
return err;
}
check_disk_space(p_path);
err = save_pack_patch(p_preset, p_debug, p_path);
_unload_patches();
return err;
Expand All @@ -2211,6 +2219,7 @@ Error EditorExportPlatform::export_zip_patch(const Ref<EditorExportPreset> &p_pr
if (err != OK) {
return err;
}
check_disk_space(p_path);
err = save_zip_patch(p_preset, p_debug, p_path);
_unload_patches();
return err;
Expand Down
2 changes: 2 additions & 0 deletions editor/export/editor_export_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ class EditorExportPlatform : public RefCounted {
virtual Ref<EditorExportPreset> create_preset();
virtual bool is_executable(const String &p_path) const { return false; }

void check_disk_space(const String &p_path) const;

virtual void clear_messages() { messages.clear(); }
virtual void add_message(ExportMessageType p_type, const String &p_category, const String &p_message) {
ExportMessage msg;
Expand Down
1 change: 1 addition & 0 deletions editor/export/editor_export_platform_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ List<String> EditorExportPlatformExtension::get_binary_extensions(const Ref<Edit

Error EditorExportPlatformExtension::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
check_disk_space(p_path);

Error ret = FAILED;
GDVIRTUAL_CALL(_export_project, p_preset, p_debug, p_path, p_flags, ret);
Expand Down
1 change: 1 addition & 0 deletions editor/export/editor_export_platform_pc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ bool EditorExportPlatformPC::has_valid_project_configuration(const Ref<EditorExp

Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
check_disk_space(p_path);

Error err = prepare_template(p_preset, p_debug, p_path, p_flags);
if (err == OK) {
Expand Down
14 changes: 14 additions & 0 deletions editor/export/export_template_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,14 @@ void ExportTemplateManager::_download_current() {
}
is_downloading_templates = true;

// Decompressed official export templates are typically around 2 GiB on disk.
// However, the compressed file has to stay on disk until the export templates are done extracting,
// so we also need to account for its compressed size on top.
EditorNode::get_singleton()->check_disk_space(
EditorPaths::get_singleton()->get_data_dir(),
4.0,
TTR("Downloading export templates will fail if the disk runs out of space."));

install_options_vb->hide();
download_progress_hb->show();

Expand Down Expand Up @@ -425,6 +433,12 @@ void ExportTemplateManager::_install_file() {
}

bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_skip_progress) {
// Decompressed official export templates are typically around 2 GiB on disk.
EditorNode::get_singleton()->check_disk_space(
EditorPaths::get_singleton()->get_data_dir(),
4.0,
TTR("Installing export templates will fail if the disk runs out of space."));

Ref<FileAccess> io_fa;
zlib_filefunc_def io = zipio_create_io(&io_fa);

Expand Down
4 changes: 4 additions & 0 deletions editor/export/project_zip_packer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "core/io/file_access.h"
#include "core/os/os.h"
#include "core/os/time.h"
#include "editor/editor_node.h"

String ProjectZIPPacker::get_project_zip_safe_name() {
// Name the downloaded ZIP file to contain the project name and download date for easier organization.
Expand All @@ -50,6 +51,9 @@ String ProjectZIPPacker::get_project_zip_safe_name() {
}

void ProjectZIPPacker::pack_project_zip(const String &p_path) {
// Project files can grow quite large, so check for a reasonable amount of available space before packing.
EditorNode::get_singleton()->check_disk_space(p_path, 10.0, TTR("Packing the project as ZIP will fail if the disk runs out of space."));

Ref<FileAccess> io_fa;
zlib_filefunc_def io = zipio_create_io(&io_fa);

Expand Down
4 changes: 4 additions & 0 deletions editor/import/3d/scene_import_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,10 @@ void SceneImportSettingsDialog::_viewport_input(const Ref<InputEvent> &p_input)
}

void SceneImportSettingsDialog::_re_import() {
// Complex 3D scenes can be quite large. Consider a buffer of 1 GiB to be
// safe, since there are also temporary files and thumbnails that come into play.
EditorNode::get_singleton()->check_disk_space(base_path, 1.0, TTR("Importing resources will fail if the disk runs out of space."));

HashMap<StringName, Variant> main_settings;

main_settings = scene_import_settings_data->current;
Expand Down
5 changes: 5 additions & 0 deletions editor/import/audio_stream_import_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "audio_stream_import_settings.h"
#include "editor/audio_stream_preview.h"
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
#include "editor/editor_string_names.h"
#include "editor/themes/editor_scale.h"
#include "scene/gui/check_box.h"
Expand Down Expand Up @@ -515,6 +516,10 @@ void AudioStreamImportSettingsDialog::_settings_changed() {
}

void AudioStreamImportSettingsDialog::_reimport() {
// Long audio files can be quite large. Consider a buffer of 1 GiB to be
// safe, since there are also temporary files and thumbnails that come into play.
EditorNode::get_singleton()->check_disk_space(path, 1.0, TTR("Importing resources will fail if the disk runs out of space."));

params["loop"] = loop->is_pressed();
params["loop_offset"] = loop_offset->get_value();
params["bpm"] = bpm_enabled->is_pressed() ? double(bpm_edit->get_value()) : double(0);
Expand Down
4 changes: 4 additions & 0 deletions editor/import/dynamic_font_import_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,10 @@ void DynamicFontImportSettingsDialog::_notification(int p_what) {
}

void DynamicFontImportSettingsDialog::_re_import() {
// Complex fonts can be quite large. Consider a buffer of 1 GiB to be
// safe, since there are also temporary files and thumbnails that come into play.
EditorNode::get_singleton()->check_disk_space(base_path, 1.0, TTR("Importing resources will fail if the disk runs out of space."));

HashMap<StringName, Variant> main_settings;

main_settings["face_index"] = import_settings_data->get("face_index");
Expand Down
1 change: 1 addition & 0 deletions platform/android/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3337,6 +3337,7 @@ bool EditorExportPlatformAndroid::_is_clean_build_required(const Ref<EditorExpor
Error EditorExportPlatformAndroid::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
int export_format = int(p_preset->get("gradle_build/export_format"));
bool should_sign = p_preset->get("package/signed");
check_disk_space(p_path);
return export_project_helper(p_preset, p_debug, p_path, export_format, should_sign, p_flags);
}

Expand Down
1 change: 1 addition & 0 deletions platform/ios/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1980,6 +1980,7 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
}

Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
check_disk_space(p_path);
return _export_project_helper(p_preset, p_debug, p_path, p_flags, false);
}

Expand Down
1 change: 1 addition & 0 deletions platform/macos/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1519,6 +1519,7 @@ Error EditorExportPlatformMacOS::_export_debug_script(const Ref<EditorExportPres

Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
check_disk_space(p_path);

const String base_dir = p_path.get_base_dir();

Expand Down
1 change: 1 addition & 0 deletions platform/web/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ List<String> EditorExportPlatformWeb::get_binary_extensions(const Ref<EditorExpo

Error EditorExportPlatformWeb::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
check_disk_space(p_path);

const String custom_debug = p_preset->get("custom_template/debug");
const String custom_release = p_preset->get("custom_template/release");
Expand Down
4 changes: 2 additions & 2 deletions servers/movie_writer/movie_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,14 @@ void MovieWriter::begin(const Size2i &p_movie_size, uint32_t p_fps, const String

// Check for available disk space and warn the user if needed.
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
String path = p_base_path.get_basename();
String path = p_base_path;
if (path.is_relative_path()) {
path = "res://" + path;
}
dir->open(path);
if (dir->get_space_left() < 10 * Math::pow(1024.0, 3.0)) {
// Less than 10 GiB available.
WARN_PRINT(vformat("Current available space on disk is low (%s). MovieWriter will fail during movie recording if the disk runs out of available space.", String::humanize_size(dir->get_space_left())));
WARN_PRINT(vformat("%s: Current available space on disk is low (%s). MovieWriter will fail during movie recording if the disk runs out of space.", path, String::humanize_size(dir->get_space_left())));
}

cpu_time = 0.0f;
Expand Down