diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/error_list.h | 1 | ||||
-rw-r--r-- | core/global_constants.cpp | 1 | ||||
-rw-r--r-- | core/io/resource_format_binary.cpp | 336 | ||||
-rw-r--r-- | core/io/resource_format_binary.h | 14 | ||||
-rw-r--r-- | core/io/resource_format_xml.cpp | 322 | ||||
-rw-r--r-- | core/io/resource_format_xml.h | 25 | ||||
-rw-r--r-- | core/io/resource_loader.cpp | 65 | ||||
-rw-r--r-- | core/io/resource_loader.h | 22 | ||||
-rw-r--r-- | core/io/resource_saver.h | 2 | ||||
-rw-r--r-- | core/io/translation_loader_po.cpp | 9 | ||||
-rw-r--r-- | core/io/translation_loader_po.h | 2 |
11 files changed, 691 insertions, 108 deletions
diff --git a/core/error_list.h b/core/error_list.h index 124027172e..92c417154c 100644 --- a/core/error_list.h +++ b/core/error_list.h @@ -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, diff --git a/core/global_constants.cpp b/core/global_constants.cpp index b8d113f67c..9fb45c672a 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -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 ), diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index c6cf631de6..60bb8b658e 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -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()) { @@ -402,6 +410,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: { ERR_FAIL_V(ERR_FILE_CORRUPT); @@ -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()); + + for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) { + save_order[E->get()]=E->key(); + } - save_unicode_string(E->get()->get_save_type()); - String path = E->get()->get_path(); + 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; +} diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index da415d97a5..8bf20bc574 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -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(); }; diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp index b744cbf967..9019b4e3c0 100644 --- a/core/io/resource_format_xml.cpp +++ b/core/io/resource_format_xml.cpp @@ -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; +} diff --git a/core/io/resource_format_xml.h b/core/io/resource_format_xml.h index d5ba9eb800..77987c6a5b 100644 --- a/core/io/resource_format_xml.h +++ b/core/io/resource_format_xml.h @@ -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(); }; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 22d89840ae..1e014480f4 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -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,32 @@ 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; + 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; + + 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; @@ -372,11 +408,15 @@ 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); + 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; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index d25727f19f..00a05dcb43 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -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; } }; diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index 05cbe7f98e..8382b65290 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -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() {} }; diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index c32b25c407..020d168208 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -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; diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index 9d8ad97a29..e07ae15e28 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -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; |