Пример #1
0
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);
	}

}
Пример #2
0
void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess *da,const ScanProgress& p_progress) {

	List<String> dirs;
	List<String> files;

	String cd = da->get_current_dir();

	p_dir->modified_time = FileAccess::get_modified_time(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;

			if (FileAccess::exists(cd.plus_file(f).plus_file("engine.cfg"))) // skip if another project inside this
				continue;

			dirs.push_back(f);

		} else {

			files.push_back(f);
		}

	}

	da->list_dir_end();

	dirs.sort();
	files.sort();

	int total = dirs.size()+files.size();
	int idx=0;

	for (List<String>::Element *E=dirs.front();E;E=E->next(),idx++) {

		if (da->change_dir(E->get())==OK) {

			EditorFileSystemDirectory *efd = memnew( EditorFileSystemDirectory );

			efd->parent=p_dir;
			efd->name=E->get();

			_scan_new_dir(efd,da,p_progress.get_sub(idx,total));

			int idx=0;
			for(int i=0;i<p_dir->subdirs.size();i++) {

				if (efd->name<p_dir->subdirs[i]->name)
					break;
				idx++;
			}
			if (idx==p_dir->subdirs.size()) {
				p_dir->subdirs.push_back(efd);
			} else {
				p_dir->subdirs.insert(idx,efd);
			}

			da->change_dir("..");
		} else {
			ERR_PRINTS("Can't go into subdir: "+E->get());
		}

		p_progress.update(idx,total);

	}

	for (List<String>::Element*E=files.front();E;E=E->next(),idx++) {

		String ext = E->get().extension().to_lower();
		if (!valid_extensions.has(ext))
			continue; //invalid

		EditorFileSystemDirectory::FileInfo *fi = memnew( EditorFileSystemDirectory::FileInfo );
		fi->file=E->get();

		String path = cd.plus_file(fi->file);

		FileCache *fc = file_cache.getptr(path);
		uint64_t mt = FileAccess::get_modified_time(path);

		if (fc && fc->modification_time == mt) {

			fi->meta=fc->meta;
			fi->type=fc->type;
			fi->modified_time=fc->modification_time;
		} else {
			fi->meta=_get_meta(path);
			fi->type=ResourceLoader::get_resource_type(path);
			fi->modified_time=mt;

		}

		if (fi->meta.enabled) {
			if (_check_meta_sources(fi->meta)) {
				ItemAction ia;
				ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED;
				ia.dir=p_dir;
				ia.file=E->get();
				scan_actions.push_back(ia);
			}
		}

		p_dir->files.push_back(fi);
		p_progress.update(idx,total);
	}

}
Пример #3
0
void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess *da, const ScanProgress &p_progress) {

	List<String> dirs;
	List<String> files;

	String cd = da->get_current_dir();

	p_dir->modified_time = FileAccess::get_modified_time(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;

			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;

			dirs.push_back(f);

		} else {

			files.push_back(f);
		}
	}

	da->list_dir_end();

	dirs.sort_custom<NaturalNoCaseComparator>();
	files.sort_custom<NaturalNoCaseComparator>();

	int total = dirs.size() + files.size();
	int idx = 0;

	for (List<String>::Element *E = dirs.front(); E; E = E->next(), idx++) {

		if (da->change_dir(E->get()) == OK) {

			String d = da->get_current_dir();

			if (d == cd || !d.begins_with(cd)) {
				da->change_dir(cd); //avoid recursion
			} else {

				EditorFileSystemDirectory *efd = memnew(EditorFileSystemDirectory);

				efd->parent = p_dir;
				efd->name = E->get();

				_scan_new_dir(efd, da, p_progress.get_sub(idx, total));

				int idx = 0;
				for (int i = 0; i < p_dir->subdirs.size(); i++) {

					if (efd->name < p_dir->subdirs[i]->name)
						break;
					idx++;
				}
				if (idx == p_dir->subdirs.size()) {
					p_dir->subdirs.push_back(efd);
				} else {
					p_dir->subdirs.insert(idx, efd);
				}

				da->change_dir("..");
			}
		} else {
			ERR_PRINTS("Cannot go into subdir: " + E->get());
		}

		p_progress.update(idx, total);
	}

	for (List<String>::Element *E = files.front(); E; E = E->next(), idx++) {

		String ext = E->get().get_extension().to_lower();
		if (!valid_extensions.has(ext)) {
			continue; //invalid
		}

		EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo);
		fi->file = E->get();

		String path = cd.plus_file(fi->file);

		FileCache *fc = file_cache.getptr(path);
		uint64_t mt = FileAccess::get_modified_time(path);

		if (import_extensions.has(ext)) {

			//is imported
			uint64_t import_mt = 0;
			if (FileAccess::exists(path + ".import")) {
				import_mt = FileAccess::get_modified_time(path + ".import");
			}

			if (fc && fc->modification_time == mt && fc->import_modification_time == import_mt && _check_missing_imported_files(path)) {

				fi->type = fc->type;
				fi->deps = fc->deps;
				fi->modified_time = fc->modification_time;
				fi->import_modified_time = fc->import_modification_time;
				if (fc->type == String()) {
					fi->type = ResourceLoader::get_resource_type(path);
					//there is also the chance that file type changed due to reimport, must probably check this somehow here (or kind of note it for next time in another file?)
					//note: I think this should not happen any longer..
				}

			} else {

				if (!fc) {
					print_line("REIMPORT BECAUSE: not previously found");
				} else if (fc->modification_time != mt) {
					print_line("REIMPORT BECAUSE: modified resource time " + itos(fc->modification_time) + " vs " + itos(mt));

				} else if (fc->import_modification_time != import_mt) {
					print_line("REIMPORT BECAUSE: modified .import time" + itos(fc->import_modification_time) + " vs " + itos(import_mt));

				} else {

					print_line("REIMPORT BECAUSE: missing imported files");
				}

				fi->type = ResourceFormatImporter::get_singleton()->get_resource_type(path);
				//fi->deps = ResourceLoader::get_dependencies(path); pointless because it will be reimported, but..
				print_line("import extension tried resource type for " + path + " and its " + fi->type);
				fi->modified_time = 0;
				fi->import_modified_time = 0;

				ItemAction ia;
				ia.action = ItemAction::ACTION_FILE_REIMPORT;
				ia.dir = p_dir;
				ia.file = E->get();
				scan_actions.push_back(ia);
			}
		} else {

			if (fc && fc->modification_time == mt) {
				//not imported, so just update type if changed
				fi->type = fc->type;
				fi->modified_time = fc->modification_time;
				fi->deps = fc->deps;
				fi->import_modified_time = 0;
			} else {
				//new or modified time
				fi->type = ResourceLoader::get_resource_type(path);
				fi->deps = _get_dependencies(path);
				print_line("regular import tried resource type for " + path + " and its " + fi->type);
				fi->modified_time = mt;
				fi->import_modified_time = 0;
			}
		}

		p_dir->files.push_back(fi);
		p_progress.update(idx, total);
	}
}
Пример #4
0
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);
	}
}
 void ScanProgress::GigFileProgressCallback(gig::progress_t* pProgress) {
     if (pProgress == NULL) return;
     ScanProgress* sp = static_cast<ScanProgress*> (pProgress->custom);
     
     sp->SetStatus((int)(pProgress->factor * 100));
 }