Skip to content

Commit

Permalink
Implement groups caching
Browse files Browse the repository at this point in the history
  • Loading branch information
DarkMessiah committed Nov 9, 2023
1 parent 077a93d commit cf72d13
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 84 deletions.
51 changes: 51 additions & 0 deletions core/config/project_settings.cpp
Expand Up @@ -682,6 +682,8 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo

Compression::gzip_level = GLOBAL_GET("compression/formats/gzip/compression_level");

load_scene_groups_cache();

project_loaded = err == OK;
return err;
}
Expand Down Expand Up @@ -1266,6 +1268,55 @@ bool ProjectSettings::has_global_group(const StringName &p_name) const {
return global_groups.has(p_name);
}

void ProjectSettings::remove_scene_groups_cache(const StringName &p_path) {
scene_groups_cache.erase(p_path);
}

void ProjectSettings::add_scene_groups_cache(const StringName &p_path, const HashSet<StringName> &p_cache) {
scene_groups_cache[p_path] = p_cache;
}

void ProjectSettings::save_scene_groups_cache() {
Ref<ConfigFile> cf;
cf.instantiate();
for (const KeyValue<StringName, HashSet<StringName>> &E : scene_groups_cache) {
if (E.value.is_empty()) {
continue;
}
Array list;
for (const StringName &group : E.value) {
list.push_back(group);
}
cf->set_value(E.key, "groups", list);
}
cf->save(get_scene_groups_cache_path());
}

String ProjectSettings::get_scene_groups_cache_path() const {
return get_project_data_path().path_join("scene_groups_cache.cfg");
}

void ProjectSettings::load_scene_groups_cache() {
Ref<ConfigFile> cf;
cf.instantiate();
if (cf->load(get_scene_groups_cache_path()) == OK) {
List<String> scene_paths;
cf->get_sections(&scene_paths);
for (const String &E : scene_paths) {
Array scene_groups = cf->get_value(E, "groups", Array());
HashSet<StringName> cache;
for (int i = 0; i < scene_groups.size(); ++i) {
cache.insert(scene_groups[i]);
}
add_scene_groups_cache(E, cache);
}
}
}

const HashMap<StringName, HashSet<StringName>> &ProjectSettings::get_scene_groups_cache() const {
return scene_groups_cache;
}

void ProjectSettings::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_setting", "name"), &ProjectSettings::has_setting);
ClassDB::bind_method(D_METHOD("set_setting", "name", "value"), &ProjectSettings::set_setting);
Expand Down
8 changes: 8 additions & 0 deletions core/config/project_settings.h
Expand Up @@ -107,6 +107,7 @@ class ProjectSettings : public Object {
LocalVector<String> hidden_prefixes;
HashMap<StringName, AutoloadInfo> autoloads;
HashMap<StringName, String> global_groups;
HashMap<StringName, HashSet<StringName>> scene_groups_cache;

Array global_class_list;
bool is_global_class_list_loaded = false;
Expand Down Expand Up @@ -214,6 +215,13 @@ class ProjectSettings : public Object {
void remove_global_group(const StringName &p_name);
bool has_global_group(const StringName &p_name) const;

const HashMap<StringName, HashSet<StringName>> &get_scene_groups_cache() const;
void add_scene_groups_cache(const StringName &p_path, const HashSet<StringName> &p_cache);
void remove_scene_groups_cache(const StringName &p_path);
void save_scene_groups_cache();
String get_scene_groups_cache_path() const;
void load_scene_groups_cache();

ProjectSettings();
~ProjectSettings();
};
Expand Down
85 changes: 85 additions & 0 deletions editor/editor_file_system.cpp
Expand Up @@ -44,6 +44,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_settings.h"
#include "scene/resources/packed_scene.h"

EditorFileSystem *EditorFileSystem::singleton = nullptr;
//the name is the version, to keep compatibility with different versions of Godot
Expand Down Expand Up @@ -614,6 +615,9 @@ bool EditorFileSystem::_update_scan_actions() {
if (ClassDB::is_parent_class(ia.new_file->type, SNAME("Script"))) {
_queue_update_script_class(ia.dir->get_file_path(idx));
}
if (ia.new_file->type == SNAME("PackedScene")) {
_queue_update_scene_groups(ia.dir->get_file_path(idx));
}

} break;
case ItemAction::ACTION_FILE_REMOVE: {
Expand All @@ -623,6 +627,9 @@ bool EditorFileSystem::_update_scan_actions() {
if (ClassDB::is_parent_class(ia.dir->files[idx]->type, SNAME("Script"))) {
_queue_update_script_class(ia.dir->get_file_path(idx));
}
if (ia.dir->files[idx]->type == SNAME("PackedScene")) {
_queue_update_scene_groups(ia.dir->get_file_path(idx));
}

_delete_internal_files(ia.dir->files[idx]->file);
memdelete(ia.dir->files[idx]);
Expand Down Expand Up @@ -661,6 +668,9 @@ bool EditorFileSystem::_update_scan_actions() {
if (ClassDB::is_parent_class(ia.dir->files[idx]->type, SNAME("Script"))) {
_queue_update_script_class(full_path);
}
if (ia.dir->files[idx]->type == SNAME("PackedScene")) {
_queue_update_scene_groups(full_path);
}

reloads.push_back(full_path);

Expand Down Expand Up @@ -731,6 +741,7 @@ void EditorFileSystem::scan() {
_update_scan_actions();
scanning = false;
_update_pending_script_classes();
_update_pending_scene_groups();
emit_signal(SNAME("filesystem_changed"));
emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
first_scan = false;
Expand Down Expand Up @@ -941,6 +952,9 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref<DirAc
if (ClassDB::is_parent_class(fi->type, SNAME("Script"))) {
_queue_update_script_class(path);
}
if (fi->type == SNAME("PackedScene")) {
_queue_update_scene_groups(path);
}
}
}

Expand Down Expand Up @@ -1195,6 +1209,7 @@ void EditorFileSystem::scan_changes() {
_scan_fs_changes(filesystem, sp);
bool changed = _update_scan_actions();
_update_pending_script_classes();
_update_pending_scene_groups();
if (changed) {
emit_signal(SNAME("filesystem_changed"));
}
Expand Down Expand Up @@ -1261,6 +1276,7 @@ void EditorFileSystem::_notification(int p_what) {
}
bool changed = _update_scan_actions();
_update_pending_script_classes();
_update_pending_scene_groups();
if (changed) {
emit_signal(SNAME("filesystem_changed"));
}
Expand All @@ -1280,6 +1296,7 @@ void EditorFileSystem::_notification(int p_what) {
thread.wait_to_finish();
_update_scan_actions();
_update_pending_script_classes();
_update_pending_scene_groups();
emit_signal(SNAME("filesystem_changed"));
emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
first_scan = false;
Expand Down Expand Up @@ -1634,6 +1651,65 @@ void EditorFileSystem::_queue_update_script_class(const String &p_path) {
update_script_mutex.unlock();
}

void EditorFileSystem::_update_scene_groups() {
update_scene_mutex.lock();

for (const String &path : update_scene_paths) {
ProjectSettings::get_singleton()->remove_scene_groups_cache(path);

int index = -1;
EditorFileSystemDirectory *efd = find_file(path, &index);

if (!efd || index < 0) {
// The file was removed.
continue;
}

const HashSet<StringName> scene_groups = _get_scene_groups(path);
if (!scene_groups.is_empty()) {
ProjectSettings::get_singleton()->add_scene_groups_cache(path, scene_groups);
}
}

update_scene_paths.clear();
update_scene_mutex.unlock();

ProjectSettings::get_singleton()->save_scene_groups_cache();
}

void EditorFileSystem::_update_pending_scene_groups() {
if (!FileAccess::exists(ProjectSettings::get_singleton()->get_scene_groups_cache_path())) {
_get_all_scenes(get_filesystem(), update_scene_paths);
_update_scene_groups();
} else if (!update_scene_paths.is_empty()) {
_update_scene_groups();
}
}

void EditorFileSystem::_queue_update_scene_groups(const String &p_path) {
update_scene_mutex.lock();
update_scene_paths.insert(p_path);
update_scene_mutex.unlock();
}

void EditorFileSystem::_get_all_scenes(EditorFileSystemDirectory *p_dir, HashSet<String> &r_list) {
for (int i = 0; i < p_dir->get_file_count(); i++) {
if (p_dir->get_file_type(i) == SNAME("PackedScene")) {
r_list.insert(p_dir->get_file_path(i));
}
}

for (int i = 0; i < p_dir->get_subdir_count(); i++) {
_get_all_scenes(p_dir->get_subdir(i), r_list);
}
}

HashSet<StringName> EditorFileSystem::_get_scene_groups(const String &p_path) {
Ref<PackedScene> packed_scene = ResourceLoader::load(p_path);
ERR_FAIL_COND_V(packed_scene.is_null(), HashSet<StringName>());
return packed_scene->get_state()->get_all_groups();
}

void EditorFileSystem::update_file(const String &p_file) {
ERR_FAIL_COND(p_file.is_empty());
EditorFileSystemDirectory *fs = nullptr;
Expand All @@ -1657,12 +1733,16 @@ void EditorFileSystem::update_file(const String &p_file) {
if (ClassDB::is_parent_class(fs->files[cpos]->type, SNAME("Script"))) {
_queue_update_script_class(p_file);
}
if (fs->files[cpos]->type == SNAME("PackedScene")) {
_queue_update_scene_groups(p_file);
}

memdelete(fs->files[cpos]);
fs->files.remove_at(cpos);
}

_update_pending_script_classes();
_update_pending_scene_groups();
call_deferred(SNAME("emit_signal"), "filesystem_changed"); //update later
return;
}
Expand Down Expand Up @@ -1729,8 +1809,12 @@ void EditorFileSystem::update_file(const String &p_file) {
if (ClassDB::is_parent_class(fs->files[cpos]->type, SNAME("Script"))) {
_queue_update_script_class(p_file);
}
if (fs->files[cpos]->type == SNAME("PackedScene")) {
_queue_update_scene_groups(p_file);
}

_update_pending_script_classes();
_update_pending_scene_groups();
call_deferred(SNAME("emit_signal"), "filesystem_changed"); //update later
}

Expand Down Expand Up @@ -2337,6 +2421,7 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {

_save_filesystem_cache();
_update_pending_script_classes();
_update_pending_scene_groups();
importing = false;
if (!is_scanning()) {
emit_signal(SNAME("filesystem_changed"));
Expand Down
8 changes: 8 additions & 0 deletions editor/editor_file_system.h
Expand Up @@ -267,6 +267,14 @@ class EditorFileSystem : public Node {
void _update_script_classes();
void _update_pending_script_classes();

Mutex update_scene_mutex;
HashSet<String> update_scene_paths;
void _queue_update_scene_groups(const String &p_path);
void _update_scene_groups();
void _update_pending_scene_groups();
HashSet<StringName> _get_scene_groups(const String &p_path);
void _get_all_scenes(EditorFileSystemDirectory *p_dir, HashSet<String> &r_list);

String _get_global_script_class(const String &p_type, const String &p_path, String *r_extends, String *r_icon_path) const;

static Error _resource_import(const String &p_path);
Expand Down

0 comments on commit cf72d13

Please sign in to comment.