Skip to content

Commit c49f784

Browse files
committed
Warn when running low on disk space when performing certain editor operations
The following editor operations will now warn the user if the available space on the target disk is low: - Saving a scene (< 1 GiB). - Importing a set of resources (< 2 GiB). - Downloading export templates (< 4 GiB). - Installing export templates (< 4 GiB). - Exporting a project (< 10 GiB). - Packing a project as a ZIP file (< 10 GiB).
1 parent 4e6451d commit c49f784

File tree

14 files changed

+64
-1
lines changed

14 files changed

+64
-1
lines changed

editor/editor_file_system.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3142,6 +3142,13 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
31423142

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

3145+
if (!p_files.is_empty()) {
3146+
// Imported resources can be relatively large, so check if there is enough disk space.
3147+
// We perform the check here so it's performed only one for all files to be reimported,
3148+
// instead of once for each file.
3149+
EditorNode::get_singleton()->check_disk_space(p_files[0], 2.0, TTR("Importing resources will fail if the disk runs out of space."));
3150+
}
3151+
31453152
// The method reimport_files runs on the main thread, and if VSync is enabled
31463153
// or Update Continuously is disabled, Main::Iteration takes longer each frame.
31473154
// Each EditorProgress::step can trigger a redraw, and when there are many files to import,

editor/editor_node.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,6 +1800,11 @@ void EditorNode::_find_node_types(Node *p_node, int &count_2d, int &count_3d) {
18001800
}
18011801

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

18051810
if (editor_data.get_edited_scene_root() != nullptr) {
@@ -6790,6 +6795,21 @@ bool EditorNode::call_build() {
67906795
return builds_successful;
67916796
}
67926797

6798+
// Check for available disk space on the target disk and warn the user if needed according to a set threshold.
6799+
// The threshold (set in GiB) should be set to cover most use cases for the file being written.
6800+
void EditorNode::check_disk_space(const String &p_target_path, float p_size_gib, const String &p_rationale) const {
6801+
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
6802+
String path = p_target_path.get_basename();
6803+
if (path.is_relative_path()) {
6804+
path = "res://" + path;
6805+
}
6806+
dir->open(path);
6807+
if (dir->get_space_left() < p_size_gib * Math::pow(1024.0, 3.0)) {
6808+
// Less than `p_size_gib` GiB available.
6809+
WARN_PRINT_ED(vformat(TTR("Current available space on target disk is low (%s)."), String::humanize_size(dir->get_space_left())) + " " + p_rationale);
6810+
}
6811+
}
6812+
67936813
void EditorNode::_inherit_imported(const String &p_action) {
67946814
open_imported->hide();
67956815
load_scene(open_import_request, true, true);

editor/editor_node.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,8 @@ class EditorNode : public Node {
741741
static void add_init_callback(EditorNodeInitCallback p_callback) { _init_callbacks.push_back(p_callback); }
742742
static void add_build_callback(EditorBuildCallback p_callback);
743743

744+
void check_disk_space(const String &p_target_path, float p_size_gib, const String &p_rationale) const;
745+
744746
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);
745747

746748
static void cleanup();

editor/export/editor_export_platform.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err)
214214
return has_messages;
215215
}
216216

217+
void EditorExportPlatform::check_disk_space(const String &p_path) const {
218+
// Project files can grow quite large, so check for a reasonable amount of available space before exporting.
219+
EditorNode::get_singleton()->check_disk_space(p_path, 10.0, TTR("Exporting the project will fail if the disk runs out of space."));
220+
}
221+
217222
bool EditorExportPlatform::_check_hash(const uint8_t *p_hash, const Vector<uint8_t> &p_data) {
218223
if (p_hash == nullptr) {
219224
return false;
@@ -2189,11 +2194,13 @@ Error EditorExportPlatform::save_zip_patch(const Ref<EditorExportPreset> &p_pres
21892194

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

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

@@ -2203,6 +2210,7 @@ Error EditorExportPlatform::export_pack_patch(const Ref<EditorExportPreset> &p_p
22032210
if (err != OK) {
22042211
return err;
22052212
}
2213+
check_disk_space(p_path);
22062214
err = save_pack_patch(p_preset, p_debug, p_path);
22072215
_unload_patches();
22082216
return err;
@@ -2214,6 +2222,7 @@ Error EditorExportPlatform::export_zip_patch(const Ref<EditorExportPreset> &p_pr
22142222
if (err != OK) {
22152223
return err;
22162224
}
2225+
check_disk_space(p_path);
22172226
err = save_zip_patch(p_preset, p_debug, p_path);
22182227
_unload_patches();
22192228
return err;

editor/export/editor_export_platform.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ class EditorExportPlatform : public RefCounted {
231231
virtual Ref<EditorExportPreset> create_preset();
232232
virtual bool is_executable(const String &p_path) const { return false; }
233233

234+
void check_disk_space(const String &p_path) const;
235+
234236
virtual void clear_messages() { messages.clear(); }
235237
virtual void add_message(ExportMessageType p_type, const String &p_category, const String &p_message) {
236238
ExportMessage msg;

editor/export/editor_export_platform_extension.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ List<String> EditorExportPlatformExtension::get_binary_extensions(const Ref<Edit
267267

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

271272
Error ret = FAILED;
272273
GDVIRTUAL_CALL(_export_project, p_preset, p_debug, p_path, p_flags, ret);

editor/export/editor_export_platform_pc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ bool EditorExportPlatformPC::has_valid_project_configuration(const Ref<EditorExp
117117

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

121122
Error err = prepare_template(p_preset, p_debug, p_path, p_flags);
122123
if (err == OK) {

editor/export/export_template_manager.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ void ExportTemplateManager::_download_current() {
159159
}
160160
is_downloading_templates = true;
161161

162+
// Decompressed official export templates are typically around 2 GiB on disk.
163+
// However, the compressed file has to stay on disk until the export templates are done extracting,
164+
// so we also need to account for its compressed size on top.
165+
EditorNode::get_singleton()->check_disk_space(
166+
EditorPaths::get_singleton()->get_data_dir(),
167+
4.0,
168+
TTR("Downloading export templates will fail if the disk runs out of space."));
169+
162170
install_options_vb->hide();
163171
download_progress_hb->show();
164172

@@ -425,6 +433,12 @@ void ExportTemplateManager::_install_file() {
425433
}
426434

427435
bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_skip_progress) {
436+
// Decompressed official export templates are typically around 2 GiB on disk.
437+
EditorNode::get_singleton()->check_disk_space(
438+
EditorPaths::get_singleton()->get_data_dir(),
439+
4.0,
440+
TTR("Installing export templates will fail if the disk runs out of space."));
441+
428442
Ref<FileAccess> io_fa;
429443
zlib_filefunc_def io = zipio_create_io(&io_fa);
430444

editor/export/project_zip_packer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ String ProjectZIPPacker::get_project_zip_safe_name() {
5050
}
5151

5252
void ProjectZIPPacker::pack_project_zip(const String &p_path) {
53+
// Project files can grow quite large, so check for a reasonable amount of available space before packing.
54+
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."));
55+
5356
Ref<FileAccess> io_fa;
5457
zlib_filefunc_def io = zipio_create_io(&io_fa);
5558

platform/android/export/export_plugin.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3337,6 +3337,7 @@ bool EditorExportPlatformAndroid::_is_clean_build_required(const Ref<EditorExpor
33373337
Error EditorExportPlatformAndroid::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) {
33383338
int export_format = int(p_preset->get("gradle_build/export_format"));
33393339
bool should_sign = p_preset->get("package/signed");
3340+
check_disk_space(p_path);
33403341
return export_project_helper(p_preset, p_debug, p_path, export_format, should_sign, p_flags);
33413342
}
33423343

0 commit comments

Comments
 (0)