From d1808f0a7f2ce5bed1ad6663e3afc262918100c5 Mon Sep 17 00:00:00 2001 From: Fredia Huya-Kouadio Date: Fri, 10 Sep 2021 10:52:41 -0700 Subject: [PATCH] Make the project data directory customizable. --- core/project_settings.cpp | 10 +++++-- core/project_settings.h | 2 ++ doc/classes/EditorImportPlugin.xml | 4 +-- doc/classes/ProjectSettings.xml | 15 ++++++---- editor/editor_file_dialog.cpp | 2 +- editor/editor_file_system.cpp | 48 +++++++++++++++++++----------- editor/editor_file_system.h | 1 + editor/find_in_files.cpp | 2 +- 8 files changed, 55 insertions(+), 29 deletions(-) diff --git a/core/project_settings.cpp b/core/project_settings.cpp index ed35a1c555e..79867d80089 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -50,12 +50,11 @@ ProjectSettings *ProjectSettings::get_singleton() { } String ProjectSettings::get_project_data_dir_name() const { - return ".import"; + return project_data_dir_name; } String ProjectSettings::get_project_data_path() const { - String project_data_dir_name = get_project_data_dir_name(); - return "res://" + project_data_dir_name; + return "res://" + get_project_data_dir_name(); } String ProjectSettings::get_resource_path() const { @@ -488,6 +487,10 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo _load_settings_text(custom_settings); } } + + // Updating the default value after the project settings have loaded. + project_data_dir_name = GLOBAL_GET("application/config/project_data_dir_name"); + // Using GLOBAL_GET on every block for compressing can be slow, so assigning here. Compression::zstd_long_distance_matching = GLOBAL_GET("compression/formats/zstd/long_distance_matching"); Compression::zstd_level = GLOBAL_GET("compression/formats/zstd/compression_level"); @@ -1035,6 +1038,7 @@ ProjectSettings::ProjectSettings() { custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "*.tscn,*.scn,*.res"); GLOBAL_DEF("application/run/disable_stdout", false); GLOBAL_DEF("application/run/disable_stderr", false); + project_data_dir_name = GLOBAL_DEF_RST("application/config/project_data_dir_name", ".import"); GLOBAL_DEF("application/config/use_custom_user_dir", false); GLOBAL_DEF("application/config/custom_user_dir_name", ""); GLOBAL_DEF("application/config/project_settings_override", ""); diff --git a/core/project_settings.h b/core/project_settings.h index 3792c155daf..c6214eba84f 100644 --- a/core/project_settings.h +++ b/core/project_settings.h @@ -91,6 +91,8 @@ protected: Set custom_features; Map feature_overrides; + String project_data_dir_name; + bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List *p_list) const; diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index c8d2975b2ae..89902fabd13 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -5,7 +5,7 @@ EditorImportPlugins provide a way to extend the editor's resource import functionality. Use them to import resources from custom files or to provide alternatives to the editor's existing importers. Register your [EditorPlugin] with [method EditorPlugin.add_import_plugin]. - EditorImportPlugins work by associating with specific file extensions and a resource type. See [method get_recognized_extensions] and [method get_resource_type]. They may optionally specify some import presets that affect the import process. EditorImportPlugins are responsible for creating the resources and saving them in the [code].import[/code] directory. + EditorImportPlugins work by associating with specific file extensions and a resource type. See [method get_recognized_extensions] and [method get_resource_type]. They may optionally specify some import presets that affect the import process. EditorImportPlugins are responsible for creating the resources and saving them in the [code].import[/code] directory (see [member ProjectSettings.application/config/project_data_dir_name]). Below is an example EditorImportPlugin that imports a [Mesh] from a file with the extension ".special" or ".spec": [codeblock] tool @@ -121,7 +121,7 @@ - Gets the extension used to save this resource in the [code].import[/code] directory. + Gets the extension used to save this resource in the [code].import[/code] directory (see [member ProjectSettings.application/config/project_data_dir_name]). diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 5deed7df162..815649ae0a9 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -200,6 +200,11 @@ The project's name. It is used both by the Project Manager and by exporters. The project name can be translated by translating its value in localization files. The window title will be set to match the project name automatically on startup. [b]Note:[/b] Changing this value will also change the user data folder's path if [member application/config/use_custom_user_dir] is [code]false[/code]. After renaming the project, you will no longer be able to access existing data in [code]user://[/code] unless you rename the old folder to match the new project name. See [url=https://docs.godotengine.org/en/3.4/tutorials/io/data_paths.html]Data paths[/url] in the documentation for more information. + + The project data directory is used for storing project-specific data (metadata, shader cache, etc.). + [b]Note:[/b] Restart the application after changing this setting. + [b]Note:[/b] Changing this value can help on platforms or with third-party tools where specific directory patterns are disallowed. Only modify this setting if you know that your environment requires it, as changing the default can impact compatibility with some external tools or plugins which expect the default [code].import[/code] folder. + Specifies a file to override project settings. For example: [code]user://custom_settings.cfg[/code]. See "Overriding" in the [ProjectSettings] class description at the top for more information. [b]Note:[/b] Regardless of this setting's value, [code]res://override.cfg[/code] will still be read to override the project settings. @@ -1450,23 +1455,23 @@ If [code]true[/code], the texture importer will import VRAM-compressed textures using the BPTC algorithm. This texture compression algorithm is only supported on desktop platforms, and only when using the GLES3 renderer. - [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].import/[/code] folder located inside the project folder then restart the editor. + [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].import/[/code] folder located inside the project folder then restart the editor (see [member application/config/project_data_dir_name]). If [code]true[/code], the texture importer will import VRAM-compressed textures using the Ericsson Texture Compression algorithm. This algorithm doesn't support alpha channels in textures. - [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].import/[/code] folder located inside the project folder then restart the editor. + [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].import/[/code] folder located inside the project folder then restart the editor (see [member application/config/project_data_dir_name]). If [code]true[/code], the texture importer will import VRAM-compressed textures using the Ericsson Texture Compression 2 algorithm. This texture compression algorithm is only supported when using the GLES3 renderer. - [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].import/[/code] folder located inside the project folder then restart the editor. + [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].import/[/code] folder located inside the project folder then restart the editor (see [member application/config/project_data_dir_name]). If [code]true[/code], the texture importer will import VRAM-compressed textures using the PowerVR Texture Compression algorithm. This texture compression algorithm is only supported on iOS. - [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].import/[/code] folder located inside the project folder then restart the editor. + [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].import/[/code] folder located inside the project folder then restart the editor (see [member application/config/project_data_dir_name]). If [code]true[/code], the texture importer will import VRAM-compressed textures using the S3 Texture Compression algorithm. This algorithm is only supported on desktop platforms and consoles. - [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].import/[/code] folder located inside the project folder then restart the editor. + [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].import/[/code] folder located inside the project folder then restart the editor (see [member application/config/project_data_dir_name]). Cell size used for the 2D hash grid that [VisibilityNotifier2D] uses (in pixels). diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 217ea790d02..bec3080a84c 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -568,7 +568,7 @@ void EditorFileDialog::_item_list_item_rmb_selected(int p_item, const Vector2 &p continue; } Dictionary item_meta = item_list->get_item_metadata(i); - if (item_meta["path"] == ProjectSettings::get_singleton()->get_project_data_path()) { + if (String(item_meta["path"]).begins_with(ProjectSettings::get_singleton()->get_project_data_path())) { allow_delete = false; break; } diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 483dd8f5ed8..5ac98a12d32 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1887,19 +1887,35 @@ void EditorFileSystem::_find_group_files(EditorFileSystemDirectory *efd, Map &p_files) { - { //check that the project data folder exists - String project_data_dir_name = ProjectSettings::get_singleton()->get_project_data_dir_name(); - DirAccess *da = DirAccess::open("res://"); - if (da->change_dir(project_data_dir_name) != OK) { - Error err = da->make_dir(project_data_dir_name); - if (err) { - memdelete(da); - ERR_FAIL_MSG("Failed to create folder res://" + project_data_dir_name); - } +void EditorFileSystem::_create_project_data_dir_if_necessary() { + // Check that the project data directory exists + DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + String project_data_path = ProjectSettings::get_singleton()->get_project_data_path(); + if (da->change_dir(project_data_path) != OK) { + Error err = da->make_dir(project_data_path); + if (err) { + memdelete(da); + ERR_FAIL_MSG("Failed to create folder " + project_data_path); } - memdelete(da); } + memdelete(da); + + // Check that the project data directory '.gdignore' file exists + String project_data_gdignore_file_path = project_data_path.plus_file(".gdignore"); + if (!FileAccess::exists(project_data_gdignore_file_path)) { + // Add an empty .gdignore file to avoid scan. + FileAccessRef f = FileAccess::open(project_data_gdignore_file_path, FileAccess::WRITE); + if (f) { + f->store_line(""); + f->close(); + } else { + ERR_FAIL_MSG("Failed to create file " + project_data_gdignore_file_path); + } + } +} + +void EditorFileSystem::reimport_files(const Vector &p_files) { + _create_project_data_dir_if_necessary(); importing = true; EditorProgress pr("reimport", TTR("(Re)Importing Assets"), p_files.size()); @@ -1974,7 +1990,7 @@ Error EditorFileSystem::_resource_import(const String &p_path) { } bool EditorFileSystem::_should_skip_directory(const String &p_path) { - if (p_path == ProjectSettings::get_singleton()->get_project_data_path()) { + if (p_path.begins_with(ProjectSettings::get_singleton()->get_project_data_path())) { return true; } @@ -2092,12 +2108,10 @@ EditorFileSystem::EditorFileSystem() { scanning_changes = false; scanning_changes_done = false; - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - String project_data_path = ProjectSettings::get_singleton()->get_project_data_path(); - if (da->change_dir(project_data_path) != OK) { - da->make_dir(project_data_path); - } + _create_project_data_dir_if_necessary(); + // This should probably also work on Unix and use the string it returns for FAT32 or exFAT + DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); using_fat32_or_exfat = (da->get_filesystem_type() == "FAT32" || da->get_filesystem_type() == "exFAT"); memdelete(da); diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index 699cd35bcda..4f2df6b0b7a 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -193,6 +193,7 @@ class EditorFileSystem : public Node { void _scan_fs_changes(EditorFileSystemDirectory *p_dir, const ScanProgress &p_progress); + void _create_project_data_dir_if_necessary(); void _delete_internal_files(String p_file); Set valid_extensions; diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index c30dc435182..c8b97ee87ff 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -240,7 +240,7 @@ void FindInFiles::_scan_dir(String path, PoolStringArray &out_folders) { // Ignore special dirs (such as .git and project data directory) String project_data_dir_name = ProjectSettings::get_singleton()->get_project_data_dir_name(); - if (file.begins_with(".") || file == project_data_dir_name) { + if (file.begins_with(".") || file.begins_with(project_data_dir_name)) { continue; } if (dir->current_is_hidden()) {