mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 05:31:01 +00:00 
			
		
		
		
	Improve/fix packed data API
- Enhance directory API - Fix `FileAccess::exists()` not checking for PackedData being disabled - Fix moving to the parent directory (`..`) - Allow absolute paths in existence checks
This commit is contained in:
		
							parent
							
								
									37bac7d75d
								
							
						
					
					
						commit
						fa08b0f377
					
				
					 3 changed files with 57 additions and 9 deletions
				
			
		|  | @ -403,9 +403,15 @@ String DirAccessPack::get_drive(int p_drive) { | ||||||
| 	return ""; | 	return ""; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Error DirAccessPack::change_dir(String p_dir) { | PackedData::PackedDir *DirAccessPack::_find_dir(String p_dir) { | ||||||
| 
 | 
 | ||||||
| 	String nd = p_dir.replace("\\", "/"); | 	String nd = p_dir.replace("\\", "/"); | ||||||
|  | 
 | ||||||
|  | 	// Special handling since simplify_path() will forbid it
 | ||||||
|  | 	if (p_dir == "..") { | ||||||
|  | 		return current->parent; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	bool absolute = false; | 	bool absolute = false; | ||||||
| 	if (nd.begins_with("res://")) { | 	if (nd.begins_with("res://")) { | ||||||
| 		nd = nd.replace_first("res://", ""); | 		nd = nd.replace_first("res://", ""); | ||||||
|  | @ -445,13 +451,22 @@ Error DirAccessPack::change_dir(String p_dir) { | ||||||
| 
 | 
 | ||||||
| 		} else { | 		} else { | ||||||
| 
 | 
 | ||||||
|  | 			return NULL; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return pd; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Error DirAccessPack::change_dir(String p_dir) { | ||||||
|  | 
 | ||||||
|  | 	PackedData::PackedDir *pd = _find_dir(p_dir); | ||||||
|  | 	if (pd) { | ||||||
|  | 		current = pd; | ||||||
|  | 		return OK; | ||||||
|  | 	} else { | ||||||
| 		return ERR_INVALID_PARAMETER; | 		return ERR_INVALID_PARAMETER; | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	current = pd; |  | ||||||
| 
 |  | ||||||
| 	return OK; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| String DirAccessPack::get_current_dir() { | String DirAccessPack::get_current_dir() { | ||||||
|  | @ -471,14 +486,18 @@ bool DirAccessPack::file_exists(String p_file) { | ||||||
| 
 | 
 | ||||||
| 	p_file = fix_path(p_file); | 	p_file = fix_path(p_file); | ||||||
| 
 | 
 | ||||||
| 	return current->files.has(p_file); | 	PackedData::PackedDir *pd = _find_dir(p_file.get_base_dir()); | ||||||
|  | 	if (!pd) { | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 	return pd->files.has(p_file.get_file()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool DirAccessPack::dir_exists(String p_dir) { | bool DirAccessPack::dir_exists(String p_dir) { | ||||||
| 
 | 
 | ||||||
| 	p_dir = fix_path(p_dir); | 	p_dir = fix_path(p_dir); | ||||||
| 
 | 
 | ||||||
| 	return current->subdirs.has(p_dir); | 	return _find_dir(p_dir) != NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Error DirAccessPack::make_dir(String p_dir) { | Error DirAccessPack::make_dir(String p_dir) { | ||||||
|  |  | ||||||
|  | @ -118,6 +118,9 @@ public: | ||||||
| 	_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path); | 	_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path); | ||||||
| 	_FORCE_INLINE_ bool has_path(const String &p_path); | 	_FORCE_INLINE_ bool has_path(const String &p_path); | ||||||
| 
 | 
 | ||||||
|  | 	_FORCE_INLINE_ DirAccess *try_open_directory(const String &p_path); | ||||||
|  | 	_FORCE_INLINE_ bool has_directory(const String &p_path); | ||||||
|  | 
 | ||||||
| 	PackedData(); | 	PackedData(); | ||||||
| 	~PackedData(); | 	~PackedData(); | ||||||
| }; | }; | ||||||
|  | @ -197,6 +200,17 @@ bool PackedData::has_path(const String &p_path) { | ||||||
| 	return files.has(PathMD5(p_path.md5_buffer())); | 	return files.has(PathMD5(p_path.md5_buffer())); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool PackedData::has_directory(const String &p_path) { | ||||||
|  | 
 | ||||||
|  | 	DirAccess *da = try_open_directory(p_path); | ||||||
|  | 	if (da) { | ||||||
|  | 		memdelete(da); | ||||||
|  | 		return true; | ||||||
|  | 	} else { | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| class DirAccessPack : public DirAccess { | class DirAccessPack : public DirAccess { | ||||||
| 
 | 
 | ||||||
| 	PackedData::PackedDir *current; | 	PackedData::PackedDir *current; | ||||||
|  | @ -205,6 +219,8 @@ class DirAccessPack : public DirAccess { | ||||||
| 	List<String> list_files; | 	List<String> list_files; | ||||||
| 	bool cdir; | 	bool cdir; | ||||||
| 
 | 
 | ||||||
|  | 	PackedData::PackedDir *_find_dir(String p_dir); | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
| 	virtual Error list_dir_begin(); | 	virtual Error list_dir_begin(); | ||||||
| 	virtual String get_next(); | 	virtual String get_next(); | ||||||
|  | @ -234,4 +250,14 @@ public: | ||||||
| 	~DirAccessPack(); | 	~DirAccessPack(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | DirAccess *PackedData::try_open_directory(const String &p_path) { | ||||||
|  | 
 | ||||||
|  | 	DirAccess *da = memnew(DirAccessPack()); | ||||||
|  | 	if (da->change_dir(p_path) != OK) { | ||||||
|  | 		memdelete(da); | ||||||
|  | 		da = NULL; | ||||||
|  | 	} | ||||||
|  | 	return da; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #endif // FILE_ACCESS_PACK_H
 | #endif // FILE_ACCESS_PACK_H
 | ||||||
|  |  | ||||||
|  | @ -53,7 +53,7 @@ FileAccess *FileAccess::create(AccessType p_access) { | ||||||
| 
 | 
 | ||||||
| bool FileAccess::exists(const String &p_name) { | bool FileAccess::exists(const String &p_name) { | ||||||
| 
 | 
 | ||||||
| 	if (PackedData::get_singleton() && PackedData::get_singleton()->has_path(p_name)) | 	if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_name)) | ||||||
| 		return true; | 		return true; | ||||||
| 
 | 
 | ||||||
| 	FileAccess *f = open(p_name, READ); | 	FileAccess *f = open(p_name, READ); | ||||||
|  | @ -494,7 +494,7 @@ void FileAccess::store_double(double p_dest) { | ||||||
| 
 | 
 | ||||||
| uint64_t FileAccess::get_modified_time(const String &p_file) { | uint64_t FileAccess::get_modified_time(const String &p_file) { | ||||||
| 
 | 
 | ||||||
| 	if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) | 	if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	FileAccess *fa = create_for_path(p_file); | 	FileAccess *fa = create_for_path(p_file); | ||||||
|  | @ -507,7 +507,7 @@ uint64_t FileAccess::get_modified_time(const String &p_file) { | ||||||
| 
 | 
 | ||||||
| uint32_t FileAccess::get_unix_permissions(const String &p_file) { | uint32_t FileAccess::get_unix_permissions(const String &p_file) { | ||||||
| 
 | 
 | ||||||
| 	if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) | 	if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	FileAccess *fa = create_for_path(p_file); | 	FileAccess *fa = create_for_path(p_file); | ||||||
|  | @ -520,6 +520,9 @@ uint32_t FileAccess::get_unix_permissions(const String &p_file) { | ||||||
| 
 | 
 | ||||||
| Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) { | Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) { | ||||||
| 
 | 
 | ||||||
|  | 	if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) | ||||||
|  | 		return ERR_UNAVAILABLE; | ||||||
|  | 
 | ||||||
| 	FileAccess *fa = create_for_path(p_file); | 	FileAccess *fa = create_for_path(p_file); | ||||||
| 	ERR_FAIL_COND_V_MSG(!fa, ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'."); | 	ERR_FAIL_COND_V_MSG(!fa, ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'."); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Pedro J. Estébanez
						Pedro J. Estébanez