**WARNING BEFORE PULLING**
This push changes the binary and XML formats and bumps the major version to 2.0. As such, files saved in this version WILL NO LONGER WORK IN PREVIOUS VERSIONS. This compatibility breakage with older versions was required in order to properly provide project refactoring tools. If I were you, unless you are brave, I would wait a week or two before pulling, in case of bugs :) Summary of Changes -New Filesystem dock, with filesystem & tree view modes. -New refactoring tools, to change or fix dependencies. -Quick search dialog, to quickly search any file
This commit is contained in:
parent
9d185ccc30
commit
07e9741425
59 changed files with 2694 additions and 402 deletions
|
@ -54,6 +54,7 @@ enum Error {
|
|||
ERR_FILE_CANT_READ,
|
||||
ERR_FILE_UNRECOGNIZED, // (15)
|
||||
ERR_FILE_CORRUPT,
|
||||
ERR_FILE_MISSING_DEPENDENCIES,
|
||||
ERR_FILE_EOF,
|
||||
ERR_CANT_OPEN, ///< Can't open a resource/socket/file
|
||||
ERR_CANT_CREATE,
|
||||
|
|
|
@ -422,6 +422,7 @@ static _GlobalConstant _global_constants[]={
|
|||
BIND_GLOBAL_CONSTANT( ERR_FILE_CANT_READ ),
|
||||
BIND_GLOBAL_CONSTANT( ERR_FILE_UNRECOGNIZED ),
|
||||
BIND_GLOBAL_CONSTANT( ERR_FILE_CORRUPT ),
|
||||
BIND_GLOBAL_CONSTANT( ERR_FILE_MISSING_DEPENDENCIES),
|
||||
BIND_GLOBAL_CONSTANT( ERR_FILE_EOF ),
|
||||
BIND_GLOBAL_CONSTANT( ERR_CANT_OPEN ), ///< Can't open a resource/socket/file
|
||||
BIND_GLOBAL_CONSTANT( ERR_CANT_CREATE ),
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "globals.h"
|
||||
#include "io/file_access_compressed.h"
|
||||
#include "io/marshalls.h"
|
||||
#include "os/dir_access.h"
|
||||
//#define print_bl(m_what) print_line(m_what)
|
||||
#define print_bl(m_what)
|
||||
|
||||
|
@ -99,7 +100,9 @@ enum {
|
|||
OBJECT_EMPTY=0,
|
||||
OBJECT_EXTERNAL_RESOURCE=1,
|
||||
OBJECT_INTERNAL_RESOURCE=2,
|
||||
FORMAT_VERSION=0
|
||||
OBJECT_EXTERNAL_RESOURCE_INDEX=3,
|
||||
FORMAT_VERSION=1,
|
||||
FORMAT_VERSION_CAN_RENAME_DEPS=1
|
||||
|
||||
|
||||
};
|
||||
|
@ -375,7 +378,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
|
|||
} break;
|
||||
case OBJECT_INTERNAL_RESOURCE: {
|
||||
uint32_t index=f->get_32();
|
||||
String path = res_path+"::"+itos(index);
|
||||
String path = res_path+"::"+itos(index);
|
||||
RES res = ResourceLoader::load(path);
|
||||
if (res.is_null()) {
|
||||
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
|
||||
|
@ -384,6 +387,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
|
|||
|
||||
} break;
|
||||
case OBJECT_EXTERNAL_RESOURCE: {
|
||||
//old file format, still around for compatibility
|
||||
|
||||
String type = get_unicode_string();
|
||||
String path = get_unicode_string();
|
||||
|
@ -394,6 +398,10 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
|
|||
|
||||
}
|
||||
|
||||
if (remaps.find(path)) {
|
||||
path=remaps[path];
|
||||
}
|
||||
|
||||
RES res=ResourceLoader::load(path,type);
|
||||
|
||||
if (res.is_null()) {
|
||||
|
@ -401,6 +409,34 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
|
|||
}
|
||||
r_v=res;
|
||||
|
||||
} break;
|
||||
case OBJECT_EXTERNAL_RESOURCE_INDEX: {
|
||||
//new file format, just refers to an index in the external list
|
||||
uint32_t erindex = f->get_32();
|
||||
|
||||
if (erindex>=external_resources.size()) {
|
||||
WARN_PRINT("Broken external resource! (index out of size");
|
||||
r_v=Variant();
|
||||
} else {
|
||||
|
||||
String type = external_resources[erindex].type;
|
||||
String path = external_resources[erindex].path;
|
||||
|
||||
if (path.find("://")==-1 && path.is_rel_path()) {
|
||||
// path is relative to file being loaded, so convert to a resource path
|
||||
path=Globals::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
|
||||
|
||||
}
|
||||
|
||||
RES res=ResourceLoader::load(path,type);
|
||||
|
||||
if (res.is_null()) {
|
||||
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
|
||||
}
|
||||
r_v=res;
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
default: {
|
||||
|
||||
|
@ -628,17 +664,20 @@ Error ResourceInteractiveLoaderBinary::poll(){
|
|||
|
||||
if (s<external_resources.size()) {
|
||||
|
||||
RES res = ResourceLoader::load(external_resources[s].path,external_resources[s].type);
|
||||
String path = external_resources[s].path;
|
||||
if (remaps.has(path)) {
|
||||
path=remaps[path];
|
||||
}
|
||||
RES res = ResourceLoader::load(path,external_resources[s].type);
|
||||
if (res.is_null()) {
|
||||
|
||||
if (!ResourceLoader::get_abort_on_missing_resources()) {
|
||||
|
||||
ResourceLoader::notify_load_error("Resource Not Found: "+external_resources[s].path);
|
||||
ResourceLoader::notify_dependency_error(local_path,path,external_resources[s].type);
|
||||
} else {
|
||||
|
||||
|
||||
error=ERR_FILE_CORRUPT;
|
||||
ERR_EXPLAIN("Can't load dependency: "+external_resources[s].path);
|
||||
error=ERR_FILE_MISSING_DEPENDENCIES;
|
||||
ERR_EXPLAIN("Can't load dependency: "+path);
|
||||
ERR_FAIL_V(error);
|
||||
}
|
||||
|
||||
|
@ -787,6 +826,27 @@ int ResourceInteractiveLoaderBinary::get_stage_count() const {
|
|||
return external_resources.size()+internal_resources.size();
|
||||
}
|
||||
|
||||
|
||||
static void save_ustring(FileAccess* f,const String& p_string) {
|
||||
|
||||
|
||||
CharString utf8 = p_string.utf8();
|
||||
f->store_32(utf8.length()+1);
|
||||
f->store_buffer((const uint8_t*)utf8.get_data(),utf8.length()+1);
|
||||
}
|
||||
|
||||
|
||||
static String get_ustring(FileAccess *f) {
|
||||
|
||||
int len = f->get_32();
|
||||
Vector<char> str_buf;
|
||||
str_buf.resize(len);
|
||||
f->get_buffer((uint8_t*)&str_buf[0],len);
|
||||
String s;
|
||||
s.parse_utf8(&str_buf[0]);
|
||||
return s;
|
||||
}
|
||||
|
||||
String ResourceInteractiveLoaderBinary::get_unicode_string() {
|
||||
|
||||
int len = f->get_32();
|
||||
|
@ -801,7 +861,7 @@ String ResourceInteractiveLoaderBinary::get_unicode_string() {
|
|||
|
||||
|
||||
|
||||
void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<String> *p_dependencies) {
|
||||
void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<String> *p_dependencies,bool p_add_types) {
|
||||
|
||||
open(p_f);
|
||||
if (error)
|
||||
|
@ -814,6 +874,10 @@ void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<Stri
|
|||
dep=ResourceLoader::guess_full_filename(dep,external_resources[i].type);
|
||||
}
|
||||
|
||||
if (p_add_types && external_resources[i].type!=String()) {
|
||||
dep+="::"+external_resources[i].type;
|
||||
}
|
||||
|
||||
p_dependencies->push_back(dep);
|
||||
}
|
||||
|
||||
|
@ -866,7 +930,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
|
|||
print_bl("minor: "+itos(ver_minor));
|
||||
print_bl("format: "+itos(ver_format));
|
||||
|
||||
if (ver_format<FORMAT_VERSION || ver_major>VERSION_MAJOR) {
|
||||
if (ver_format>FORMAT_VERSION || ver_major>VERSION_MAJOR) {
|
||||
|
||||
f->close();
|
||||
ERR_EXPLAIN("File Format '"+itos(FORMAT_VERSION)+"."+itos(ver_major)+"."+itos(ver_minor)+"' is too new! Please upgrade to a a new engine version: "+local_path);
|
||||
|
@ -903,6 +967,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
|
|||
}
|
||||
|
||||
//see if the exporter has different set of external resources for more efficient loading
|
||||
/*
|
||||
String preload_depts = "deps/"+res_path.md5_text();
|
||||
if (Globals::get_singleton()->has(preload_depts)) {
|
||||
external_resources.clear();
|
||||
|
@ -913,7 +978,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
|
|||
external_resources[i].path=depts.get_name(i);
|
||||
}
|
||||
print_line(res_path+" - EXTERNAL RESOURCES: "+itos(external_resources.size()));
|
||||
}
|
||||
}*/
|
||||
|
||||
print_bl("ext resources: "+itos(ext_resources_size));
|
||||
uint32_t int_resources_size=f->get_32();
|
||||
|
@ -973,7 +1038,7 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) {
|
|||
uint32_t ver_minor=f->get_32();
|
||||
uint32_t ver_format=f->get_32();
|
||||
|
||||
if (ver_format<FORMAT_VERSION || ver_major>VERSION_MAJOR) {
|
||||
if (ver_format>FORMAT_VERSION || ver_major>VERSION_MAJOR) {
|
||||
|
||||
f->close();
|
||||
return "";
|
||||
|
@ -1000,8 +1065,10 @@ ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() {
|
|||
}
|
||||
|
||||
|
||||
Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path) {
|
||||
Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CANT_OPEN;
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
|
||||
|
@ -1114,7 +1181,7 @@ Error ResourceFormatLoaderBinary::load_import_metadata(const String &p_path, Ref
|
|||
}
|
||||
|
||||
|
||||
void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<String> *p_dependencies) {
|
||||
void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types) {
|
||||
|
||||
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
|
||||
ERR_FAIL_COND(!f);
|
||||
|
@ -1123,7 +1190,217 @@ void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<Stri
|
|||
ria->local_path=Globals::get_singleton()->localize_path(p_path);
|
||||
ria->res_path=ria->local_path;
|
||||
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
|
||||
ria->get_dependencies(f,p_dependencies);
|
||||
ria->get_dependencies(f,p_dependencies,p_add_types);
|
||||
}
|
||||
|
||||
Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
|
||||
|
||||
|
||||
// Error error=OK;
|
||||
|
||||
|
||||
FileAccess *f=FileAccess::open(p_path,FileAccess::READ);
|
||||
ERR_FAIL_COND_V(!f,ERR_CANT_OPEN);
|
||||
|
||||
FileAccess* fw=NULL;//=FileAccess::open(p_path+".depren");
|
||||
|
||||
String local_path=p_path.get_base_dir();
|
||||
|
||||
uint8_t header[4];
|
||||
f->get_buffer(header,4);
|
||||
if (header[0]=='R' && header[1]=='S' && header[2]=='C' && header[3]=='C') {
|
||||
//compressed
|
||||
FileAccessCompressed *fac = memnew( FileAccessCompressed );
|
||||
fac->open_after_magic(f);
|
||||
f=fac;
|
||||
|
||||
FileAccessCompressed *facw = memnew( FileAccessCompressed );
|
||||
facw->configure("RSCC");
|
||||
Error err = facw->_open(p_path+".depren",FileAccess::WRITE);
|
||||
if (err) {
|
||||
memdelete(fac);
|
||||
memdelete(facw);
|
||||
ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT);
|
||||
}
|
||||
|
||||
fw=facw;
|
||||
|
||||
|
||||
} else if (header[0]!='R' || header[1]!='S' || header[2]!='R' || header[3]!='C') {
|
||||
//not normal
|
||||
|
||||
//error=ERR_FILE_UNRECOGNIZED;
|
||||
memdelete(f);
|
||||
ERR_EXPLAIN("Unrecognized binary resource file: "+local_path);
|
||||
ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
|
||||
} else {
|
||||
fw = FileAccess::open(p_path+".depren",FileAccess::WRITE);
|
||||
if (!fw) {
|
||||
memdelete(f);
|
||||
}
|
||||
ERR_FAIL_COND_V(!fw,ERR_CANT_CREATE);
|
||||
}
|
||||
|
||||
bool big_endian = f->get_32();
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
endian_swap = !big_endian;
|
||||
#else
|
||||
bool endian_swap = big_endian;
|
||||
#endif
|
||||
|
||||
bool use_real64 = f->get_32();
|
||||
|
||||
f->set_endian_swap(big_endian!=0); //read big endian if saved as big endian
|
||||
fw->store_32(endian_swap);
|
||||
fw->set_endian_swap(big_endian!=0);
|
||||
fw->store_32(use_real64); //use real64
|
||||
|
||||
uint32_t ver_major=f->get_32();
|
||||
uint32_t ver_minor=f->get_32();
|
||||
uint32_t ver_format=f->get_32();
|
||||
|
||||
if (ver_format<FORMAT_VERSION_CAN_RENAME_DEPS) {
|
||||
|
||||
memdelete(f);
|
||||
memdelete(fw);
|
||||
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
da->remove(p_path+".depren");
|
||||
memdelete(da);
|
||||
//fuck it, use the old approach;
|
||||
|
||||
WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: "+p_path).utf8().get_data());
|
||||
|
||||
Error err;
|
||||
f = FileAccess::open(p_path,FileAccess::READ,&err);
|
||||
if (err!=OK) {
|
||||
ERR_FAIL_COND_V(err!=OK,ERR_FILE_CANT_OPEN);
|
||||
}
|
||||
|
||||
Ref<ResourceInteractiveLoaderBinary> ria = memnew( ResourceInteractiveLoaderBinary );
|
||||
ria->local_path=Globals::get_singleton()->localize_path(p_path);
|
||||
ria->res_path=ria->local_path;
|
||||
ria->remaps=p_map;
|
||||
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
|
||||
ria->open(f);
|
||||
|
||||
err = ria->poll();
|
||||
|
||||
while(err==OK) {
|
||||
err=ria->poll();
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(err!=ERR_FILE_EOF,ERR_FILE_CORRUPT);
|
||||
RES res = ria->get_resource();
|
||||
ERR_FAIL_COND_V(!res.is_valid(),ERR_FILE_CORRUPT);
|
||||
|
||||
return ResourceFormatSaverBinary::singleton->save(p_path,res);
|
||||
}
|
||||
|
||||
if (ver_format>FORMAT_VERSION || ver_major>VERSION_MAJOR) {
|
||||
|
||||
memdelete(f);
|
||||
memdelete(fw);
|
||||
ERR_EXPLAIN("File Format '"+itos(FORMAT_VERSION)+"."+itos(ver_major)+"."+itos(ver_minor)+"' is too new! Please upgrade to a a new engine version: "+local_path);
|
||||
ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
|
||||
|
||||
}
|
||||
|
||||
fw->store_32( VERSION_MAJOR ); //current version
|
||||
fw->store_32( VERSION_MINOR );
|
||||
fw->store_32( FORMAT_VERSION );
|
||||
|
||||
save_ustring(fw,get_ustring(f)); //type
|
||||
|
||||
|
||||
size_t md_ofs = f->get_pos();
|
||||
size_t importmd_ofs = f->get_64();
|
||||
fw->store_64(0); //metadata offset
|
||||
|
||||
for(int i=0;i<14;i++) {
|
||||
fw->store_32(0);
|
||||
f->get_32();
|
||||
}
|
||||
|
||||
//string table
|
||||
uint32_t string_table_size=f->get_32();
|
||||
|
||||
fw->store_32(string_table_size);
|
||||
|
||||
for(uint32_t i=0;i<string_table_size;i++) {
|
||||
|
||||
String s = get_ustring(f);
|
||||
save_ustring(fw,s);
|
||||
}
|
||||
|
||||
//external resources
|
||||
uint32_t ext_resources_size=f->get_32();
|
||||
fw->store_32(ext_resources_size);
|
||||
for(uint32_t i=0;i<ext_resources_size;i++) {
|
||||
|
||||
String type = get_ustring(f);
|
||||
String path = get_ustring(f);
|
||||
|
||||
bool relative=false;
|
||||
if (!path.begins_with("res://")) {
|
||||
path=local_path.plus_file(path).simplify_path();
|
||||
relative=true;
|
||||
}
|
||||
|
||||
|
||||
if (p_map.has(path)) {
|
||||
String np=p_map[path];
|
||||
path=np;
|
||||
}
|
||||
|
||||
if (relative) {
|
||||
//restore relative
|
||||
path=local_path.path_to_file(path);
|
||||
}
|
||||
|
||||
save_ustring(fw,type);
|
||||
save_ustring(fw,path);
|
||||
}
|
||||
|
||||
int64_t size_diff = (int64_t)fw->get_pos() - (int64_t)f->get_pos();
|
||||
|
||||
//internal resources
|
||||
uint32_t int_resources_size=f->get_32();
|
||||
fw->store_32(int_resources_size);
|
||||
|
||||
for(uint32_t i=0;i<int_resources_size;i++) {
|
||||
|
||||
|
||||
String path=get_ustring(f);
|
||||
uint64_t offset=f->get_64();
|
||||
save_ustring(fw,path);
|
||||
fw->store_64(offset+size_diff);
|
||||
}
|
||||
|
||||
//rest of file
|
||||
uint8_t b = f->get_8();
|
||||
while(!f->eof_reached()) {
|
||||
fw->store_8(b);
|
||||
b = f->get_8();
|
||||
}
|
||||
|
||||
bool all_ok = fw->get_error()==OK;
|
||||
|
||||
fw->seek(md_ofs);
|
||||
fw->store_64(importmd_ofs+size_diff);
|
||||
|
||||
|
||||
memdelete(f);
|
||||
memdelete(fw);
|
||||
|
||||
if (!all_ok) {
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
da->remove(p_path);
|
||||
da->rename(p_path+".depren",p_path);
|
||||
memdelete(da);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1433,10 +1710,8 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property,
|
|||
}
|
||||
|
||||
if (res->get_path().length() && res->get_path().find("::")==-1) {
|
||||
f->store_32(OBJECT_EXTERNAL_RESOURCE);
|
||||
save_unicode_string(res->get_save_type());
|
||||
String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
|
||||
save_unicode_string(path);
|
||||
f->store_32(OBJECT_EXTERNAL_RESOURCE_INDEX);
|
||||
f->store_32(external_resources[res]);
|
||||
} else {
|
||||
|
||||
if (!resource_set.has(res)) {
|
||||
|
@ -1594,11 +1869,12 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant& p_variant
|
|||
|
||||
RES res = p_variant.operator RefPtr();
|
||||
|
||||
if (res.is_null())
|
||||
if (res.is_null() || external_resources.has(res))
|
||||
return;
|
||||
|
||||
if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) {
|
||||
external_resources.insert(res);
|
||||
int idx = external_resources.size();
|
||||
external_resources[res]=idx;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1842,10 +2118,18 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
|
|||
|
||||
// save external resource table
|
||||
f->store_32(external_resources.size()); //amount of external resources
|
||||
for(Set<RES>::Element *E=external_resources.front();E;E=E->next()) {
|
||||
Vector<RES> save_order;
|
||||
save_order.resize(external_resources.size());
|
||||
|
||||
save_unicode_string(E->get()->get_save_type());
|
||||
String path = E->get()->get_path();
|
||||
for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) {
|
||||
save_order[E->get()]=E->key();
|
||||
}
|
||||
|
||||
for(int i=0;i<save_order.size();i++) {
|
||||
|
||||
save_unicode_string(save_order[i]->get_save_type());
|
||||
String path = save_order[i]->get_path();
|
||||
path=relative_paths?local_path.path_to_file(path):path;
|
||||
save_unicode_string(path);
|
||||
}
|
||||
// save internal resource table
|
||||
|
@ -1995,3 +2279,9 @@ void ResourceFormatSaverBinary::get_recognized_extensions(const RES& p_resource,
|
|||
|
||||
}
|
||||
|
||||
ResourceFormatSaverBinary* ResourceFormatSaverBinary::singleton=NULL;
|
||||
|
||||
ResourceFormatSaverBinary::ResourceFormatSaverBinary() {
|
||||
|
||||
singleton=this;
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
|
|||
String get_unicode_string();
|
||||
void _advance_padding(uint32_t p_len);
|
||||
|
||||
Map<String,String> remaps;
|
||||
Error error;
|
||||
|
||||
int stage;
|
||||
|
@ -88,9 +89,10 @@ public:
|
|||
virtual int get_stage() const;
|
||||
virtual int get_stage_count() const;
|
||||
|
||||
void set_remaps(const Map<String,String>& p_remaps) { remaps=p_remaps; }
|
||||
void open(FileAccess *p_f);
|
||||
String recognize(FileAccess *p_f);
|
||||
void get_dependencies(FileAccess *p_f,List<String> *p_dependencies);
|
||||
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
|
||||
|
||||
|
||||
ResourceInteractiveLoaderBinary();
|
||||
|
@ -101,13 +103,14 @@ public:
|
|||
class ResourceFormatLoaderBinary : public ResourceFormatLoader {
|
||||
public:
|
||||
|
||||
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path);
|
||||
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
virtual void get_dependencies(const String& p_path,List<String> *p_dependencies);
|
||||
virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
|
||||
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const;
|
||||
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
|
||||
|
||||
|
||||
|
||||
|
@ -134,7 +137,7 @@ class ResourceFormatSaverBinaryInstance {
|
|||
Vector<StringName> strings;
|
||||
|
||||
|
||||
Set<RES> external_resources;
|
||||
Map<RES,int> external_resources;
|
||||
List<RES> saved_resources;
|
||||
|
||||
|
||||
|
@ -174,11 +177,12 @@ class ResourceFormatSaverBinary : public ResourceFormatSaver {
|
|||
|
||||
public:
|
||||
|
||||
static ResourceFormatSaverBinary* singleton;
|
||||
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
|
||||
virtual bool recognize(const RES& p_resource) const;
|
||||
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
|
||||
|
||||
|
||||
ResourceFormatSaverBinary();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -29,10 +29,10 @@
|
|||
#include "resource_format_xml.h"
|
||||
#include "globals.h"
|
||||
#include "version.h"
|
||||
#include "os/dir_access.h"
|
||||
|
||||
|
||||
|
||||
ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool *r_exit,bool p_printerr) {
|
||||
ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool *r_exit, bool p_printerr, List<String> *r_order) {
|
||||
|
||||
|
||||
while(get_char()!='<' && !f->eof_reached()) {}
|
||||
|
@ -107,7 +107,11 @@ ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool
|
|||
if (r_value.size()) {
|
||||
|
||||
r_value.push_back(0);
|
||||
tag.args[name].parse_utf8(r_value.get_data());
|
||||
String str;
|
||||
str.parse_utf8(r_value.get_data());
|
||||
tag.args[name]=str;
|
||||
if (r_order)
|
||||
r_order->push_back(name);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -119,7 +123,11 @@ ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool
|
|||
} else if (reading_value && r_value.size()) {
|
||||
|
||||
r_value.push_back(0);
|
||||
tag.args[name].parse_utf8(r_value.get_data());
|
||||
String str;
|
||||
str.parse_utf8(r_value.get_data());
|
||||
tag.args[name]=str;
|
||||
if (r_order)
|
||||
r_order->push_back(name);
|
||||
name="";
|
||||
r_value.clear();
|
||||
reading_value=false;
|
||||
|
@ -463,6 +471,10 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
|
|||
|
||||
}
|
||||
|
||||
if (remaps.has(path)) {
|
||||
path=remaps[path];
|
||||
}
|
||||
|
||||
//take advantage of the resource loader cache. The resource is cached on it, even if
|
||||
RES res=ResourceLoader::load(path,hint);
|
||||
|
||||
|
@ -473,10 +485,31 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
|
|||
}
|
||||
|
||||
r_v=res.get_ref_ptr();
|
||||
} else if (tag->args.has("external")) {
|
||||
|
||||
int index = tag->args["external"].to_int();
|
||||
if (ext_resources.has(index)) {
|
||||
String path=ext_resources[index].path;
|
||||
String type=ext_resources[index].type;
|
||||
|
||||
//take advantage of the resource loader cache. The resource is cached on it, even if
|
||||
RES res=ResourceLoader::load(path,type);
|
||||
|
||||
if (res.is_null()) {
|
||||
|
||||
WARN_PRINT(String("Couldn't load externalresource: "+path).ascii().get_data());
|
||||
}
|
||||
|
||||
r_v=res.get_ref_ptr();
|
||||
} else {
|
||||
WARN_PRINT(String("Invalid external resource index: "+itos(index)).ascii().get_data());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Error err=goto_end_of_tag();
|
||||
if (err) {
|
||||
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Error closing <resource> tag.");
|
||||
|
@ -1364,32 +1397,6 @@ Error ResourceInteractiveLoaderXML::poll() {
|
|||
if (error!=OK)
|
||||
return error;
|
||||
|
||||
if (ext_resources.size()) {
|
||||
|
||||
error=ERR_FILE_CORRUPT;
|
||||
String path=ext_resources.front()->get();
|
||||
|
||||
RES res = ResourceLoader::load(path);
|
||||
|
||||
if (res.is_null()) {
|
||||
|
||||
if (ResourceLoader::get_abort_on_missing_resources()) {
|
||||
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": editor exported nonexistent resource at: "+path);
|
||||
ERR_FAIL_V(error);
|
||||
} else {
|
||||
ResourceLoader::notify_load_error("Resource Not Found: "+path);
|
||||
}
|
||||
} else {
|
||||
|
||||
resource_cache.push_back(res);
|
||||
}
|
||||
|
||||
error=OK;
|
||||
ext_resources.pop_front();
|
||||
resource_current++;
|
||||
return error;
|
||||
}
|
||||
|
||||
bool exit;
|
||||
Tag *tag = parse_tag(&exit);
|
||||
|
||||
|
@ -1413,12 +1420,13 @@ Error ResourceInteractiveLoaderXML::poll() {
|
|||
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> missing 'path' field.");
|
||||
ERR_FAIL_COND_V(!tag->args.has("path"),ERR_FILE_CORRUPT);
|
||||
|
||||
String type;
|
||||
String type="Resource";
|
||||
if (tag->args.has("type"))
|
||||
type=tag->args["type"];
|
||||
|
||||
String path = tag->args["path"];
|
||||
|
||||
|
||||
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> can't use a local path, this is a bug?.");
|
||||
ERR_FAIL_COND_V(path.begins_with("local://"),ERR_FILE_CORRUPT);
|
||||
|
||||
|
@ -1427,6 +1435,9 @@ Error ResourceInteractiveLoaderXML::poll() {
|
|||
path=Globals::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path));
|
||||
}
|
||||
|
||||
if (remaps.has(path)) {
|
||||
path=remaps[path];
|
||||
}
|
||||
|
||||
RES res = ResourceLoader::load(path,type);
|
||||
|
||||
|
@ -1436,13 +1447,21 @@ Error ResourceInteractiveLoaderXML::poll() {
|
|||
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> referenced nonexistent resource at: "+path);
|
||||
ERR_FAIL_V(error);
|
||||
} else {
|
||||
ResourceLoader::notify_load_error("Resource Not Found: "+path);
|
||||
ResourceLoader::notify_dependency_error(local_path,path,type);
|
||||
}
|
||||
} else {
|
||||
|
||||
resource_cache.push_back(res);
|
||||
}
|
||||
|
||||
if (tag->args.has("index")) {
|
||||
ExtResource er;
|
||||
er.path=path;
|
||||
er.type=type;
|
||||
ext_resources[tag->args["index"].to_int()]=er;
|
||||
}
|
||||
|
||||
|
||||
Error err = close_tag("ext_resource");
|
||||
if (err)
|
||||
return error;
|
||||
|
@ -1566,7 +1585,7 @@ int ResourceInteractiveLoaderXML::get_stage() const {
|
|||
}
|
||||
int ResourceInteractiveLoaderXML::get_stage_count() const {
|
||||
|
||||
return resources_total+ext_resources.size();
|
||||
return resources_total;//+ext_resources;
|
||||
}
|
||||
|
||||
ResourceInteractiveLoaderXML::~ResourceInteractiveLoaderXML() {
|
||||
|
@ -1574,7 +1593,7 @@ ResourceInteractiveLoaderXML::~ResourceInteractiveLoaderXML() {
|
|||
memdelete(f);
|
||||
}
|
||||
|
||||
void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *p_dependencies) {
|
||||
void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *p_dependencies,bool p_add_types) {
|
||||
|
||||
|
||||
open(f);
|
||||
|
@ -1617,6 +1636,10 @@ void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *
|
|||
path = ResourceLoader::guess_full_filename(path,type);
|
||||
}
|
||||
|
||||
if (p_add_types && tag->args.has("type")) {
|
||||
path+="::"+tag->args["type"];
|
||||
}
|
||||
|
||||
p_dependencies->push_back(path);
|
||||
|
||||
Error err = close_tag("ext_resource");
|
||||
|
@ -1628,6 +1651,167 @@ void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *
|
|||
|
||||
}
|
||||
|
||||
Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map) {
|
||||
|
||||
open(p_f);
|
||||
ERR_FAIL_COND_V(error!=OK,error);
|
||||
|
||||
//FileAccess
|
||||
|
||||
bool old_format=false;
|
||||
|
||||
FileAccess *fw = NULL;
|
||||
|
||||
String base_path=local_path.get_base_dir();
|
||||
|
||||
while(true) {
|
||||
bool exit;
|
||||
List<String> order;
|
||||
|
||||
Tag *tag = parse_tag(&exit,true,&order);
|
||||
|
||||
bool done=false;
|
||||
|
||||
if (!tag) {
|
||||
if (fw) {
|
||||
memdelete(fw);
|
||||
}
|
||||
error=ERR_FILE_CORRUPT;
|
||||
ERR_FAIL_COND_V(!exit,error);
|
||||
error=ERR_FILE_EOF;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
if (tag->name=="ext_resource") {
|
||||
|
||||
if (!tag->args.has("index") || !tag->args.has("path") || !tag->args.has("type")) {
|
||||
old_format=true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fw) {
|
||||
|
||||
fw=FileAccess::open(p_path+".depren",FileAccess::WRITE);
|
||||
fw->store_line("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); //no escape
|
||||
fw->store_line("<resource_file type=\""+resource_type+"\" subresource_count=\""+itos(resources_total)+"\" version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\" version_name=\""+VERSION_FULL_NAME+"\">");
|
||||
|
||||
}
|
||||
|
||||
String path = tag->args["path"];
|
||||
String index = tag->args["index"];
|
||||
String type = tag->args["type"];
|
||||
|
||||
|
||||
bool relative=false;
|
||||
if (!path.begins_with("res://")) {
|
||||
path=base_path.plus_file(path).simplify_path();
|
||||
relative=true;
|
||||
}
|
||||
|
||||
|
||||
if (p_map.has(path)) {
|
||||
String np=p_map[path];
|
||||
path=np;
|
||||
}
|
||||
|
||||
if (relative) {
|
||||
//restore relative
|
||||
path=base_path.path_to_file(path);
|
||||
}
|
||||
|
||||
tag->args["path"]=path;
|
||||
tag->args["index"]=index;
|
||||
tag->args["type"]=type;
|
||||
|
||||
} else {
|
||||
|
||||
done=true;
|
||||
}
|
||||
|
||||
String tagt="\t<";
|
||||
if (exit)
|
||||
tagt+="/";
|
||||
tagt+=tag->name;
|
||||
|
||||
for(List<String>::Element *E=order.front();E;E=E->next()) {
|
||||
tagt+=" "+E->get()+"=\""+tag->args[E->get()]+"\"";
|
||||
}
|
||||
tagt+=">";
|
||||
fw->store_line(tagt);
|
||||
if (done)
|
||||
break;
|
||||
close_tag("ext_resource");
|
||||
fw->store_line("\t</ext_resource>");
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (old_format) {
|
||||
if (fw)
|
||||
memdelete(fw);
|
||||
|
||||
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
da->remove(p_path+".depren");
|
||||
memdelete(da);
|
||||
//fuck it, use the old approach;
|
||||
|
||||
WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: "+p_path).utf8().get_data());
|
||||
|
||||
Error err;
|
||||
FileAccess *f2 = FileAccess::open(p_path,FileAccess::READ,&err);
|
||||
if (err!=OK) {
|
||||
ERR_FAIL_COND_V(err!=OK,ERR_FILE_CANT_OPEN);
|
||||
}
|
||||
|
||||
Ref<ResourceInteractiveLoaderXML> ria = memnew( ResourceInteractiveLoaderXML );
|
||||
ria->local_path=Globals::get_singleton()->localize_path(p_path);
|
||||
ria->res_path=ria->local_path;
|
||||
ria->remaps=p_map;
|
||||
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
|
||||
ria->open(f2);
|
||||
|
||||
err = ria->poll();
|
||||
|
||||
while(err==OK) {
|
||||
err=ria->poll();
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(err!=ERR_FILE_EOF,ERR_FILE_CORRUPT);
|
||||
RES res = ria->get_resource();
|
||||
ERR_FAIL_COND_V(!res.is_valid(),ERR_FILE_CORRUPT);
|
||||
|
||||
return ResourceFormatSaverXML::singleton->save(p_path,res);
|
||||
}
|
||||
|
||||
if (!fw) {
|
||||
|
||||
return OK; //nothing to rename, do nothing
|
||||
}
|
||||
|
||||
uint8_t c=f->get_8();
|
||||
while(!f->eof_reached()) {
|
||||
fw->store_8(c);
|
||||
c=f->get_8();
|
||||
}
|
||||
|
||||
bool all_ok = fw->get_error()==OK;
|
||||
|
||||
memdelete(fw);
|
||||
|
||||
if (!all_ok) {
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
da->remove(p_path);
|
||||
da->rename(p_path+".depren",p_path);
|
||||
memdelete(da);
|
||||
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
|
||||
|
||||
|
@ -1686,6 +1870,7 @@ void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
String preload_depts = "deps/"+local_path.md5_text();
|
||||
if (Globals::get_singleton()->has(preload_depts)) {
|
||||
ext_resources.clear();
|
||||
|
@ -1697,7 +1882,7 @@ void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
|
|||
}
|
||||
print_line(local_path+" - EXTERNAL RESOURCES: "+itos(ext_resources.size()));
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
@ -1730,7 +1915,10 @@ String ResourceInteractiveLoaderXML::recognize(FileAccess *p_f) {
|
|||
|
||||
/////////////////////
|
||||
|
||||
Ref<ResourceInteractiveLoader> ResourceFormatLoaderXML::load_interactive(const String &p_path) {
|
||||
Ref<ResourceInteractiveLoader> ResourceFormatLoaderXML::load_interactive(const String &p_path, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_CANT_OPEN;
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
|
||||
|
@ -1816,7 +2004,7 @@ String ResourceFormatLoaderXML::get_resource_type(const String &p_path) const{
|
|||
}
|
||||
|
||||
|
||||
void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String> *p_dependencies) {
|
||||
void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types) {
|
||||
|
||||
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
|
||||
if (!f) {
|
||||
|
@ -1828,11 +2016,27 @@ void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String>
|
|||
ria->local_path=Globals::get_singleton()->localize_path(p_path);
|
||||
ria->res_path=ria->local_path;
|
||||
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
|
||||
ria->get_dependencies(f,p_dependencies);
|
||||
ria->get_dependencies(f,p_dependencies,p_add_types);
|
||||
|
||||
|
||||
}
|
||||
|
||||
Error ResourceFormatLoaderXML::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
|
||||
|
||||
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
|
||||
if (!f) {
|
||||
|
||||
ERR_FAIL_V(ERR_CANT_OPEN);
|
||||
}
|
||||
|
||||
Ref<ResourceInteractiveLoaderXML> ria = memnew( ResourceInteractiveLoaderXML );
|
||||
ria->local_path=Globals::get_singleton()->localize_path(p_path);
|
||||
ria->res_path=ria->local_path;
|
||||
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
|
||||
return ria->rename_dependencies(f,p_path,p_map);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************************/
|
||||
/****************************************************************************************/
|
||||
/****************************************************************************************/
|
||||
|
@ -2024,20 +2228,26 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V
|
|||
return; // don't save it
|
||||
}
|
||||
|
||||
params="resource_type=\""+res->get_save_type()+"\"";
|
||||
if (external_resources.has(res)) {
|
||||
|
||||
if (res->get_path().length() && res->get_path().find("::")==-1) {
|
||||
//external resource
|
||||
String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
|
||||
escape(path);
|
||||
params+=" path=\""+path+"\"";
|
||||
params="external=\""+itos(external_resources[res])+"\"";
|
||||
} else {
|
||||
params="resource_type=\""+res->get_save_type()+"\"";
|
||||
|
||||
//internal resource
|
||||
ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
|
||||
ERR_FAIL_COND(!resource_set.has(res));
|
||||
|
||||
params+=" path=\"local://"+itos(res->get_subindex())+"\"";
|
||||
if (res->get_path().length() && res->get_path().find("::")==-1) {
|
||||
//external resource
|
||||
String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
|
||||
escape(path);
|
||||
params+=" path=\""+path+"\"";
|
||||
} else {
|
||||
|
||||
//internal resource
|
||||
ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
|
||||
ERR_FAIL_COND(!resource_set.has(res));
|
||||
|
||||
params+=" path=\"local://"+itos(res->get_subindex())+"\"";
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
|
@ -2441,11 +2651,12 @@ void ResourceFormatSaverXMLInstance::_find_resources(const Variant& p_variant,bo
|
|||
|
||||
RES res = p_variant.operator RefPtr();
|
||||
|
||||
if (res.is_null())
|
||||
if (res.is_null() || external_resources.has(res))
|
||||
return;
|
||||
|
||||
if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) {
|
||||
external_resources.push_back(res);
|
||||
int index = external_resources.size();
|
||||
external_resources[res]=index;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2533,12 +2744,12 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res
|
|||
enter_tag("resource_file","type=\""+p_resource->get_type()+"\" subresource_count=\""+itos(saved_resources.size()+external_resources.size())+"\" version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\" version_name=\""+VERSION_FULL_NAME+"\"");
|
||||
write_string("\n",false);
|
||||
|
||||
for(List<RES>::Element *E=external_resources.front();E;E=E->next()) {
|
||||
for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) {
|
||||
|
||||
write_tabs();
|
||||
String p = E->get()->get_path();
|
||||
String p = E->key()->get_path();
|
||||
|
||||
enter_tag("ext_resource","path=\""+p+"\" type=\""+E->get()->get_save_type()+"\""); //bundled
|
||||
enter_tag("ext_resource","path=\""+p+"\" type=\""+E->key()->get_save_type()+"\" index=\""+itos(E->get())+"\""); //bundled
|
||||
exit_tag("ext_resource"); //bundled
|
||||
write_string("\n",false);
|
||||
}
|
||||
|
@ -2667,3 +2878,8 @@ void ResourceFormatSaverXML::get_recognized_extensions(const RES& p_resource,Lis
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
ResourceFormatSaverXML* ResourceFormatSaverXML::singleton=NULL;
|
||||
ResourceFormatSaverXML::ResourceFormatSaverXML() {
|
||||
singleton=this;
|
||||
}
|
||||
|
|
|
@ -46,13 +46,21 @@ class ResourceInteractiveLoaderXML : public ResourceInteractiveLoader {
|
|||
|
||||
String name;
|
||||
HashMap<String,String> args;
|
||||
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ Error _parse_array_element(Vector<char> &buff,bool p_number_only,FileAccess *f,bool *end);
|
||||
|
||||
|
||||
struct ExtResource {
|
||||
String path;
|
||||
String type;
|
||||
};
|
||||
|
||||
List<StringName> ext_resources;
|
||||
|
||||
Map<String,String> remaps;
|
||||
|
||||
Map<int,ExtResource> ext_resources;
|
||||
|
||||
int resources_total;
|
||||
int resource_current;
|
||||
|
@ -66,7 +74,7 @@ friend class ResourceFormatLoaderXML;
|
|||
List<Tag> tag_stack;
|
||||
|
||||
List<RES> resource_cache;
|
||||
Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true);
|
||||
Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true,List<String> *r_order=NULL);
|
||||
Error close_tag(const String& p_name);
|
||||
_FORCE_INLINE_ void unquote(String& p_str);
|
||||
Error goto_end_of_tag();
|
||||
|
@ -87,7 +95,8 @@ public:
|
|||
|
||||
void open(FileAccess *p_f);
|
||||
String recognize(FileAccess *p_f);
|
||||
void get_dependencies(FileAccess *p_f,List<String> *p_dependencies);
|
||||
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
|
||||
Error rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map);
|
||||
|
||||
|
||||
~ResourceInteractiveLoaderXML();
|
||||
|
@ -97,12 +106,13 @@ public:
|
|||
class ResourceFormatLoaderXML : public ResourceFormatLoader {
|
||||
public:
|
||||
|
||||
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path);
|
||||
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
virtual void get_dependencies(const String& p_path,List<String> *p_dependencies);
|
||||
virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
|
||||
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
|
||||
|
||||
|
||||
};
|
||||
|
@ -125,7 +135,7 @@ class ResourceFormatSaverXMLInstance {
|
|||
int depth;
|
||||
Set<RES> resource_set;
|
||||
List<RES> saved_resources;
|
||||
List<RES> external_resources;
|
||||
Map<RES,int> external_resources;
|
||||
|
||||
void enter_tag(const char* p_tag,const String& p_args=String());
|
||||
void exit_tag(const char* p_tag);
|
||||
|
@ -148,11 +158,12 @@ public:
|
|||
|
||||
class ResourceFormatSaverXML : public ResourceFormatSaver {
|
||||
public:
|
||||
static ResourceFormatSaverXML* singleton;
|
||||
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
|
||||
virtual bool recognize(const RES& p_resource) const;
|
||||
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
|
||||
|
||||
|
||||
ResourceFormatSaverXML();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -103,10 +103,10 @@ public:
|
|||
|
||||
|
||||
|
||||
Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path) {
|
||||
Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, Error *r_error) {
|
||||
|
||||
//either this
|
||||
Ref<Resource> res = load(p_path);
|
||||
Ref<Resource> res = load(p_path,p_path,r_error);
|
||||
if (res.is_null())
|
||||
return Ref<ResourceInteractiveLoader>();
|
||||
|
||||
|
@ -115,12 +115,13 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const Stri
|
|||
return ril;
|
||||
}
|
||||
|
||||
RES ResourceFormatLoader::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatLoader::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
|
||||
|
||||
String path=p_path;
|
||||
|
||||
//or this must be implemented
|
||||
Ref<ResourceInteractiveLoader> ril = load_interactive(p_path);
|
||||
Ref<ResourceInteractiveLoader> ril = load_interactive(p_path,r_error);
|
||||
if (!ril.is_valid())
|
||||
return RES();
|
||||
ril->set_local_path(p_original_path);
|
||||
|
@ -130,9 +131,14 @@ RES ResourceFormatLoader::load(const String &p_path,const String& p_original_pat
|
|||
Error err = ril->poll();
|
||||
|
||||
if (err==ERR_FILE_EOF) {
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
return ril->get_resource();
|
||||
}
|
||||
|
||||
if (r_error)
|
||||
*r_error=err;
|
||||
|
||||
ERR_FAIL_COND_V(err!=OK,RES());
|
||||
}
|
||||
|
||||
|
@ -140,7 +146,7 @@ RES ResourceFormatLoader::load(const String &p_path,const String& p_original_pat
|
|||
|
||||
}
|
||||
|
||||
void ResourceFormatLoader::get_dependencies(const String& p_path,List<String> *p_dependencies) {
|
||||
void ResourceFormatLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) {
|
||||
|
||||
//do nothing by default
|
||||
}
|
||||
|
@ -149,7 +155,10 @@ void ResourceFormatLoader::get_dependencies(const String& p_path,List<String> *p
|
|||
///////////////////////////////////
|
||||
|
||||
|
||||
RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_no_cache) {
|
||||
RES ResourceLoader::load(const String &p_path, const String& p_type_hint, bool p_no_cache, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_CANT_OPEN;
|
||||
|
||||
String local_path;
|
||||
if (p_path.is_rel_path())
|
||||
|
@ -183,7 +192,7 @@ RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_n
|
|||
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
|
||||
continue;
|
||||
found=true;
|
||||
RES res = loader[i]->load(remapped_path,local_path);
|
||||
RES res = loader[i]->load(remapped_path,local_path,r_error);
|
||||
if (res.is_null())
|
||||
continue;
|
||||
if (!p_no_cache)
|
||||
|
@ -289,9 +298,11 @@ String ResourceLoader::find_complete_path(const String& p_path,const String& p_t
|
|||
return local_path;
|
||||
}
|
||||
|
||||
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path,const String& p_type_hint,bool p_no_cache) {
|
||||
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path,const String& p_type_hint,bool p_no_cache,Error *r_error) {
|
||||
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_CANT_OPEN;
|
||||
|
||||
String local_path;
|
||||
if (p_path.is_rel_path())
|
||||
|
@ -327,7 +338,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
|
|||
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
|
||||
continue;
|
||||
found=true;
|
||||
Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(remapped_path);
|
||||
Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(remapped_path,r_error);
|
||||
if (ril.is_null())
|
||||
continue;
|
||||
if (!p_no_cache)
|
||||
|
@ -352,7 +363,7 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l
|
|||
loader[loader_count++]=p_format_loader;
|
||||
}
|
||||
|
||||
void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_dependencies) {
|
||||
void ResourceLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) {
|
||||
|
||||
|
||||
String local_path;
|
||||
|
@ -372,11 +383,40 @@ void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_depen
|
|||
//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
|
||||
// continue;
|
||||
|
||||
loader[i]->get_dependencies(remapped_path,p_dependencies);
|
||||
loader[i]->get_dependencies(remapped_path,p_dependencies,p_add_types);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Error ResourceLoader::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
|
||||
|
||||
|
||||
String local_path;
|
||||
if (p_path.is_rel_path())
|
||||
local_path="res://"+p_path;
|
||||
else
|
||||
local_path = Globals::get_singleton()->localize_path(p_path);
|
||||
|
||||
String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
|
||||
|
||||
String extension=remapped_path.extension();
|
||||
|
||||
for (int i=0;i<loader_count;i++) {
|
||||
|
||||
if (!loader[i]->recognize(extension))
|
||||
continue;
|
||||
//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
|
||||
// continue;
|
||||
|
||||
return loader[i]->rename_dependencies(p_path,p_map);
|
||||
|
||||
}
|
||||
|
||||
return OK; // ??
|
||||
|
||||
}
|
||||
|
||||
|
||||
String ResourceLoader::guess_full_filename(const String &p_path,const String& p_type) {
|
||||
|
||||
String local_path;
|
||||
|
@ -414,6 +454,9 @@ String ResourceLoader::get_resource_type(const String &p_path) {
|
|||
ResourceLoadErrorNotify ResourceLoader::err_notify=NULL;
|
||||
void *ResourceLoader::err_notify_ud=NULL;
|
||||
|
||||
DependencyErrorNotify ResourceLoader::dep_err_notify=NULL;
|
||||
void *ResourceLoader::dep_err_notify_ud=NULL;
|
||||
|
||||
bool ResourceLoader::abort_on_missing_resource=true;
|
||||
bool ResourceLoader::timestamp_on_load=false;
|
||||
|
||||
|
|
|
@ -57,21 +57,23 @@ public:
|
|||
class ResourceFormatLoader {
|
||||
public:
|
||||
|
||||
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path);
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
|
||||
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
|
||||
bool recognize(const String& p_extension) const;
|
||||
virtual bool handles_type(const String& p_type) const=0;
|
||||
virtual String get_resource_type(const String &p_path) const=0;
|
||||
virtual void get_dependencies(const String& p_path,List<String> *p_dependencies);
|
||||
virtual void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false);
|
||||
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const { return ERR_UNAVAILABLE; }
|
||||
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map) { return OK; }
|
||||
|
||||
virtual ~ResourceFormatLoader() {}
|
||||
};
|
||||
|
||||
|
||||
typedef void (*ResourceLoadErrorNotify)(void *p_ud,const String& p_text);
|
||||
typedef void (*DependencyErrorNotify)(void *p_ud,const String& p_loading,const String& p_which,const String& p_type);
|
||||
|
||||
|
||||
class ResourceLoader {
|
||||
|
@ -86,6 +88,8 @@ class ResourceLoader {
|
|||
|
||||
static void* err_notify_ud;
|
||||
static ResourceLoadErrorNotify err_notify;
|
||||
static void* dep_err_notify_ud;
|
||||
static DependencyErrorNotify dep_err_notify;
|
||||
static bool abort_on_missing_resource;
|
||||
|
||||
static String find_complete_path(const String& p_path,const String& p_type);
|
||||
|
@ -93,14 +97,15 @@ public:
|
|||
|
||||
|
||||
|
||||
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false);
|
||||
static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false);
|
||||
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
|
||||
static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
|
||||
static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path);
|
||||
|
||||
static void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions);
|
||||
static void add_resource_format_loader(ResourceFormatLoader *p_format_loader);
|
||||
static String get_resource_type(const String &p_path);
|
||||
static void get_dependencies(const String& p_path,List<String> *p_dependencies);
|
||||
static void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false);
|
||||
static Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
|
||||
|
||||
static String guess_full_filename(const String &p_path,const String& p_type);
|
||||
|
||||
|
@ -108,6 +113,11 @@ public:
|
|||
|
||||
static void notify_load_error(const String& p_err) { if (err_notify) err_notify(err_notify_ud,p_err); }
|
||||
static void set_error_notify_func(void* p_ud,ResourceLoadErrorNotify p_err_notify) { err_notify=p_err_notify; err_notify_ud=p_ud;}
|
||||
|
||||
static void notify_dependency_error(const String& p_path,const String& p_dependency,const String& p_type) { if (dep_err_notify) dep_err_notify(dep_err_notify_ud,p_path,p_dependency,p_type); }
|
||||
static void set_dependency_error_notify_func(void* p_ud,DependencyErrorNotify p_err_notify) { dep_err_notify=p_err_notify; dep_err_notify_ud=p_ud;}
|
||||
|
||||
|
||||
static void set_abort_on_missing_resources(bool p_abort) { abort_on_missing_resource=p_abort; }
|
||||
static bool get_abort_on_missing_resources() { return abort_on_missing_resource; }
|
||||
};
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0)=0;
|
||||
virtual bool recognize(const RES& p_resource) const=0;
|
||||
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const=0;
|
||||
|
||||
|
||||
virtual ~ResourceFormatSaver() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -30,7 +30,10 @@
|
|||
#include "os/file_access.h"
|
||||
#include "translation.h"
|
||||
|
||||
RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path) {
|
||||
RES TranslationLoaderPO::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_CANT_OPEN;
|
||||
|
||||
FileAccess *f=FileAccess::open(p_path,FileAccess::READ);
|
||||
ERR_FAIL_COND_V(!f,RES());
|
||||
|
@ -49,6 +52,8 @@ RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path
|
|||
String msg_id;
|
||||
String msg_str;
|
||||
String config;
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CORRUPT;
|
||||
|
||||
Ref<Translation> translation = Ref<Translation>( memnew( Translation ));
|
||||
int line = 1;
|
||||
|
@ -174,6 +179,8 @@ RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path
|
|||
}
|
||||
}
|
||||
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
return translation;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
class TranslationLoaderPO : public ResourceFormatLoader {
|
||||
public:
|
||||
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -779,8 +779,10 @@ EventStreamChibi::EventStreamChibi() {
|
|||
|
||||
|
||||
|
||||
RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatLoaderChibi::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CANT_OPEN;
|
||||
String el = p_path.extension().to_lower();
|
||||
|
||||
CPFileAccessWrapperImpl f;
|
||||
|
@ -791,6 +793,8 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
|
|||
CPLoader_IT loader(&f);
|
||||
CPLoader::Error err = loader.load_song(p_path.utf8().get_data(),&esc->song,false);
|
||||
ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
return esc;
|
||||
|
||||
|
@ -800,6 +804,8 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
|
|||
CPLoader_XM loader(&f);
|
||||
CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false);
|
||||
ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
return esc;
|
||||
|
||||
} else if (el=="s3m") {
|
||||
|
@ -808,6 +814,9 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
|
|||
CPLoader_S3M loader(&f);
|
||||
CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false);
|
||||
ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
return esc;
|
||||
|
||||
} else if (el=="mod") {
|
||||
|
@ -816,6 +825,8 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
|
|||
CPLoader_MOD loader(&f);
|
||||
CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false);
|
||||
ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
return esc;
|
||||
}
|
||||
|
||||
|
|
|
@ -301,7 +301,7 @@ public:
|
|||
class ResourceFormatLoaderChibi : public ResourceFormatLoader {
|
||||
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -64,8 +64,10 @@ static const DDSFormatInfo dds_format_info[DDS_MAX]={
|
|||
};
|
||||
|
||||
|
||||
RES ResourceFormatDDS::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatDDS::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_CANT_OPEN;
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
|
||||
|
@ -73,6 +75,8 @@ RES ResourceFormatDDS::load(const String &p_path,const String& p_original_path)
|
|||
return RES();
|
||||
|
||||
FileAccessRef fref(f);
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CORRUPT;
|
||||
|
||||
ERR_EXPLAIN("Unable to open DDS texture file: "+p_path);
|
||||
ERR_FAIL_COND_V(err!=OK,RES());
|
||||
|
@ -427,6 +431,10 @@ RES ResourceFormatDDS::load(const String &p_path,const String& p_original_path)
|
|||
Ref<ImageTexture> texture = memnew( ImageTexture );
|
||||
texture->create_from_image(img);
|
||||
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
|
||||
return texture;
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
class ResourceFormatDDS : public ResourceFormatLoader{
|
||||
public:
|
||||
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -366,8 +366,9 @@ AudioStreamMPC::~AudioStreamMPC() {
|
|||
|
||||
|
||||
|
||||
RES ResourceFormatLoaderAudioStreamMPC::load(const String &p_path,const String& p_original_path) {
|
||||
|
||||
RES ResourceFormatLoaderAudioStreamMPC::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
if (r_error)
|
||||
*r_error=OK; //streamed so it will always work..
|
||||
AudioStreamMPC *mpc_stream = memnew(AudioStreamMPC);
|
||||
mpc_stream->set_file(p_path);
|
||||
return Ref<AudioStreamMPC>(mpc_stream);
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
|
||||
class ResourceFormatLoaderAudioStreamMPC : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -22,8 +22,10 @@ enum PVRFLags {
|
|||
|
||||
|
||||
|
||||
RES ResourceFormatPVR::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatPVR::load(const String &p_path,const String& p_original_path,Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_CANT_OPEN;
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
|
||||
|
@ -34,6 +36,8 @@ RES ResourceFormatPVR::load(const String &p_path,const String& p_original_path)
|
|||
|
||||
ERR_FAIL_COND_V(err,RES());
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CORRUPT;
|
||||
|
||||
uint32_t hsize = f->get_32();
|
||||
|
||||
|
@ -135,6 +139,9 @@ RES ResourceFormatPVR::load(const String &p_path,const String& p_original_path)
|
|||
Ref<ImageTexture> texture = memnew( ImageTexture );
|
||||
texture->create_from_image(image,tex_flags);
|
||||
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
return texture;
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
class ResourceFormatPVR : public ResourceFormatLoader{
|
||||
public:
|
||||
|
||||
virtual RES load(const String &p_path,const String& p_original_path);
|
||||
virtual RES load(const String &p_path,const String& p_original_path,Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -530,7 +530,10 @@ AudioStreamSpeex::~AudioStreamSpeex() {
|
|||
unload();
|
||||
}
|
||||
|
||||
RES ResourceFormatLoaderAudioStreamSpeex::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatLoaderAudioStreamSpeex::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
AudioStreamSpeex *stream = memnew(AudioStreamSpeex);
|
||||
stream->set_file(p_path);
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
|
||||
class ResourceFormatLoaderAudioStreamSpeex : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -102,7 +102,7 @@ public:
|
|||
|
||||
class ResourceFormatLoaderVideoStreamTheora : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -525,7 +525,9 @@ VideoStreamTheoraplayer::VideoStreamTheoraplayer() {
|
|||
};
|
||||
|
||||
|
||||
RES ResourceFormatLoaderVideoStreamTheoraplayer::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatLoaderVideoStreamTheoraplayer::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
VideoStreamTheoraplayer *stream = memnew(VideoStreamTheoraplayer);
|
||||
stream->set_file(p_path);
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
class ResourceFormatLoaderVideoStreamTheoraplayer : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -385,7 +385,9 @@ AudioStreamOGGVorbis::~AudioStreamOGGVorbis() {
|
|||
|
||||
|
||||
|
||||
RES ResourceFormatLoaderAudioStreamOGGVorbis::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatLoaderAudioStreamOGGVorbis::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
AudioStreamOGGVorbis *ogg_stream = memnew(AudioStreamOGGVorbis);
|
||||
ogg_stream->set_file(p_path);
|
||||
|
|
|
@ -111,7 +111,7 @@ public:
|
|||
|
||||
class ResourceFormatLoaderAudioStreamOGGVorbis : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -2710,7 +2710,10 @@ GDScriptLanguage::~GDScriptLanguage() {
|
|||
|
||||
/*************** RESOURCE ***************/
|
||||
|
||||
RES ResourceFormatLoaderGDScript::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatLoaderGDScript::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CANT_OPEN;
|
||||
|
||||
GDScript *script = memnew( GDScript );
|
||||
|
||||
|
@ -2742,6 +2745,8 @@ RES ResourceFormatLoaderGDScript::load(const String &p_path,const String& p_orig
|
|||
|
||||
script->reload();
|
||||
}
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
return scriptres;
|
||||
}
|
||||
|
|
|
@ -557,7 +557,7 @@ public:
|
|||
class ResourceFormatLoaderGDScript : public ResourceFormatLoader {
|
||||
public:
|
||||
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -274,7 +274,7 @@ Button* AcceptDialog::add_button(const String& p_text,bool p_right,const String&
|
|||
}
|
||||
|
||||
if (p_action!="") {
|
||||
button->connect("pressed",this,"_custom_action",make_binds(p_action));
|
||||
button->connect("pressed",this,"_custom_action",varray(p_action));
|
||||
}
|
||||
|
||||
return button;
|
||||
|
|
|
@ -187,6 +187,7 @@ void ItemList::select(int p_idx,bool p_single){
|
|||
}
|
||||
|
||||
current=p_idx;
|
||||
ensure_selected_visible=false;
|
||||
} else {
|
||||
|
||||
if (items[p_idx].selectable) {
|
||||
|
@ -195,6 +196,7 @@ void ItemList::select(int p_idx,bool p_single){
|
|||
}
|
||||
update();
|
||||
|
||||
|
||||
}
|
||||
void ItemList::unselect(int p_idx){
|
||||
|
||||
|
@ -246,12 +248,14 @@ void ItemList::remove_item(int p_idx){
|
|||
update();
|
||||
shape_changed=true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ItemList::clear(){
|
||||
|
||||
items.clear();
|
||||
current=-1;
|
||||
ensure_selected_visible=false;
|
||||
update();
|
||||
|
||||
}
|
||||
|
@ -602,18 +606,8 @@ void ItemList::_input_event(const InputEvent& p_event) {
|
|||
|
||||
void ItemList::ensure_current_is_visible() {
|
||||
|
||||
if (current>=0 && current <=items.size()) {
|
||||
|
||||
Rect2 r = items[current].rect_cache;
|
||||
int from = scroll_bar->get_val();
|
||||
int to = from + scroll_bar->get_page();
|
||||
|
||||
if (r.pos.y < from) {
|
||||
scroll_bar->set_val(r.pos.y);
|
||||
} else if (r.pos.y+r.size.y > to) {
|
||||
scroll_bar->set_val(r.pos.y+r.size.y - (to-from));
|
||||
}
|
||||
}
|
||||
ensure_selected_visible=true;
|
||||
update();
|
||||
}
|
||||
|
||||
void ItemList::_notification(int p_what) {
|
||||
|
@ -928,6 +922,24 @@ void ItemList::_notification(int p_what) {
|
|||
draw_line(Vector2(bg->get_margin(MARGIN_LEFT),base_ofs.y+separators[i]),Vector2(size.width-bg->get_margin(MARGIN_LEFT),base_ofs.y+separators[i]),guide_color);
|
||||
}
|
||||
|
||||
|
||||
if (ensure_selected_visible && current>=0 && current <=items.size()) {
|
||||
|
||||
Rect2 r = items[current].rect_cache;
|
||||
int from = scroll_bar->get_val();
|
||||
int to = from + scroll_bar->get_page();
|
||||
|
||||
if (r.pos.y < from) {
|
||||
scroll_bar->set_val(r.pos.y);
|
||||
} else if (r.pos.y+r.size.y > to) {
|
||||
scroll_bar->set_val(r.pos.y+r.size.y - (to-from));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
ensure_selected_visible=false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1095,6 +1107,7 @@ ItemList::ItemList() {
|
|||
set_focus_mode(FOCUS_ALL);
|
||||
current_columns=1;
|
||||
search_time_msec=0;
|
||||
ensure_selected_visible=false;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ private:
|
|||
|
||||
bool shape_changed;
|
||||
|
||||
bool ensure_selected_visible;
|
||||
|
||||
Vector<Item> items;
|
||||
Vector<int> separators;
|
||||
|
||||
|
|
|
@ -2360,6 +2360,11 @@ void Tree::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_VISIBILITY_CHANGED) {
|
||||
|
||||
drag_touching=false;
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_TREE) {
|
||||
|
||||
update_cache();;
|
||||
|
|
|
@ -31,9 +31,11 @@
|
|||
#include "io/image_loader.h"
|
||||
#include "globals.h"
|
||||
#include "os/os.h"
|
||||
RES ResourceFormatLoaderImage::load(const String &p_path,const String& p_original_path) {
|
||||
|
||||
RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_CANT_OPEN;
|
||||
|
||||
if (p_path.extension()=="cube") {
|
||||
// open as cubemap txture
|
||||
|
||||
|
@ -83,6 +85,8 @@ RES ResourceFormatLoaderImage::load(const String &p_path,const String& p_origina
|
|||
memdelete(f);
|
||||
|
||||
cubemap->set_name(p_path.get_file());
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
return cubemap;
|
||||
|
||||
|
@ -112,6 +116,8 @@ RES ResourceFormatLoaderImage::load(const String &p_path,const String& p_origina
|
|||
|
||||
ERR_EXPLAIN("Failed loading image: "+p_path);
|
||||
ERR_FAIL_COND_V(err, RES());
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CORRUPT;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
@ -199,6 +205,9 @@ RES ResourceFormatLoaderImage::load(const String &p_path,const String& p_origina
|
|||
print_line(" -make texture: "+rtos(total));
|
||||
}
|
||||
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
return RES( texture );
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class ResourceFormatLoaderImage : public ResourceFormatLoader {
|
|||
int max_texture_size;
|
||||
public:
|
||||
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -31,13 +31,18 @@
|
|||
#include "scene/resources/sample.h"
|
||||
|
||||
|
||||
RES ResourceFormatLoaderWAV::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatLoaderWAV::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CANT_OPEN;
|
||||
|
||||
Error err;
|
||||
FileAccess *file=FileAccess::open(p_path, FileAccess::READ,&err);
|
||||
|
||||
ERR_FAIL_COND_V( err!=OK, RES() );
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CORRUPT;
|
||||
|
||||
/* CHECK RIFF */
|
||||
char riff[5];
|
||||
riff[4]=0;
|
||||
|
@ -244,6 +249,9 @@ RES ResourceFormatLoaderWAV::load(const String &p_path,const String& p_original_
|
|||
file->close();
|
||||
memdelete(file);
|
||||
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
return sample;
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
class ResourceFormatLoaderWAV : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -205,7 +205,10 @@ BitMap::BitMap() {
|
|||
//////////////////////////////////////
|
||||
|
||||
|
||||
RES ResourceFormatLoaderBitMap::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatLoaderBitMap::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CANT_OPEN;
|
||||
|
||||
BitMap* ptr = memnew(BitMap);
|
||||
Ref<BitMap> bitmap( ptr );
|
||||
|
@ -219,6 +222,8 @@ RES ResourceFormatLoaderBitMap::load(const String &p_path,const String& p_origin
|
|||
ERR_FAIL_COND_V(err, RES());
|
||||
|
||||
bitmap->create_from_image_alpha(image);
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
return bitmap;
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ class ResourceFormatLoaderBitMap : public ResourceFormatLoader {
|
|||
|
||||
public:
|
||||
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -219,7 +219,10 @@ Shader::~Shader() {
|
|||
|
||||
|
||||
|
||||
RES ResourceFormatLoaderShader::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatLoaderShader::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CANT_OPEN;
|
||||
|
||||
String fragment_code;
|
||||
String vertex_code;
|
||||
|
@ -235,6 +238,8 @@ RES ResourceFormatLoaderShader::load(const String &p_path,const String& p_origin
|
|||
ERR_FAIL_COND_V(err,RES());
|
||||
String base_path = p_path.get_base_dir();
|
||||
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CORRUPT;
|
||||
|
||||
Ref<Shader> shader;//( memnew( Shader ) );
|
||||
|
||||
|
@ -435,6 +440,8 @@ RES ResourceFormatLoaderShader::load(const String &p_path,const String& p_origin
|
|||
|
||||
f->close();
|
||||
memdelete(f);
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ public:
|
|||
|
||||
class ResourceFormatLoaderShader : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
|
@ -601,7 +601,9 @@ Theme::~Theme()
|
|||
|
||||
|
||||
|
||||
RES ResourceFormatLoaderTheme::load(const String &p_path,const String& p_original_path) {
|
||||
RES ResourceFormatLoaderTheme::load(const String &p_path, const String& p_original_path, Error *r_error) {
|
||||
if (r_error)
|
||||
*r_error=ERR_CANT_OPEN;
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
|
||||
|
@ -611,6 +613,8 @@ RES ResourceFormatLoaderTheme::load(const String &p_path,const String& p_origina
|
|||
String base_path = p_path.get_base_dir();
|
||||
Ref<Theme> theme( memnew( Theme ) );
|
||||
Map<StringName,Variant> library;
|
||||
if (r_error)
|
||||
*r_error=ERR_FILE_CORRUPT;
|
||||
|
||||
bool reading_library=false;
|
||||
int line=0;
|
||||
|
@ -1003,6 +1007,9 @@ RES ResourceFormatLoaderTheme::load(const String &p_path,const String& p_origina
|
|||
f->close();
|
||||
memdelete(f);
|
||||
|
||||
if (r_error)
|
||||
*r_error=OK;
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ public:
|
|||
|
||||
class ResourceFormatLoaderTheme : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="");
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
|
512
tools/editor/dependency_editor.cpp
Normal file
512
tools/editor/dependency_editor.cpp
Normal file
|
@ -0,0 +1,512 @@
|
|||
#include "dependency_editor.h"
|
||||
#include "os/file_access.h"
|
||||
#include "scene/gui/margin_container.h"
|
||||
#include "io/resource_loader.h"
|
||||
#include "editor_node.h"
|
||||
|
||||
void DependencyEditor::_notification(int p_what){
|
||||
|
||||
|
||||
}
|
||||
|
||||
void DependencyEditor::_searched(const String& p_path) {
|
||||
|
||||
Map<String,String> dep_rename;
|
||||
dep_rename[replacing]=p_path;
|
||||
|
||||
|
||||
ResourceLoader::rename_dependencies(editing,dep_rename);
|
||||
|
||||
_update_list();
|
||||
_update_file();
|
||||
}
|
||||
|
||||
void DependencyEditor::_load_pressed(Object* p_item,int p_cell,int p_button){
|
||||
|
||||
TreeItem *ti=p_item->cast_to<TreeItem>();
|
||||
String fname = ti->get_text(0);
|
||||
replacing = ti->get_text(1);
|
||||
|
||||
search->set_title("Search Replacement For: "+replacing.get_file());
|
||||
|
||||
search->clear_filters();
|
||||
List<String> ext;
|
||||
ResourceLoader::get_recognized_extensions_for_type(ti->get_metadata(0),&ext);
|
||||
for (List<String>::Element *E=ext.front();E;E=E->next()) {
|
||||
search->add_filter("*"+E->get());
|
||||
}
|
||||
search->popup_centered_ratio();
|
||||
|
||||
}
|
||||
|
||||
void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String,Map<String,String> >& candidates){
|
||||
|
||||
for(int i=0;i<efsd->get_subdir_count();i++) {
|
||||
_fix_and_find(efsd->get_subdir(i),candidates);
|
||||
}
|
||||
|
||||
for(int i=0;i<efsd->get_file_count();i++) {
|
||||
|
||||
String file = efsd->get_file(i);
|
||||
if (!candidates.has(file))
|
||||
continue;
|
||||
|
||||
String path = efsd->get_file_path(i);
|
||||
Map<String,String> &ss = candidates[file];
|
||||
|
||||
|
||||
for(Map<String,String>::Element *E=candidates[file].front();E;E=E->next()) {
|
||||
|
||||
if (E->get()==String()) {
|
||||
E->get()=path;
|
||||
continue;
|
||||
}
|
||||
|
||||
//must match the best, using subdirs
|
||||
String existing=E->get().replace_first("res://","");
|
||||
String current=path.replace_first("res://","");
|
||||
String lost=E->key().replace_first("res://","");
|
||||
|
||||
Vector<String> existingv=existing.split("/");
|
||||
existingv.invert();
|
||||
Vector<String> currentv=current.split("/");
|
||||
currentv.invert();
|
||||
Vector<String> lostv=lost.split("/");
|
||||
lostv.invert();
|
||||
|
||||
int existing_score=0;
|
||||
int current_score=0;
|
||||
|
||||
for(int j=0;j<lostv.size();j++) {
|
||||
|
||||
if (j<existingv.size() && lostv[j]==existingv[j]) {
|
||||
existing_score++;
|
||||
}
|
||||
if (j<currentv.size() && lostv[j]==currentv[j]) {
|
||||
current_score++;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_score > existing_score) {
|
||||
|
||||
//if it was the same, could track distance to new path but..
|
||||
|
||||
E->get()=path; //replace by more accurate
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DependencyEditor::_fix_all(){
|
||||
|
||||
if (!EditorFileSystem::get_singleton()->get_filesystem())
|
||||
return;
|
||||
|
||||
Map<String,Map<String,String> > candidates;
|
||||
|
||||
for (List<String>::Element *E=missing.front();E;E=E->next()) {
|
||||
|
||||
String base = E->get().get_file();
|
||||
if (!candidates.has(base)) {
|
||||
candidates[base]=Map<String,String>();
|
||||
}
|
||||
|
||||
candidates[base][E->get()]="";
|
||||
}
|
||||
|
||||
_fix_and_find(EditorFileSystem::get_singleton()->get_filesystem(),candidates);
|
||||
|
||||
Map<String,String> remaps;
|
||||
|
||||
for (Map<String,Map<String,String> >::Element *E=candidates.front();E;E=E->next()) {
|
||||
|
||||
for (Map<String,String>::Element *F=E->get().front();F;F=F->next()) {
|
||||
|
||||
if (F->get()!=String()) {
|
||||
remaps[F->key()]=F->get();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (remaps.size()) {
|
||||
|
||||
ResourceLoader::rename_dependencies(editing,remaps);
|
||||
|
||||
_update_list();
|
||||
_update_file();
|
||||
}
|
||||
}
|
||||
|
||||
void DependencyEditor::_update_file() {
|
||||
|
||||
EditorFileSystem::get_singleton()->update_file(editing);
|
||||
|
||||
}
|
||||
|
||||
void DependencyEditor::_update_list() {
|
||||
|
||||
List<String> deps;
|
||||
ResourceLoader::get_dependencies(editing,&deps,true);
|
||||
|
||||
tree->clear();
|
||||
missing.clear();
|
||||
|
||||
TreeItem *root = tree->create_item();
|
||||
|
||||
Ref<Texture> folder = get_icon("folder","FileDialog");
|
||||
|
||||
bool broken=false;
|
||||
|
||||
for(List<String>::Element *E=deps.front();E;E=E->next()) {
|
||||
|
||||
TreeItem *item = tree->create_item(root);
|
||||
|
||||
String n = E->get();
|
||||
String path;
|
||||
String type;
|
||||
|
||||
if (n.find("::")!=-1) {
|
||||
path = n.get_slice("::",0);
|
||||
type = n.get_slice("::",1);
|
||||
} else {
|
||||
path=n;
|
||||
type="Resource";
|
||||
}
|
||||
String name = path.get_file();
|
||||
|
||||
Ref<Texture> icon;
|
||||
if (has_icon(type,"EditorIcons")) {
|
||||
icon=get_icon(type,"EditorIcons");
|
||||
} else {
|
||||
icon=get_icon("Object","EditorIcons");
|
||||
}
|
||||
item->set_text(0,name);
|
||||
item->set_icon(0,icon);
|
||||
item->set_metadata(0,type);
|
||||
item->set_text(1,path);
|
||||
|
||||
if (!FileAccess::exists(path)) {
|
||||
item->set_custom_color(1,Color(1,0.4,0.3));
|
||||
missing.push_back(path);
|
||||
broken=true;
|
||||
}
|
||||
|
||||
item->add_button(1,folder,0);
|
||||
}
|
||||
|
||||
fixdeps->set_disabled(!broken);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DependencyEditor::edit(const String& p_path) {
|
||||
|
||||
|
||||
editing=p_path;
|
||||
set_title("Dependencies For: "+p_path.get_file());
|
||||
|
||||
_update_list();
|
||||
popup_centered_ratio();
|
||||
|
||||
if (EditorNode::get_singleton()->is_scene_open(p_path)) {
|
||||
EditorNode::get_singleton()->show_warning("Scene '"+p_path.get_file()+"' is currently being edited.\nChanges will not take effect unless reloaded.");
|
||||
} else if (ResourceCache::has(p_path)) {
|
||||
EditorNode::get_singleton()->show_warning("Resource '"+p_path.get_file()+"' is in use.\nChanges will take effect when reloaded.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DependencyEditor::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_searched"),&DependencyEditor::_searched);
|
||||
ObjectTypeDB::bind_method(_MD("_load_pressed"),&DependencyEditor::_load_pressed);
|
||||
ObjectTypeDB::bind_method(_MD("_fix_all"),&DependencyEditor::_fix_all);
|
||||
|
||||
}
|
||||
|
||||
DependencyEditor::DependencyEditor() {
|
||||
|
||||
VBoxContainer *vb = memnew( VBoxContainer );
|
||||
vb->set_name("Dependencies");
|
||||
add_child(vb);
|
||||
set_child_rect(vb);
|
||||
|
||||
tree = memnew( Tree );
|
||||
tree->set_columns(2);
|
||||
tree->set_column_titles_visible(true);
|
||||
tree->set_column_title(0,"Resource");
|
||||
tree->set_column_title(1,"Path");
|
||||
tree->set_hide_root(true);
|
||||
tree->connect("button_pressed",this,"_load_pressed");
|
||||
|
||||
HBoxContainer *hbc = memnew( HBoxContainer );
|
||||
Label *label = memnew( Label("Dependencies:"));
|
||||
hbc->add_child(label);
|
||||
hbc->add_spacer();
|
||||
fixdeps = memnew( Button("Fix Broken"));
|
||||
hbc->add_child(fixdeps);
|
||||
fixdeps->connect("pressed",this,"_fix_all");
|
||||
|
||||
vb->add_child(hbc);
|
||||
|
||||
MarginContainer *mc = memnew( MarginContainer );
|
||||
mc->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
mc->add_child(tree);
|
||||
vb->add_child(mc);
|
||||
|
||||
set_title("Dependency Editor");
|
||||
search = memnew( EditorFileDialog );
|
||||
search->connect("file_selected",this,"_searched");
|
||||
search->set_mode(EditorFileDialog::MODE_OPEN_FILE);
|
||||
search->set_title("Search Replacement Resource:");
|
||||
add_child(search);
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
void DependencyEditorOwners::_fill_owners(EditorFileSystemDirectory *efsd) {
|
||||
|
||||
if (!efsd)
|
||||
return;
|
||||
|
||||
for(int i=0;i<efsd->get_subdir_count();i++) {
|
||||
_fill_owners(efsd->get_subdir(i));
|
||||
}
|
||||
|
||||
for(int i=0;i<efsd->get_file_count();i++) {
|
||||
|
||||
Vector<String> deps = efsd->get_file_deps(i);
|
||||
//print_line(":::"+efsd->get_file_path(i));
|
||||
bool found=false;
|
||||
for(int j=0;j<deps.size();j++) {
|
||||
//print_line("\t"+deps[j]+" vs "+editing);
|
||||
if (deps[j]==editing) {
|
||||
//print_line("found");
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
Ref<Texture> icon;
|
||||
String type=efsd->get_file_type(i);
|
||||
if (!has_icon(type,"EditorIcons")) {
|
||||
icon=get_icon("Object","EditorIcons");
|
||||
} else {
|
||||
icon=get_icon(type,"EditorIcons");
|
||||
}
|
||||
|
||||
owners->add_item(efsd->get_file_path(i),icon);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DependencyEditorOwners::show(const String& p_path) {
|
||||
|
||||
editing=p_path;
|
||||
owners->clear();
|
||||
_fill_owners(EditorFileSystem::get_singleton()->get_filesystem());
|
||||
popup_centered_ratio();
|
||||
|
||||
set_title("Owners Of: "+p_path.get_file());
|
||||
|
||||
}
|
||||
|
||||
DependencyEditorOwners::DependencyEditorOwners() {
|
||||
|
||||
|
||||
owners = memnew( ItemList );
|
||||
add_child(owners);
|
||||
set_child_rect(owners);
|
||||
|
||||
|
||||
}
|
||||
|
||||
///////////////////////
|
||||
|
||||
|
||||
void DependencyRemoveDialog::_fill_owners(EditorFileSystemDirectory *efsd) {
|
||||
|
||||
if (!efsd)
|
||||
return;
|
||||
|
||||
for(int i=0;i<efsd->get_subdir_count();i++) {
|
||||
_fill_owners(efsd->get_subdir(i));
|
||||
}
|
||||
|
||||
for(int i=0;i<efsd->get_file_count();i++) {
|
||||
|
||||
Vector<String> deps = efsd->get_file_deps(i);
|
||||
//print_line(":::"+efsd->get_file_path(i));
|
||||
Set<String> met;
|
||||
for(int j=0;j<deps.size();j++) {
|
||||
if (files.has(deps[j])) {
|
||||
met.insert(deps[j]);
|
||||
}
|
||||
}
|
||||
if (!met.size())
|
||||
continue;
|
||||
|
||||
exist=true;
|
||||
|
||||
Ref<Texture> icon;
|
||||
String type=efsd->get_file_type(i);
|
||||
if (!has_icon(type,"EditorIcons")) {
|
||||
icon=get_icon("Object","EditorIcons");
|
||||
} else {
|
||||
icon=get_icon(type,"EditorIcons");
|
||||
}
|
||||
|
||||
|
||||
for(Set<String>::Element *E=met.front();E;E=E->next()) {
|
||||
|
||||
String which = E->get();
|
||||
if (!files[which]) {
|
||||
TreeItem *ti=owners->create_item(owners->get_root());
|
||||
ti->set_text(0,which.get_file());
|
||||
files[which]=ti;
|
||||
|
||||
}
|
||||
TreeItem *ti=owners->create_item(files[which]);
|
||||
ti->set_text(0,efsd->get_file_path(i));
|
||||
ti->set_icon(0,icon);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DependencyRemoveDialog::show(const Vector<String> &to_erase) {
|
||||
|
||||
exist=false;
|
||||
owners->clear();
|
||||
files.clear();
|
||||
TreeItem *root=owners->create_item();
|
||||
for(int i=0;i<to_erase.size();i++) {
|
||||
files[to_erase[i]]=NULL;
|
||||
}
|
||||
|
||||
_fill_owners(EditorFileSystem::get_singleton()->get_filesystem());
|
||||
|
||||
if (exist) {
|
||||
owners->show();
|
||||
text->set_text("The files being removed are required by other resources in order for them to work.\nRemove them anyway? (no undo)");
|
||||
popup_centered_minsize(Size2(500,220));
|
||||
} else {
|
||||
owners->hide();
|
||||
text->set_text("Remove selected files from the project? (no undo)");
|
||||
popup_centered_minsize(Size2(400,100));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DependencyRemoveDialog::ok_pressed() {
|
||||
|
||||
|
||||
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
for (Map<String,TreeItem*>::Element *E=files.front();E;E=E->next()) {
|
||||
|
||||
da->remove(E->key());
|
||||
EditorFileSystem::get_singleton()->update_file(E->key());
|
||||
}
|
||||
memdelete(da);
|
||||
|
||||
}
|
||||
|
||||
DependencyRemoveDialog::DependencyRemoveDialog() {
|
||||
|
||||
VBoxContainer *vb = memnew( VBoxContainer );
|
||||
add_child(vb);
|
||||
set_child_rect(vb);
|
||||
|
||||
text = memnew( Label );
|
||||
vb->add_child(text);
|
||||
|
||||
owners = memnew( Tree );
|
||||
owners->set_hide_root(true);
|
||||
vb->add_child(owners);
|
||||
owners->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
get_ok()->set_text("Remove");
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
|
||||
|
||||
void DependencyErrorDialog::show(const String& p_for_file,const Vector<String> &report) {
|
||||
|
||||
|
||||
for_file=p_for_file;
|
||||
set_title("Error loading: "+p_for_file.get_file());
|
||||
files->clear();
|
||||
|
||||
TreeItem *root = files->create_item(NULL);
|
||||
for(int i=0;i<report.size();i++) {
|
||||
|
||||
String dep;
|
||||
String type="Object";
|
||||
dep=report[i].get_slice("::",0);
|
||||
if (report[i].get_slice_count("::")>0)
|
||||
type=report[i].get_slice("::",1);
|
||||
|
||||
Ref<Texture> icon;
|
||||
if (!has_icon(type,"EditorIcons")) {
|
||||
icon=get_icon("Object","EditorIcons");
|
||||
} else {
|
||||
icon=get_icon(type,"EditorIcons");
|
||||
}
|
||||
|
||||
TreeItem *ti=files->create_item(root);
|
||||
ti->set_text(0,dep);
|
||||
ti->set_icon(0,icon);
|
||||
|
||||
}
|
||||
|
||||
popup_centered_minsize(Size2(500,220));
|
||||
|
||||
}
|
||||
|
||||
void DependencyErrorDialog::ok_pressed() {
|
||||
|
||||
EditorNode::get_singleton()->load_scene(for_file,true);
|
||||
}
|
||||
|
||||
void DependencyErrorDialog::custom_action(const String&) {
|
||||
|
||||
EditorNode::get_singleton()->fix_dependencies(for_file);
|
||||
}
|
||||
|
||||
DependencyErrorDialog::DependencyErrorDialog() {
|
||||
|
||||
VBoxContainer *vb = memnew( VBoxContainer );
|
||||
add_child(vb);
|
||||
set_child_rect(vb);
|
||||
|
||||
|
||||
files = memnew( Tree );
|
||||
files->set_hide_root(true);
|
||||
vb->add_margin_child("Scene failed to load due to missing dependencies:",files,true);
|
||||
files->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
get_ok()->set_text("Open Anyway");
|
||||
|
||||
text = memnew( Label );
|
||||
vb->add_child(text);
|
||||
text->set_text("Which action should be taken?");
|
||||
|
||||
|
||||
fdep=add_button("Fix Dependencies",true,"fixdeps");
|
||||
|
||||
set_title("Errors loading!");
|
||||
|
||||
}
|
94
tools/editor/dependency_editor.h
Normal file
94
tools/editor/dependency_editor.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
#ifndef DEPENDENCY_EDITOR_H
|
||||
#define DEPENDENCY_EDITOR_H
|
||||
|
||||
#include "scene/gui/dialogs.h"
|
||||
#include "scene/gui/tree.h"
|
||||
#include "scene/gui/tab_container.h"
|
||||
#include "editor_file_dialog.h"
|
||||
|
||||
class EditorFileSystemDirectory;
|
||||
|
||||
class DependencyEditor : public AcceptDialog {
|
||||
OBJ_TYPE(DependencyEditor,AcceptDialog);
|
||||
|
||||
|
||||
Tree *tree;
|
||||
Button *fixdeps;
|
||||
|
||||
EditorFileDialog *search;
|
||||
|
||||
String replacing;
|
||||
String editing;
|
||||
List<String> missing;
|
||||
|
||||
|
||||
void _fix_and_find(EditorFileSystemDirectory *efsd, Map<String,Map<String,String> >& candidates);
|
||||
|
||||
void _searched(const String& p_path);
|
||||
void _load_pressed(Object* p_item,int p_cell,int p_button);
|
||||
void _fix_all();
|
||||
void _update_list();
|
||||
|
||||
void _update_file();
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
public:
|
||||
|
||||
|
||||
void edit(const String& p_path);
|
||||
DependencyEditor();
|
||||
};
|
||||
|
||||
class DependencyEditorOwners : public AcceptDialog {
|
||||
OBJ_TYPE(DependencyEditorOwners,AcceptDialog);
|
||||
|
||||
ItemList *owners;
|
||||
String editing;
|
||||
void _fill_owners(EditorFileSystemDirectory *efsd);
|
||||
|
||||
public:
|
||||
|
||||
void show(const String& p_path);
|
||||
DependencyEditorOwners();
|
||||
};
|
||||
|
||||
class DependencyRemoveDialog : public ConfirmationDialog {
|
||||
OBJ_TYPE(DependencyRemoveDialog,ConfirmationDialog);
|
||||
|
||||
|
||||
Label *text;
|
||||
Tree *owners;
|
||||
bool exist;
|
||||
Map<String,TreeItem*> files;
|
||||
void _fill_owners(EditorFileSystemDirectory *efsd);
|
||||
|
||||
void ok_pressed();
|
||||
|
||||
public:
|
||||
|
||||
void show(const Vector<String> &to_erase);
|
||||
DependencyRemoveDialog();
|
||||
};
|
||||
|
||||
|
||||
class DependencyErrorDialog : public ConfirmationDialog {
|
||||
OBJ_TYPE(DependencyErrorDialog,ConfirmationDialog);
|
||||
|
||||
|
||||
String for_file;
|
||||
Button *fdep;
|
||||
Label *text;
|
||||
Tree *files;
|
||||
void ok_pressed();
|
||||
void custom_action(const String&);
|
||||
|
||||
public:
|
||||
|
||||
void show(const String& p_for,const Vector<String> &report);
|
||||
DependencyErrorDialog();
|
||||
};
|
||||
|
||||
#endif // DEPENDENCY_EDITOR_H
|
|
@ -190,7 +190,7 @@ void EditorFileDialog::_thumbnail_done(const String& p_path,const Ref<Texture>&
|
|||
void EditorFileDialog::_request_single_thumbnail(const String& p_path) {
|
||||
|
||||
EditorResourcePreview::get_singleton()->queue_resource_preview(p_path,this,"_thumbnail_done",p_path);
|
||||
print_line("want file "+p_path);
|
||||
//print_line("want file "+p_path);
|
||||
set_process(true);
|
||||
preview_waiting=true;
|
||||
preview_wheel_timeout=0;
|
||||
|
@ -359,7 +359,7 @@ void EditorFileDialog::_item_dc_selected(int p_item) {
|
|||
|
||||
if (d["dir"]) {
|
||||
|
||||
print_line("change dir: "+String(d["name"]));
|
||||
//print_line("change dir: "+String(d["name"]));
|
||||
dir_access->change_dir(d["name"]);
|
||||
if (mode==MODE_OPEN_FILE || mode==MODE_OPEN_FILES || mode==MODE_OPEN_DIR)
|
||||
file->set_text("");
|
||||
|
@ -536,6 +536,7 @@ void EditorFileDialog::update_file_list() {
|
|||
|
||||
if (get_icon_func) {
|
||||
|
||||
|
||||
Ref<Texture> icon = get_icon_func(base_dir.plus_file(files.front()->get()));
|
||||
//ti->set_icon(0,icon);
|
||||
if (display_mode==DISPLAY_THUMBNAILS) {
|
||||
|
|
|
@ -94,6 +94,12 @@ bool EditorFileSystemDirectory::get_file_meta(int p_idx) const {
|
|||
return files[p_idx].meta.enabled;
|
||||
}
|
||||
|
||||
Vector<String> EditorFileSystemDirectory::get_file_deps(int p_idx) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_idx,files.size(),Vector<String>());
|
||||
return files[p_idx].meta.deps;
|
||||
|
||||
}
|
||||
Vector<String> EditorFileSystemDirectory::get_missing_sources(int p_idx) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_idx,files.size(),Vector<String>());
|
||||
|
@ -118,7 +124,7 @@ bool EditorFileSystemDirectory::is_missing_sources(int p_idx) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
String EditorFileSystemDirectory::get_file_type(int p_idx) const {
|
||||
StringName EditorFileSystemDirectory::get_file_type(int p_idx) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_idx,files.size(),"");
|
||||
return files[p_idx].type;
|
||||
|
@ -198,6 +204,13 @@ EditorFileSystemDirectory::ImportMeta EditorFileSystem::_get_meta(const String&
|
|||
}
|
||||
m.import_editor=imd->get_editor();
|
||||
}
|
||||
|
||||
List<String> deps;
|
||||
ResourceLoader::get_dependencies(p_path,&deps);
|
||||
for(List<String>::Element *E=deps.front();E;E=E->next()) {
|
||||
m.deps.push_back(E->get());
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -358,7 +371,7 @@ void EditorFileSystem::_scan_scenes() {
|
|||
|
||||
String project=Globals::get_singleton()->get_resource_path();
|
||||
|
||||
String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("file_cache");
|
||||
String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache");
|
||||
FileAccess *f =FileAccess::open(fscache,FileAccess::READ);
|
||||
|
||||
if (f) {
|
||||
|
@ -397,7 +410,7 @@ void EditorFileSystem::_scan_scenes() {
|
|||
|
||||
} else {
|
||||
Vector<String> split = l.split("::");
|
||||
ERR_CONTINUE( split.size() != 4);
|
||||
ERR_CONTINUE( split.size() != 5);
|
||||
String name = split[0];
|
||||
String file;
|
||||
|
||||
|
@ -429,6 +442,15 @@ void EditorFileSystem::_scan_scenes() {
|
|||
}
|
||||
|
||||
}
|
||||
String deps = split[4].strip_edges();
|
||||
if (deps.length()) {
|
||||
Vector<String> dp = deps.split("<>");
|
||||
for(int i=0;i<dp.size();i++) {
|
||||
String path=dp[i];
|
||||
fc.meta.deps.push_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
file_cache[name]=fc;
|
||||
|
||||
ERR_CONTINUE(!dc);
|
||||
|
@ -530,6 +552,7 @@ void EditorFileSystem::scan() {
|
|||
thread = Thread::create(_thread_func,this,s);
|
||||
//tree->hide();
|
||||
//progress->show();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -798,6 +821,14 @@ void EditorFileSystem::_save_type_cache_fs(DirItem *p_dir,FileAccess *p_file) {
|
|||
|
||||
}
|
||||
}
|
||||
s+="::";
|
||||
for(int j=0;j<p_dir->files[i]->meta.deps.size();j++) {
|
||||
|
||||
if (j>0)
|
||||
s+="<>";
|
||||
s+=p_dir->files[i]->meta.deps[j];
|
||||
}
|
||||
|
||||
p_file->store_line(s);
|
||||
}
|
||||
|
||||
|
@ -1037,6 +1068,13 @@ void EditorFileSystem::update_file(const String& p_file) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!FileAccess::exists(p_file)) {
|
||||
//was removed
|
||||
fs->files.remove(cpos);
|
||||
call_deferred("emit_signal","filesystem_changed"); //update later
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
String type = ResourceLoader::get_resource_type(p_file);
|
||||
|
||||
|
|
|
@ -59,13 +59,14 @@ class EditorFileSystemDirectory : public Object {
|
|||
|
||||
Vector<Source> sources;
|
||||
String import_editor;
|
||||
Vector<String> deps;
|
||||
bool enabled;
|
||||
|
||||
};
|
||||
|
||||
struct FileInfo {
|
||||
String file;
|
||||
String type;
|
||||
StringName type;
|
||||
uint64_t modified_time;
|
||||
|
||||
ImportMeta meta;
|
||||
|
@ -87,10 +88,11 @@ public:
|
|||
int get_file_count() const;
|
||||
String get_file(int p_idx) const;
|
||||
String get_file_path(int p_idx) const;
|
||||
String get_file_type(int p_idx) const;
|
||||
StringName get_file_type(int p_idx) const;
|
||||
bool get_file_meta(int p_idx) const;
|
||||
bool is_missing_sources(int p_idx) const;
|
||||
Vector<String> get_missing_sources(int p_idx) const;
|
||||
Vector<String> get_file_deps(int p_idx) const;
|
||||
|
||||
EditorFileSystemDirectory *get_parent();
|
||||
|
||||
|
@ -120,7 +122,7 @@ class EditorFileSystem : public Node {
|
|||
String path;
|
||||
String name;
|
||||
Vector<DirItem*> dirs;
|
||||
Vector<SceneItem*> files;
|
||||
Vector<SceneItem*> files;
|
||||
~DirItem();
|
||||
};
|
||||
|
||||
|
@ -149,6 +151,7 @@ class EditorFileSystem : public Node {
|
|||
String type;
|
||||
uint64_t modification_time;
|
||||
EditorFileSystemDirectory::ImportMeta meta;
|
||||
Vector<String> deps;
|
||||
};
|
||||
|
||||
struct DirCache {
|
||||
|
|
|
@ -1800,6 +1800,13 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
|||
quick_open->popup("Script");
|
||||
quick_open->set_title("Quick Open Script..");
|
||||
|
||||
} break;
|
||||
case FILE_QUICK_OPEN_FILE: {
|
||||
|
||||
|
||||
quick_open->popup("Resource",false,true);
|
||||
quick_open->set_title("Quick Search File..");
|
||||
|
||||
} break;
|
||||
case FILE_RUN_SCRIPT: {
|
||||
|
||||
|
@ -3047,7 +3054,21 @@ void EditorNode::set_current_scene(int p_idx) {
|
|||
|
||||
}
|
||||
|
||||
Error EditorNode::load_scene(const String& p_scene) {
|
||||
bool EditorNode::is_scene_open(const String& p_path) {
|
||||
|
||||
for(int i=0;i<editor_data.get_edited_scene_count();i++) {
|
||||
if (editor_data.get_scene_path(i)==p_path)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void EditorNode::fix_dependencies(const String& p_for_file) {
|
||||
dependency_fixer->edit(p_for_file);
|
||||
}
|
||||
|
||||
Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps) {
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
defer_load_scene = p_scene;
|
||||
|
@ -3093,6 +3114,8 @@ Error EditorNode::load_scene(const String& p_scene) {
|
|||
|
||||
//_cleanup_scene(); // i'm sorry but this MUST happen to avoid modified resources to not be reloaded.
|
||||
|
||||
dependency_errors.clear();
|
||||
|
||||
Ref<PackedScene> sdata = ResourceLoader::load(lpath,"",true);
|
||||
if (!sdata.is_valid()) {
|
||||
|
||||
|
@ -3110,6 +3133,35 @@ Error EditorNode::load_scene(const String& p_scene) {
|
|||
return ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!p_ignore_broken_deps && dependency_errors.has(lpath)) {
|
||||
|
||||
current_option=-1;
|
||||
Vector<String> errors;
|
||||
for(Set<String>::Element *E=dependency_errors[lpath].front();E;E=E->next()) {
|
||||
|
||||
errors.push_back(E->get());
|
||||
}
|
||||
dependency_error->show(lpath,errors);
|
||||
opening_prev=false;
|
||||
|
||||
if (prev!=-1) {
|
||||
set_current_scene(prev);
|
||||
editor_data.remove_scene(idx);
|
||||
}
|
||||
return ERR_FILE_MISSING_DEPENDENCIES;
|
||||
}
|
||||
|
||||
dependency_errors.erase(lpath); //at least not self path
|
||||
|
||||
for (Map<String,Set<String> >::Element *E=dependency_errors.front();E;E=E->next()) {
|
||||
|
||||
String txt="Scene '"+E->key()+"' has broken dependencies:\n";
|
||||
for(Set<String>::Element *F=E->get().front();F;F=F->next()) {
|
||||
txt+="\t"+F->get()+"\n";
|
||||
}
|
||||
add_io_error(txt);
|
||||
}
|
||||
|
||||
sdata->set_path(lpath,true); //take over path
|
||||
|
||||
Node*new_scene=sdata->instance(true);
|
||||
|
@ -3405,9 +3457,12 @@ void EditorNode::hide_animation_player_editors() {
|
|||
|
||||
void EditorNode::_quick_opened(const String& p_resource) {
|
||||
|
||||
print_line("quick_opened");
|
||||
if (quick_open->get_base_type()=="PackedScene") {
|
||||
if (current_option==FILE_QUICK_OPEN_FILE) {
|
||||
scenes_dock->open(p_resource);
|
||||
return;
|
||||
}
|
||||
|
||||
if (quick_open->get_base_type()=="PackedScene") {
|
||||
open_request(p_resource);
|
||||
} else {
|
||||
load_resource(p_resource);
|
||||
|
@ -4117,6 +4172,7 @@ EditorNode::EditorNode() {
|
|||
ResourceLoader::set_abort_on_missing_resources(false);
|
||||
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("file_dialog/show_hidden_files"));
|
||||
ResourceLoader::set_error_notify_func(this,_load_error_notify);
|
||||
ResourceLoader::set_dependency_error_notify_func(this,_dependency_error_report);
|
||||
|
||||
ResourceLoader::set_timestamp_on_load(true);
|
||||
ResourceSaver::set_timestamp_on_save(true);
|
||||
|
@ -4490,6 +4546,7 @@ EditorNode::EditorNode() {
|
|||
p->add_separator();
|
||||
p->add_item("Quick Open Scene..",FILE_QUICK_OPEN_SCENE,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_O);
|
||||
p->add_item("Quick Open Script..",FILE_QUICK_OPEN_SCRIPT,KEY_MASK_ALT+KEY_MASK_CMD+KEY_O);
|
||||
p->add_item("Quick Search File..",FILE_QUICK_OPEN_FILE,KEY_MASK_ALT+KEY_MASK_CMD+KEY_P);
|
||||
p->add_separator();
|
||||
|
||||
PopupMenu *pm_export = memnew(PopupMenu );
|
||||
|
@ -4926,7 +4983,11 @@ EditorNode::EditorNode() {
|
|||
|
||||
|
||||
|
||||
dependency_error = memnew( DependencyErrorDialog );
|
||||
gui_base->add_child(dependency_error);
|
||||
|
||||
dependency_fixer = memnew( DependencyEditor );
|
||||
gui_base->add_child( dependency_fixer );
|
||||
|
||||
settings_config_dialog = memnew( EditorSettingsDialog );
|
||||
gui_base->add_child(settings_config_dialog);
|
||||
|
|
|
@ -123,6 +123,7 @@ class EditorNode : public Node {
|
|||
FILE_OPEN_OLD_SCENE,
|
||||
FILE_QUICK_OPEN_SCENE,
|
||||
FILE_QUICK_OPEN_SCRIPT,
|
||||
FILE_QUICK_OPEN_FILE,
|
||||
FILE_RUN_SCRIPT,
|
||||
FILE_OPEN_PREV,
|
||||
FILE_CLOSE,
|
||||
|
@ -312,6 +313,9 @@ class EditorNode : public Node {
|
|||
ProgressDialog *progress_dialog;
|
||||
BackgroundProgress *progress_hb;
|
||||
|
||||
DependencyErrorDialog *dependency_error;
|
||||
DependencyEditor *dependency_fixer;
|
||||
|
||||
TabContainer *dock_slot[DOCK_SLOT_MAX];
|
||||
Rect2 dock_select_rect[DOCK_SLOT_MAX];
|
||||
int dock_select_rect_over;
|
||||
|
@ -451,6 +455,16 @@ class EditorNode : public Node {
|
|||
void _save_scene_with_preview(String p_file);
|
||||
|
||||
|
||||
Map<String,Set<String> > dependency_errors;
|
||||
|
||||
static void _dependency_error_report(void *ud,const String& p_path,const String& p_dep,const String& p_type) {
|
||||
EditorNode*en=(EditorNode*)ud;
|
||||
if (!en->dependency_errors.has(p_path))
|
||||
en->dependency_errors[p_path]=Set<String>();
|
||||
en->dependency_errors[p_path].insert(p_dep+"::"+p_type);
|
||||
|
||||
}
|
||||
|
||||
struct ExportDefer {
|
||||
String platform;
|
||||
String path;
|
||||
|
@ -534,10 +548,13 @@ public:
|
|||
Viewport *get_scene_root() { return scene_root; } //root of the scene being edited
|
||||
Error save_optimized_copy(const String& p_scene,const String& p_preset);
|
||||
|
||||
void fix_dependencies(const String& p_for_file);
|
||||
void clear_scene() { _cleanup_scene(); }
|
||||
Error load_scene(const String& p_scene);
|
||||
Error load_scene(const String& p_scene,bool p_ignore_broken_deps=false);
|
||||
Error load_resource(const String& p_scene);
|
||||
|
||||
bool is_scene_open(const String& p_path);
|
||||
|
||||
void set_current_version(uint64_t p_version);
|
||||
void set_current_scene(int p_idx);
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 288 B |
BIN
tools/editor/icons/icon_filesystem.png
Normal file
BIN
tools/editor/icons/icon_filesystem.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 241 B |
BIN
tools/editor/icons/icon_non_favorite.png
Normal file
BIN
tools/editor/icons/icon_non_favorite.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 469 B |
|
@ -80,7 +80,7 @@ bool ProjectExportDialog::_create_tree(TreeItem *p_parent,EditorFileSystemDirect
|
|||
String path = p_dir->get_file_path(i);
|
||||
fitem->set_tooltip(0,path);
|
||||
fitem->set_metadata(0,path);
|
||||
Ref<Texture> icon = get_icon( (has_icon(p_dir->get_file_type(i),"EditorIcons")?p_dir->get_file_type(i):String("Object")),"EditorIcons");
|
||||
Ref<Texture> icon = get_icon( (has_icon(p_dir->get_file_type(i),ei)?p_dir->get_file_type(i):ot),ei);
|
||||
fitem->set_icon(0,icon);
|
||||
|
||||
fitem->set_cell_mode(1,TreeItem::CELL_MODE_RANGE);
|
||||
|
@ -1372,6 +1372,8 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
|
|||
button_export = add_button("Export..",!OS::get_singleton()->get_swap_ok_cancel(),"export_pck");
|
||||
updating_script=false;
|
||||
|
||||
ei="EditorIcons";
|
||||
ot="Object";
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,9 @@ private:
|
|||
HBoxContainer *plat_errors;
|
||||
Label *platform_error_string;
|
||||
|
||||
StringName ei;
|
||||
StringName ot;
|
||||
|
||||
Tree * tree;
|
||||
|
||||
EditorFileDialog *pck_export;
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
#include "os/keyboard.h"
|
||||
|
||||
|
||||
void EditorQuickOpen::popup(const String& p_base, bool p_dontclear) {
|
||||
void EditorQuickOpen::popup(const StringName &p_base, bool p_dontclear, bool p_add_dirs) {
|
||||
|
||||
add_directories=p_add_dirs;
|
||||
popup_centered_ratio(0.6);
|
||||
if (p_dontclear)
|
||||
search_box->select_all();
|
||||
|
@ -66,27 +67,53 @@ void EditorQuickOpen::_sbox_input(const InputEvent& p_ie) {
|
|||
|
||||
void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd) {
|
||||
|
||||
for(int i=0;i<efsd->get_subdir_count();i++) {
|
||||
if (!add_directories) {
|
||||
for(int i=0;i<efsd->get_subdir_count();i++) {
|
||||
|
||||
_parse_fs(efsd->get_subdir(i));
|
||||
_parse_fs(efsd->get_subdir(i));
|
||||
}
|
||||
}
|
||||
|
||||
TreeItem *root = search_options->get_root();
|
||||
|
||||
if (add_directories) {
|
||||
String path = efsd->get_path();
|
||||
if (!path.ends_with("/"))
|
||||
path+="/";
|
||||
if (path!="res://") {
|
||||
path=path.substr(6,path.length());
|
||||
if (path.findn(search_box->get_text())!=-1) {
|
||||
TreeItem *ti = search_options->create_item(root);
|
||||
ti->set_text(0,path);
|
||||
Ref<Texture> icon = get_icon("folder","FileDialog");
|
||||
ti->set_icon(0,icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int i=0;i<efsd->get_file_count();i++) {
|
||||
|
||||
String file = efsd->get_file_path(i);
|
||||
file=file.substr(6,file.length());
|
||||
if (ObjectTypeDB::is_type(efsd->get_file_type(i),base_type) && (search_box->get_text()=="" || file.findn(search_box->get_text())!=-1)) {
|
||||
|
||||
TreeItem *root = search_options->get_root();
|
||||
TreeItem *ti = search_options->create_item(root);
|
||||
ti->set_text(0,file);
|
||||
Ref<Texture> icon = get_icon( (has_icon(efsd->get_file_type(i),"EditorIcons")?efsd->get_file_type(i):String("Object")),"EditorIcons");
|
||||
Ref<Texture> icon = get_icon( (has_icon(efsd->get_file_type(i),ei)?efsd->get_file_type(i):ot),ei);
|
||||
ti->set_icon(0,icon);
|
||||
if (root->get_children()==ti)
|
||||
ti->select(0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (add_directories) {
|
||||
for(int i=0;i<efsd->get_subdir_count();i++) {
|
||||
|
||||
_parse_fs(efsd->get_subdir(i));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EditorQuickOpen::_update_search() {
|
||||
|
@ -118,7 +145,7 @@ void EditorQuickOpen::_notification(int p_what) {
|
|||
}
|
||||
|
||||
|
||||
String EditorQuickOpen::get_base_type() const {
|
||||
StringName EditorQuickOpen::get_base_type() const {
|
||||
|
||||
return base_type;
|
||||
}
|
||||
|
@ -152,4 +179,7 @@ EditorQuickOpen::EditorQuickOpen() {
|
|||
set_hide_on_ok(false);
|
||||
search_options->connect("item_activated",this,"_confirmed");
|
||||
search_options->set_hide_root(true);
|
||||
ei="EditorIcons";
|
||||
ot="Object";
|
||||
add_directories=false;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,11 @@ class EditorQuickOpen : public ConfirmationDialog {
|
|||
|
||||
LineEdit *search_box;
|
||||
Tree *search_options;
|
||||
String base_type;
|
||||
StringName base_type;
|
||||
StringName ei;
|
||||
StringName ot;
|
||||
bool add_directories;
|
||||
|
||||
|
||||
void _update_search();
|
||||
|
||||
|
@ -55,9 +59,9 @@ protected:
|
|||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
String get_base_type() const;
|
||||
StringName get_base_type() const;
|
||||
|
||||
void popup(const String& p_base,bool p_dontclear=false);
|
||||
void popup(const StringName& p_base,bool p_dontclear=false,bool p_add_dirs=false);
|
||||
EditorQuickOpen();
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -36,40 +36,112 @@
|
|||
#include "scene/gui/tool_button.h"
|
||||
#include "scene/gui/option_button.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/menu_button.h"
|
||||
#include "scene/gui/item_list.h"
|
||||
#include "scene/gui/progress_bar.h"
|
||||
|
||||
#include "os/dir_access.h"
|
||||
#include "os/thread.h"
|
||||
|
||||
#include "editor_file_system.h"
|
||||
|
||||
#include "editor_dir_dialog.h"
|
||||
#include "dependency_editor.h"
|
||||
|
||||
class EditorNode;
|
||||
|
||||
class ScenesDockFilter;
|
||||
|
||||
class ScenesDock : public VBoxContainer {
|
||||
OBJ_TYPE( ScenesDock, VBoxContainer );
|
||||
|
||||
enum FileMenu {
|
||||
FILE_DEPENDENCIES,
|
||||
FILE_OWNERS,
|
||||
FILE_MOVE,
|
||||
FILE_REMOVE,
|
||||
FILE_REIMPORT,
|
||||
FILE_INFO
|
||||
};
|
||||
|
||||
|
||||
VBoxContainer *scanning_vb;
|
||||
ProgressBar *scanning_progress;
|
||||
|
||||
EditorNode *editor;
|
||||
Set<String> favorites;
|
||||
|
||||
Button *button_reload;
|
||||
Button *button_instance;
|
||||
Button *button_favorite;
|
||||
Button *button_fav_up;
|
||||
Button *button_fav_down;
|
||||
Button *button_open;
|
||||
Timer *timer;
|
||||
Button *button_back;
|
||||
Button *display_mode;
|
||||
Button *button_hist_next;
|
||||
Button *button_hist_prev;
|
||||
LineEdit *current_path;
|
||||
HBoxContainer *path_hb;
|
||||
|
||||
ScenesDockFilter *tree_filter;
|
||||
MenuButton *file_options;
|
||||
|
||||
|
||||
DependencyEditor *deps_editor;
|
||||
DependencyEditorOwners *owners_editor;
|
||||
DependencyRemoveDialog *remove_dialog;
|
||||
|
||||
EditorDirDialog *move_dialog;
|
||||
EditorFileDialog *rename_dialog;
|
||||
|
||||
Vector<String> move_dirs;
|
||||
Vector<String> move_files;
|
||||
|
||||
|
||||
Vector<String> history;
|
||||
int history_pos;
|
||||
|
||||
String path;
|
||||
|
||||
bool initialized;
|
||||
|
||||
bool updating_tree;
|
||||
Tree * tree;
|
||||
bool _create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_dir);
|
||||
Tree * tree; //directories
|
||||
ItemList *files;
|
||||
|
||||
bool tree_mode;
|
||||
|
||||
void _go_to_tree();
|
||||
void _go_to_dir(const String& p_dir);
|
||||
void _select_file(int p_idx);
|
||||
|
||||
bool _create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_dir);
|
||||
void _thumbnail_done(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata);
|
||||
void _find_inside_move_files(EditorFileSystemDirectory *efsd,Vector<String>& files);
|
||||
void _find_remaps(EditorFileSystemDirectory *efsd,Map<String,String> &renames,List<String>& to_remaps);
|
||||
|
||||
void _rename_operation(const String& p_to_path);
|
||||
void _move_operation(const String& p_to_path);
|
||||
|
||||
|
||||
void _file_option(int p_option);
|
||||
void _update_files(bool p_keep_selection);
|
||||
void _change_file_display();
|
||||
|
||||
void _fs_changed();
|
||||
void _fw_history();
|
||||
void _bw_history();
|
||||
void _push_to_history();
|
||||
|
||||
void _fav_up_pressed();
|
||||
void _fav_down_pressed();
|
||||
void _dir_selected();
|
||||
void _update_tree();
|
||||
void _rescan();
|
||||
void _favorites_toggled(bool);
|
||||
void _favorite_toggled();
|
||||
void _set_scannig_mode();
|
||||
|
||||
void _favorites_pressed();
|
||||
void _instance_pressed();
|
||||
void _open_pressed();
|
||||
void _save_favorites();
|
||||
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
|
@ -77,48 +149,14 @@ protected:
|
|||
public:
|
||||
|
||||
String get_selected_path() const;
|
||||
void open(const String& p_path);
|
||||
|
||||
void fix_dependencies(const String& p_for_file);
|
||||
|
||||
|
||||
ScenesDock(EditorNode *p_editor);
|
||||
~ScenesDock();
|
||||
};
|
||||
|
||||
class ScenesDockFilter : public HBoxContainer {
|
||||
|
||||
OBJ_TYPE( ScenesDockFilter, HBoxContainer );
|
||||
|
||||
private:
|
||||
friend class ScenesDock;
|
||||
|
||||
enum Command {
|
||||
CMD_CLEAR_FILTER,
|
||||
};
|
||||
|
||||
Tree *tree;
|
||||
OptionButton *filter_option;
|
||||
LineEdit *search_box;
|
||||
ToolButton *clear_search_button;
|
||||
|
||||
enum FilterOption {
|
||||
FILTER_PATH, // NAME or Folder
|
||||
FILTER_NAME,
|
||||
FILTER_FOLDER,
|
||||
};
|
||||
FilterOption _current_filter;
|
||||
//Vector<String> filters;
|
||||
|
||||
void _command(int p_command);
|
||||
void _search_text_changed(const String& p_newtext);
|
||||
void _setup_filters();
|
||||
void _file_filter_selected(int p_idx);
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
String get_search_term();
|
||||
FilterOption get_file_filter();
|
||||
ScenesDockFilter();
|
||||
};
|
||||
|
||||
#endif // SCENES_DOCK_H
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
short_name="godot"
|
||||
name="Godot Engine"
|
||||
major=1
|
||||
minor=1
|
||||
status="stable"
|
||||
major=2
|
||||
minor=0
|
||||
status="alpha"
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue