Esempio n. 1
0
void EditorFileSystem::_scan_sources(EditorFileSystemDirectory *p_dir,EditorProgressBG *ep) {

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

		if (_check_meta_sources(p_dir->files[i].meta,ep)) {
			sources_changed.push_back(p_dir->get_file_path(i));
		}
	}

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

		_scan_sources(p_dir->get_subdir(i),ep);
	}

}
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_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);
	}

}
Esempio n. 4
0
EditorFileSystem::DirItem* EditorFileSystem::_scan_dir(DirAccess *da,Set<String> &extensions,String p_name,float p_from,float p_range,const String& p_path,HashMap<String,FileCache> &file_cache,HashMap<String,DirCache> &dir_cache,EditorProgressBG& p_prog) {

	if (abort_scan)
		return NULL;

	if (p_path!=String()) {
		if (FileAccess::exists(("res://"+p_path).plus_file("engine.cfg"))) {
			return NULL;
		}
	}

	List<String> dirs;
	List<String> files;
	Set<String> pngs;

	String path=p_path;
	if (path.ends_with("/"))
		path=path.substr(0,path.length()-1);
	String global_path = Globals::get_singleton()->get_resource_path().plus_file(path);

	path="res://"+path;
	uint64_t mtime = FileAccess::get_modified_time(global_path);

	DirCache *dc = dir_cache.getptr(path);


	if (false && dc && dc->modification_time==mtime) {
		//use the cached files, since directory did not change
		for (Set<String>::Element *E=dc->subdirs.front();E;E=E->next()) {
			dirs.push_back(E->get());
		}
		for (Set<String>::Element *E=dc->files.front();E;E=E->next()) {
			files.push_back(E->get());
		}

	} else {
		//use the filesystem, some files may have changed
		Error err = da->change_dir(global_path);
		if (err!=OK) {
			print_line("Can't change to: "+path);
			ERR_FAIL_COND_V(err!=OK,NULL);
		}


		da->list_dir_begin();
		while (true) {

			bool isdir;
			String f = da->get_next(&isdir);
			if (f=="")
				break;
			if (isdir) {
				dirs.push_back(f);
			} else {
				String ext = f.extension().to_lower();
				if (extensions.has(ext))
					files.push_back(f);

			}

		}

		da->list_dir_end();
		files.sort();
		dirs.sort();

	}



	//print_line(da->get_current_dir()+": dirs: "+itos(dirs.size())+" files:"+itos(files.size()) );

	//find subdirs
	Vector<DirItem*> subdirs;

	//String current = da->get_current_dir();
	float idx=0;
	for (List<String>::Element *E=dirs.front();E;E=E->next(),idx+=1.0) {

		String d = E->get();
		if (d.begins_with(".")) //ignore hidden and . / ..
			continue;

		//ERR_CONTINUE( da->change_dir(d)!= OK );
		DirItem *sdi = _scan_dir(da,extensions,d,p_from+(idx/dirs.size())*p_range,p_range/dirs.size(),p_path+d+"/",file_cache,dir_cache,p_prog);
		if (sdi) {
			subdirs.push_back(sdi);
		}
		//da->change_dir(current);
	}


	if (subdirs.empty() && files.empty()) {
		total=p_from+p_range;
		p_prog.step(total*100);
		return NULL; //give up, nothing to do here
	}

	DirItem *di = memnew( DirItem );
	di->path=path;
	di->name=p_name;
	di->dirs=subdirs;
	di->modified_time=mtime;

	//add files
	for (List<String>::Element *E=files.front();E;E=E->next()) {

		SceneItem * si = memnew( SceneItem );
		si->file=E->get();
		si->path="res://"+p_path+si->file;
		FileCache *fc = file_cache.getptr(si->path);
		uint64_t mt = FileAccess::get_modified_time(si->path);

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

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

		}

		if (si->meta.enabled) {
			md_count++;
			if (_check_meta_sources(si->meta)) {
				sources_changed.push_back(si->path);
			}
		}
		di->files.push_back(si);
	}

	total=p_from+p_range;
	p_prog.step(total*100);

	return di;
}