void EditorFileSystem::scan_sources() { if (scanning || scanning_sources|| thread) return; sources_changed.clear(); scanning_sources=true; scanning_sources_done=false; abort_scan=false; if (!use_threads) { if (filesystem) { EditorProgressBG pr("sources","ScanSources",1000); ScanProgress sp; sp.progress=≺ sp.hi=1; sp.low=0; scan_total=0; _scan_fs_changes(filesystem,sp); if (_update_scan_actions()) emit_signal("filesystem_changed"); } scanning_sources=false; scanning_sources_done=true; emit_signal("sources_changed",sources_changed.size()>0); } else { ERR_FAIL_COND(thread_sources); set_process(true); scan_total=0; Thread::Settings s; s.priority=Thread::PRIORITY_LOW; thread_sources = Thread::create(_thread_func_sources,this,s); //tree->hide(); //print_line("SCAN BEGIN!"); //progress->show(); } }
void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const ScanProgress& p_progress) { uint64_t current_mtime = FileAccess::get_modified_time(p_dir->get_path()); bool updated_dir=false; //print_line("dir: "+p_dir->get_path()+" MODTIME: "+itos(p_dir->modified_time)+" CTIME: "+itos(current_mtime)); if (current_mtime!=p_dir->modified_time) { updated_dir=true; p_dir->modified_time=current_mtime; //ooooops, dir changed, see what's going on //first mark everything as veryfied for(int i=0;i<p_dir->files.size();i++) { p_dir->files[i]->verified=false; } for(int i=0;i<p_dir->subdirs.size();i++) { p_dir->get_subdir(i)->verified=false; } //then scan files and directories and check what's different DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); String cd = p_dir->get_path(); da->change_dir(cd); da->list_dir_begin(); while (true) { bool isdir; String f = da->get_next(&isdir); if (f=="") break; if (isdir) { if (f.begins_with(".")) //ignore hidden and . / .. continue; int idx = p_dir->find_dir_index(f); if (idx==-1) { if (FileAccess::exists(cd.plus_file(f).plus_file("engine.cfg"))) // skip if another project inside this continue; EditorFileSystemDirectory *efd = memnew( EditorFileSystemDirectory ); efd->parent=p_dir; efd->name=f; DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES); d->change_dir(cd.plus_file(f)); _scan_new_dir(efd,d,p_progress.get_sub(1,1)); memdelete(d); ItemAction ia; ia.action=ItemAction::ACTION_DIR_ADD; ia.dir=p_dir; ia.file=f; ia.new_dir=efd; scan_actions.push_back(ia); } else { p_dir->subdirs[idx]->verified=true; } } else { String ext = f.extension().to_lower(); if (!valid_extensions.has(ext)) continue; //invalid int idx = p_dir->find_file_index(f); if (idx==-1) { //never seen this file, add actition to add it EditorFileSystemDirectory::FileInfo *fi = memnew( EditorFileSystemDirectory::FileInfo ); fi->file=f; String path = cd.plus_file(fi->file); fi->modified_time=FileAccess::get_modified_time(path); fi->meta=_get_meta(path); fi->type=ResourceLoader::get_resource_type(path); { ItemAction ia; ia.action=ItemAction::ACTION_FILE_ADD; ia.dir=p_dir; ia.file=f; ia.new_file=fi; scan_actions.push_back(ia); } //take the chance and scan sources if (_check_meta_sources(fi->meta)) { ItemAction ia; ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED; ia.dir=p_dir; ia.file=f; scan_actions.push_back(ia); } } else { p_dir->files[idx]->verified=true; } } } da->list_dir_end(); memdelete(da); } for(int i=0;i<p_dir->files.size();i++) { if (updated_dir && !p_dir->files[i]->verified) { //this file was removed, add action to remove it ItemAction ia; ia.action=ItemAction::ACTION_FILE_REMOVE; ia.dir=p_dir; ia.file=p_dir->files[i]->file; scan_actions.push_back(ia); continue; } if (_check_meta_sources(p_dir->files[i]->meta)) { ItemAction ia; ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED; ia.dir=p_dir; ia.file=p_dir->files[i]->file; scan_actions.push_back(ia); } } for(int i=0;i<p_dir->subdirs.size();i++) { if (updated_dir && !p_dir->subdirs[i]->verified) { //this directory was removed, add action to remove it ItemAction ia; ia.action=ItemAction::ACTION_DIR_REMOVE; ia.dir=p_dir->subdirs[i]; scan_actions.push_back(ia); continue; } _scan_fs_changes(p_dir->get_subdir(i),p_progress); } }
void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const ScanProgress &p_progress) { uint64_t current_mtime = FileAccess::get_modified_time(p_dir->get_path()); bool updated_dir = false; String cd = p_dir->get_path(); //print_line("dir: "+p_dir->get_path()+" MODTIME: "+itos(p_dir->modified_time)+" CTIME: "+itos(current_mtime)); if (current_mtime != p_dir->modified_time) { updated_dir = true; p_dir->modified_time = current_mtime; //ooooops, dir changed, see what's going on //first mark everything as veryfied for (int i = 0; i < p_dir->files.size(); i++) { p_dir->files[i]->verified = false; } for (int i = 0; i < p_dir->subdirs.size(); i++) { p_dir->get_subdir(i)->verified = false; } //then scan files and directories and check what's different DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); da->change_dir(cd); da->list_dir_begin(); while (true) { bool isdir; String f = da->get_next(&isdir); if (f == "") break; if (isdir) { if (f.begins_with(".")) //ignore hidden and . / .. continue; int idx = p_dir->find_dir_index(f); if (idx == -1) { if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) // skip if another project inside this continue; if (FileAccess::exists(cd.plus_file(f).plus_file(".gdignore"))) // skip if another project inside this continue; EditorFileSystemDirectory *efd = memnew(EditorFileSystemDirectory); efd->parent = p_dir; efd->name = f; DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES); d->change_dir(cd.plus_file(f)); _scan_new_dir(efd, d, p_progress.get_sub(1, 1)); memdelete(d); ItemAction ia; ia.action = ItemAction::ACTION_DIR_ADD; ia.dir = p_dir; ia.file = f; ia.new_dir = efd; scan_actions.push_back(ia); } else { p_dir->subdirs[idx]->verified = true; } } else { String ext = f.get_extension().to_lower(); if (!valid_extensions.has(ext)) continue; //invalid int idx = p_dir->find_file_index(f); if (idx == -1) { //never seen this file, add actition to add it EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo); fi->file = f; String path = cd.plus_file(fi->file); fi->modified_time = FileAccess::get_modified_time(path); fi->import_modified_time = 0; fi->type = ResourceLoader::get_resource_type(path); { ItemAction ia; ia.action = ItemAction::ACTION_FILE_ADD; ia.dir = p_dir; ia.file = f; ia.new_file = fi; scan_actions.push_back(ia); } if (import_extensions.has(ext)) { //if it can be imported, and it was added, it needs to be reimported print_line("REIMPORT: file was not found before, reimport"); print_line("at dir: " + p_dir->get_path() + " file: " + f); for (int i = 0; i < p_dir->files.size(); i++) { print_line(itos(i) + ": " + p_dir->files[i]->file); } ItemAction ia; ia.action = ItemAction::ACTION_FILE_REIMPORT; ia.dir = p_dir; ia.file = f; scan_actions.push_back(ia); } } else { p_dir->files[idx]->verified = true; } } } da->list_dir_end(); memdelete(da); } for (int i = 0; i < p_dir->files.size(); i++) { if (updated_dir && !p_dir->files[i]->verified) { //this file was removed, add action to remove it ItemAction ia; ia.action = ItemAction::ACTION_FILE_REMOVE; ia.dir = p_dir; ia.file = p_dir->files[i]->file; scan_actions.push_back(ia); continue; } if (import_extensions.has(p_dir->files[i]->file.get_extension().to_lower())) { //check here if file must be imported or not String path = cd.plus_file(p_dir->files[i]->file); uint64_t mt = FileAccess::get_modified_time(path); bool reimport = false; if (mt != p_dir->files[i]->modified_time) { print_line("REIMPORT: modified time changed, reimport"); reimport = true; //it was modified, must be reimported. } else if (!FileAccess::exists(path + ".import")) { print_line("REIMPORT: no .import exists, reimport"); reimport = true; //no .import file, obviously reimport } else { uint64_t import_mt = FileAccess::get_modified_time(path + ".import"); //print_line(itos(import_mt) + " vs " + itos(p_dir->files[i]->import_modified_time)); if (import_mt != p_dir->files[i]->import_modified_time) { print_line("REIMPORT: import modified changed, reimport"); reimport = true; } else if (!_check_missing_imported_files(path)) { print_line("REIMPORT: imported files removed"); reimport = true; } } if (reimport) { ItemAction ia; ia.action = ItemAction::ACTION_FILE_REIMPORT; ia.dir = p_dir; ia.file = p_dir->files[i]->file; scan_actions.push_back(ia); } } EditorResourcePreview::get_singleton()->check_for_invalidation(p_dir->get_file_path(i)); } for (int i = 0; i < p_dir->subdirs.size(); i++) { if (updated_dir && !p_dir->subdirs[i]->verified) { //this directory was removed, add action to remove it ItemAction ia; ia.action = ItemAction::ACTION_DIR_REMOVE; ia.dir = p_dir->subdirs[i]; scan_actions.push_back(ia); continue; } _scan_fs_changes(p_dir->get_subdir(i), p_progress); } }