2017-03-05 15:47:28 +01:00
/**************************************************************************/
2019-02-12 13:30:56 +01:00
/* resource_importer.cpp */
2017-03-05 15:47:28 +01:00
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 00:50:27 +01:00
2019-02-12 13:30:56 +01:00
# include "resource_importer.h"
2017-03-05 15:47:28 +01:00
2020-11-07 19:33:38 -03:00
# include "core/config/project_settings.h"
2022-12-05 19:01:59 +01:00
# include "core/io/config_file.h"
2025-01-27 21:42:02 +02:00
# include "core/io/image.h"
2018-09-11 18:13:45 +02:00
# include "core/os/os.h"
2020-11-07 19:33:38 -03:00
# include "core/variant/variant_parser.h"
2019-02-27 08:57:37 +01:00
2024-06-01 19:52:28 -04:00
ResourceFormatImporterLoadOnStartup ResourceImporter : : load_on_startup = nullptr ;
2019-02-27 08:57:37 +01:00
bool ResourceFormatImporter : : SortImporterByName : : operator ( ) ( const Ref < ResourceImporter > & p_a , const Ref < ResourceImporter > & p_b ) const {
2019-02-26 18:43:37 -03:00
return p_a - > get_importer_name ( ) < p_b - > get_importer_name ( ) ;
}
2017-01-25 21:55:59 -03:00
2025-01-27 21:42:02 +02:00
Error ResourceFormatImporter : : _get_path_and_type ( const String & p_path , PathAndType & r_path_and_type , bool p_load , bool * r_valid ) const {
2017-01-25 21:55:59 -03:00
Error err ;
2022-03-23 11:08:58 +02:00
Ref < FileAccess > f = FileAccess : : open ( p_path + " .import " , FileAccess : : READ , & err ) ;
2017-01-25 21:55:59 -03:00
2022-03-23 11:08:58 +02:00
if ( f . is_null ( ) ) {
2017-08-29 19:50:58 -03:00
if ( r_valid ) {
* r_valid = false ;
}
2017-01-25 21:55:59 -03:00
return err ;
2017-08-29 19:50:58 -03:00
}
2017-01-25 21:55:59 -03:00
VariantParser : : StreamFile stream ;
stream . f = f ;
String assign ;
Variant value ;
VariantParser : : Tag next_tag ;
2017-08-29 19:50:58 -03:00
if ( r_valid ) {
* r_valid = true ;
}
2017-01-25 21:55:59 -03:00
int lines = 0 ;
String error_text ;
2025-01-27 21:42:02 +02:00
bool path_found = false ; // First match must have priority.
String decomp_path ;
bool decomp_path_found = false ;
2017-01-25 21:55:59 -03:00
while ( true ) {
assign = Variant ( ) ;
next_tag . fields . clear ( ) ;
next_tag . name = String ( ) ;
2020-04-02 01:20:12 +02:00
err = VariantParser : : parse_tag_assign_eof ( & stream , lines , error_text , next_tag , assign , value , nullptr , true ) ;
2017-01-25 21:55:59 -03:00
if ( err = = ERR_FILE_EOF ) {
2025-01-27 21:42:02 +02:00
if ( p_load & & ! path_found & & decomp_path_found ) {
print_verbose ( vformat ( " No natively supported texture format found for %s, using decompressable format %s. " , p_path , decomp_path ) ) ;
r_path_and_type . path = decomp_path ;
}
2017-01-25 21:55:59 -03:00
return OK ;
} else if ( err ! = OK ) {
2024-10-11 16:17:49 +02:00
ERR_PRINT ( vformat ( " ResourceFormatImporter::load - %s.import:%d error: %s. " , p_path , lines , error_text ) ) ;
2017-01-25 21:55:59 -03:00
return err ;
}
2021-12-09 03:42:46 -06:00
if ( ! assign . is_empty ( ) ) {
if ( ! path_found & & assign . begins_with ( " path. " ) & & r_path_and_type . path . is_empty ( ) ) {
2017-02-06 00:38:39 -03:00
String feature = assign . get_slicec ( ' . ' , 1 ) ;
2018-08-27 13:47:13 -03:00
if ( OS : : get_singleton ( ) - > has_feature ( feature ) ) {
2017-02-06 00:38:39 -03:00
r_path_and_type . path = value ;
2025-01-27 21:42:02 +02:00
path_found = true ; // First match must have priority.
} else if ( p_load & & Image : : can_decompress ( feature ) & & ! decomp_path_found ) { // When loading, check for decompressable formats and use first one found if nothing else is supported.
decomp_path = value ;
decomp_path_found = true ; // First match must have priority.
2017-02-06 00:38:39 -03:00
}
2017-07-19 17:00:46 -03:00
} else if ( ! path_found & & assign = = " path " ) {
2017-01-25 21:55:59 -03:00
r_path_and_type . path = value ;
2025-01-27 21:42:02 +02:00
path_found = true ; // First match must have priority.
2017-01-25 21:55:59 -03:00
} else if ( assign = = " type " ) {
2020-05-01 09:34:23 -03:00
r_path_and_type . type = ClassDB : : get_compatibility_remapped_class ( value ) ;
2017-09-20 20:59:19 -03:00
} else if ( assign = = " importer " ) {
r_path_and_type . importer = value ;
2021-07-23 16:01:18 -03:00
} else if ( assign = = " uid " ) {
r_path_and_type . uid = ResourceUID : : get_singleton ( ) - > text_to_id ( value ) ;
2019-04-19 15:54:33 -03:00
} else if ( assign = = " group_file " ) {
r_path_and_type . group_file = value ;
2019-02-26 18:43:37 -03:00
} else if ( assign = = " metadata " ) {
r_path_and_type . metadata = value ;
2017-08-29 19:50:58 -03:00
} else if ( assign = = " valid " ) {
if ( r_valid ) {
* r_valid = value ;
}
2017-01-25 21:55:59 -03:00
}
} else if ( next_tag . name ! = " remap " ) {
break ;
}
}
2022-08-22 22:07:02 +03:00
# ifdef TOOLS_ENABLED
if ( r_path_and_type . metadata & & ! r_path_and_type . path . is_empty ( ) ) {
2022-09-29 12:53:28 +03:00
Dictionary meta = r_path_and_type . metadata ;
if ( meta . has ( " has_editor_variant " ) ) {
2022-08-22 22:07:02 +03:00
r_path_and_type . path = r_path_and_type . path . get_basename ( ) + " .editor. " + r_path_and_type . path . get_extension ( ) ;
}
}
# endif
2024-05-24 11:32:33 -04:00
if ( r_path_and_type . type . is_empty ( ) ) {
2017-01-25 21:55:59 -03:00
return ERR_FILE_CORRUPT ;
}
2024-05-24 11:32:33 -04:00
if ( r_path_and_type . path . is_empty ( ) ) {
// Some importers may not write files to the .godot folder, so the path can be empty.
if ( r_path_and_type . importer . is_empty ( ) ) {
return ERR_FILE_CORRUPT ;
}
// It's only invalid if the extension for the importer is not empty.
Ref < ResourceImporter > importer = get_importer_by_name ( r_path_and_type . importer ) ;
if ( importer . is_null ( ) | | ! importer - > get_save_extension ( ) . is_empty ( ) ) {
return ERR_FILE_CORRUPT ;
}
}
2017-01-25 21:55:59 -03:00
return OK ;
}
2022-05-03 01:43:50 +02:00
Ref < Resource > ResourceFormatImporter : : load ( const String & p_path , const String & p_original_path , Error * r_error , bool p_use_sub_threads , float * r_progress , CacheMode p_cache_mode ) {
2024-06-01 19:52:28 -04:00
# ifdef TOOLS_ENABLED
// When loading a resource on startup, we use the load_on_startup callback,
// which executes the loading in the EditorFileSystem. It can reimport
// the resource and retry the load, allowing the resource to be loaded
// even if it is not yet imported.
if ( ResourceImporter : : load_on_startup ! = nullptr ) {
return ResourceImporter : : load_on_startup ( this , p_path , r_error , p_use_sub_threads , r_progress , p_cache_mode ) ;
}
# endif
return load_internal ( p_path , r_error , p_use_sub_threads , r_progress , p_cache_mode , false ) ;
}
Ref < Resource > ResourceFormatImporter : : load_internal ( const String & p_path , Error * r_error , bool p_use_sub_threads , float * r_progress , CacheMode p_cache_mode , bool p_silence_errors ) {
2017-01-25 21:55:59 -03:00
PathAndType pat ;
2025-01-27 21:42:02 +02:00
Error err = _get_path_and_type ( p_path , pat , true ) ;
2017-01-25 21:55:59 -03:00
if ( err ! = OK ) {
2020-05-14 16:41:43 +02:00
if ( r_error ) {
2017-01-25 21:55:59 -03:00
* r_error = err ;
2020-05-14 16:41:43 +02:00
}
2017-01-25 21:55:59 -03:00
2022-05-03 01:43:50 +02:00
return Ref < Resource > ( ) ;
2017-01-25 21:55:59 -03:00
}
2024-06-01 19:52:28 -04:00
if ( p_silence_errors ) {
// Note: Some importers do not create files in the .godot folder, so we need to check if the path is empty.
if ( ! pat . path . is_empty ( ) & & ! FileAccess : : exists ( pat . path ) ) {
return Ref < Resource > ( ) ;
}
}
2022-05-03 01:43:50 +02:00
Ref < Resource > res = ResourceLoader : : _load ( pat . path , p_path , pat . type , p_cache_mode , r_error , p_use_sub_threads , r_progress ) ;
2017-02-01 09:45:45 -03:00
# ifdef TOOLS_ENABLED
2017-02-15 08:29:46 -03:00
if ( res . is_valid ( ) ) {
res - > set_import_last_modified_time ( res - > get_last_modified_time ( ) ) ; //pass this, if used
res - > set_import_path ( pat . path ) ;
}
2017-02-01 09:45:45 -03:00
# endif
return res ;
2017-01-25 21:55:59 -03:00
}
void ResourceFormatImporter : : get_recognized_extensions ( List < String > * p_extensions ) const {
2022-05-19 17:00:06 +02:00
HashSet < String > found ;
2017-01-25 21:55:59 -03:00
2018-01-06 16:36:49 -03:00
for ( int i = 0 ; i < importers . size ( ) ; i + + ) {
2017-01-25 21:55:59 -03:00
List < String > local_exts ;
2018-01-06 16:36:49 -03:00
importers [ i ] - > get_recognized_extensions ( & local_exts ) ;
2021-07-24 15:46:25 +02:00
for ( const String & F : local_exts ) {
2021-07-15 23:45:57 -04:00
if ( ! found . has ( F ) ) {
p_extensions - > push_back ( F ) ;
found . insert ( F ) ;
2017-01-25 21:55:59 -03:00
}
}
}
}
void ResourceFormatImporter : : get_recognized_extensions_for_type ( const String & p_type , List < String > * p_extensions ) const {
2021-12-09 03:42:46 -06:00
if ( p_type . is_empty ( ) ) {
2019-07-01 12:59:42 +02:00
get_recognized_extensions ( p_extensions ) ;
return ;
2017-02-01 09:45:45 -03:00
}
2022-05-19 17:00:06 +02:00
HashSet < String > found ;
2017-01-25 21:55:59 -03:00
2018-01-06 16:36:49 -03:00
for ( int i = 0 ; i < importers . size ( ) ; i + + ) {
String res_type = importers [ i ] - > get_resource_type ( ) ;
2021-12-09 03:42:46 -06:00
if ( res_type . is_empty ( ) ) {
2017-02-01 20:41:05 -03:00
continue ;
2020-05-14 16:41:43 +02:00
}
2017-02-01 20:41:05 -03:00
2020-05-14 16:41:43 +02:00
if ( ! ClassDB : : is_parent_class ( res_type , p_type ) ) {
2017-01-25 21:55:59 -03:00
continue ;
2020-05-14 16:41:43 +02:00
}
2017-01-25 21:55:59 -03:00
List < String > local_exts ;
2018-01-06 16:36:49 -03:00
importers [ i ] - > get_recognized_extensions ( & local_exts ) ;
2021-07-24 15:46:25 +02:00
for ( const String & F : local_exts ) {
2021-07-15 23:45:57 -04:00
if ( ! found . has ( F ) ) {
p_extensions - > push_back ( F ) ;
found . insert ( F ) ;
2017-01-25 21:55:59 -03:00
}
}
}
}
2019-03-04 21:00:50 -03:00
bool ResourceFormatImporter : : exists ( const String & p_path ) const {
return FileAccess : : exists ( p_path + " .import " ) ;
}
2017-01-25 21:55:59 -03:00
bool ResourceFormatImporter : : recognize_path ( const String & p_path , const String & p_for_type ) const {
2017-02-01 09:45:45 -03:00
return FileAccess : : exists ( p_path + " .import " ) ;
}
2021-03-24 20:44:13 -03:00
Error ResourceFormatImporter : : get_import_order_threads_and_importer ( const String & p_path , int & r_order , bool & r_can_threads , String & r_importer ) const {
r_order = 0 ;
r_importer = " " ;
r_can_threads = false ;
Ref < ResourceImporter > importer ;
if ( FileAccess : : exists ( p_path + " .import " ) ) {
PathAndType pat ;
2025-01-27 21:42:02 +02:00
Error err = _get_path_and_type ( p_path , pat , false ) ;
2021-03-24 20:44:13 -03:00
if ( err = = OK ) {
importer = get_importer_by_name ( pat . importer ) ;
}
} else {
2025-02-15 15:08:56 -05:00
importer = get_importer_by_file ( p_path ) ;
2021-03-24 20:44:13 -03:00
}
if ( importer . is_valid ( ) ) {
r_order = importer - > get_import_order ( ) ;
r_importer = importer - > get_importer_name ( ) ;
r_can_threads = importer - > can_import_threaded ( ) ;
return OK ;
} else {
return ERR_INVALID_PARAMETER ;
}
}
2017-09-20 20:59:19 -03:00
int ResourceFormatImporter : : get_import_order ( const String & p_path ) const {
Ref < ResourceImporter > importer ;
if ( FileAccess : : exists ( p_path + " .import " ) ) {
PathAndType pat ;
2025-01-27 21:42:02 +02:00
Error err = _get_path_and_type ( p_path , pat , false ) ;
2017-09-20 20:59:19 -03:00
if ( err = = OK ) {
importer = get_importer_by_name ( pat . importer ) ;
}
} else {
2025-02-15 15:08:56 -05:00
importer = get_importer_by_file ( p_path ) ;
2017-09-20 20:59:19 -03:00
}
2020-05-14 16:41:43 +02:00
if ( importer . is_valid ( ) ) {
2017-09-20 20:59:19 -03:00
return importer - > get_import_order ( ) ;
2020-05-14 16:41:43 +02:00
}
2017-09-20 20:59:19 -03:00
return 0 ;
}
2017-01-25 21:55:59 -03:00
bool ResourceFormatImporter : : handles_type ( const String & p_type ) const {
2018-01-06 16:36:49 -03:00
for ( int i = 0 ; i < importers . size ( ) ; i + + ) {
String res_type = importers [ i ] - > get_resource_type ( ) ;
2021-12-09 03:42:46 -06:00
if ( res_type . is_empty ( ) ) {
2017-02-01 20:41:05 -03:00
continue ;
2020-05-14 16:41:43 +02:00
}
if ( ClassDB : : is_parent_class ( res_type , p_type ) ) {
2017-01-25 21:55:59 -03:00
return true ;
2020-05-14 16:41:43 +02:00
}
2017-01-25 21:55:59 -03:00
}
return true ;
}
2017-02-06 00:38:39 -03:00
String ResourceFormatImporter : : get_internal_resource_path ( const String & p_path ) const {
PathAndType pat ;
2025-01-27 21:42:02 +02:00
Error err = _get_path_and_type ( p_path , pat , false ) ;
2017-02-06 00:38:39 -03:00
if ( err ! = OK ) {
return String ( ) ;
}
return pat . path ;
}
2017-08-15 01:13:14 +02:00
void ResourceFormatImporter : : get_internal_resource_path_list ( const String & p_path , List < String > * r_paths ) {
Error err ;
2022-03-23 11:08:58 +02:00
Ref < FileAccess > f = FileAccess : : open ( p_path + " .import " , FileAccess : : READ , & err ) ;
2017-08-15 01:13:14 +02:00
2022-03-23 11:08:58 +02:00
if ( f . is_null ( ) ) {
2017-08-15 01:13:14 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2017-08-15 01:13:14 +02:00
VariantParser : : StreamFile stream ;
stream . f = f ;
String assign ;
Variant value ;
VariantParser : : Tag next_tag ;
int lines = 0 ;
String error_text ;
while ( true ) {
assign = Variant ( ) ;
next_tag . fields . clear ( ) ;
next_tag . name = String ( ) ;
2020-04-02 01:20:12 +02:00
err = VariantParser : : parse_tag_assign_eof ( & stream , lines , error_text , next_tag , assign , value , nullptr , true ) ;
2017-08-15 01:13:14 +02:00
if ( err = = ERR_FILE_EOF ) {
return ;
} else if ( err ! = OK ) {
2024-10-11 16:17:49 +02:00
ERR_PRINT ( vformat ( " ResourceFormatImporter::get_internal_resource_path_list - %s.import:%d error: %s. " , p_path , lines , error_text ) ) ;
2017-08-15 01:13:14 +02:00
return ;
}
2021-12-09 03:42:46 -06:00
if ( ! assign . is_empty ( ) ) {
2017-08-15 01:13:14 +02:00
if ( assign . begins_with ( " path. " ) ) {
r_paths - > push_back ( value ) ;
} else if ( assign = = " path " ) {
r_paths - > push_back ( value ) ;
}
} else if ( next_tag . name ! = " remap " ) {
break ;
}
}
}
2019-04-19 15:54:33 -03:00
String ResourceFormatImporter : : get_import_group_file ( const String & p_path ) const {
bool valid = true ;
PathAndType pat ;
2025-01-27 21:42:02 +02:00
_get_path_and_type ( p_path , pat , false , & valid ) ;
2019-05-20 13:51:51 +02:00
return valid ? pat . group_file : String ( ) ;
2019-04-19 15:54:33 -03:00
}
2017-08-29 19:50:58 -03:00
bool ResourceFormatImporter : : is_import_valid ( const String & p_path ) const {
bool valid = true ;
PathAndType pat ;
2025-01-27 21:42:02 +02:00
_get_path_and_type ( p_path , pat , false , & valid ) ;
2017-08-29 19:50:58 -03:00
return valid ;
}
2017-01-25 21:55:59 -03:00
String ResourceFormatImporter : : get_resource_type ( const String & p_path ) const {
PathAndType pat ;
2025-01-27 21:42:02 +02:00
Error err = _get_path_and_type ( p_path , pat , false ) ;
2017-01-25 21:55:59 -03:00
if ( err ! = OK ) {
return " " ;
}
return pat . type ;
}
2021-07-23 16:01:18 -03:00
ResourceUID : : ID ResourceFormatImporter : : get_resource_uid ( const String & p_path ) const {
PathAndType pat ;
2025-01-27 21:42:02 +02:00
Error err = _get_path_and_type ( p_path , pat , false ) ;
2021-07-23 16:01:18 -03:00
if ( err ! = OK ) {
return ResourceUID : : INVALID_ID ;
}
return pat . uid ;
}
2024-09-23 10:42:18 +02:00
bool ResourceFormatImporter : : has_custom_uid_support ( ) const {
return true ;
}
2024-06-11 20:11:10 -04:00
Error ResourceFormatImporter : : get_resource_import_info ( const String & p_path , StringName & r_type , ResourceUID : : ID & r_uid , String & r_import_group_file ) const {
PathAndType pat ;
2025-01-27 21:42:02 +02:00
Error err = _get_path_and_type ( p_path , pat , false ) ;
2024-06-11 20:11:10 -04:00
if ( err = = OK ) {
r_type = pat . type ;
r_uid = pat . uid ;
r_import_group_file = pat . group_file ;
} else {
r_type = " " ;
r_uid = ResourceUID : : INVALID_ID ;
r_import_group_file = " " ;
}
return err ;
}
2019-02-26 18:43:37 -03:00
Variant ResourceFormatImporter : : get_resource_metadata ( const String & p_path ) const {
PathAndType pat ;
2025-01-27 21:42:02 +02:00
Error err = _get_path_and_type ( p_path , pat , false ) ;
2019-02-26 18:43:37 -03:00
if ( err ! = OK ) {
return Variant ( ) ;
}
return pat . metadata ;
}
2022-07-14 14:18:18 +02:00
void ResourceFormatImporter : : get_classes_used ( const String & p_path , HashSet < StringName > * r_classes ) {
PathAndType pat ;
2025-01-27 21:42:02 +02:00
Error err = _get_path_and_type ( p_path , pat , false ) ;
2022-07-14 14:18:18 +02:00
if ( err ! = OK ) {
return ;
}
ResourceLoader : : get_classes_used ( pat . path , r_classes ) ;
}
2019-02-26 18:43:37 -03:00
2017-01-25 21:55:59 -03:00
void ResourceFormatImporter : : get_dependencies ( const String & p_path , List < String > * p_dependencies , bool p_add_types ) {
PathAndType pat ;
2025-01-27 21:42:02 +02:00
Error err = _get_path_and_type ( p_path , pat , false ) ;
2017-01-25 21:55:59 -03:00
if ( err ! = OK ) {
return ;
}
2019-07-01 12:59:42 +02:00
ResourceLoader : : get_dependencies ( pat . path , p_dependencies , p_add_types ) ;
2017-01-25 21:55:59 -03:00
}
2017-09-20 20:59:19 -03:00
Ref < ResourceImporter > ResourceFormatImporter : : get_importer_by_name ( const String & p_name ) const {
2018-01-06 16:36:49 -03:00
for ( int i = 0 ; i < importers . size ( ) ; i + + ) {
if ( importers [ i ] - > get_importer_name ( ) = = p_name ) {
return importers [ i ] ;
2017-02-01 09:45:45 -03:00
}
}
return Ref < ResourceImporter > ( ) ;
}
2021-05-13 22:34:34 +02:00
void ResourceFormatImporter : : add_importer ( const Ref < ResourceImporter > & p_importer , bool p_first_priority ) {
ERR_FAIL_COND ( p_importer . is_null ( ) ) ;
if ( p_first_priority ) {
importers . insert ( 0 , p_importer ) ;
} else {
importers . push_back ( p_importer ) ;
}
}
2025-02-15 15:08:56 -05:00
void ResourceFormatImporter : : get_importers_for_file ( const String & p_file , List < Ref < ResourceImporter > > * r_importers ) {
2018-01-06 16:36:49 -03:00
for ( int i = 0 ; i < importers . size ( ) ; i + + ) {
2017-02-01 09:45:45 -03:00
List < String > local_exts ;
2018-01-06 16:36:49 -03:00
importers [ i ] - > get_recognized_extensions ( & local_exts ) ;
2021-07-24 15:46:25 +02:00
for ( const String & F : local_exts ) {
2025-02-15 15:08:56 -05:00
if ( p_file . right ( F . length ( ) ) . nocasecmp_to ( F ) = = 0 ) {
2018-01-06 16:36:49 -03:00
r_importers - > push_back ( importers [ i ] ) ;
2024-06-03 17:28:46 +08:00
break ;
2017-02-01 09:45:45 -03:00
}
}
}
}
2021-02-23 14:17:42 -03:00
void ResourceFormatImporter : : get_importers ( List < Ref < ResourceImporter > > * r_importers ) {
for ( int i = 0 ; i < importers . size ( ) ; i + + ) {
r_importers - > push_back ( importers [ i ] ) ;
}
}
2025-02-15 15:08:56 -05:00
Ref < ResourceImporter > ResourceFormatImporter : : get_importer_by_file ( const String & p_file ) const {
2017-02-01 09:45:45 -03:00
Ref < ResourceImporter > importer ;
float priority = 0 ;
2018-01-06 16:36:49 -03:00
for ( int i = 0 ; i < importers . size ( ) ; i + + ) {
2017-02-01 09:45:45 -03:00
List < String > local_exts ;
2018-01-06 16:36:49 -03:00
importers [ i ] - > get_recognized_extensions ( & local_exts ) ;
2021-07-24 15:46:25 +02:00
for ( const String & F : local_exts ) {
2025-02-15 15:08:56 -05:00
if ( p_file . right ( F . length ( ) ) . nocasecmp_to ( F ) = = 0 & & importers [ i ] - > get_priority ( ) > priority ) {
2018-01-06 16:36:49 -03:00
importer = importers [ i ] ;
priority = importers [ i ] - > get_priority ( ) ;
2025-02-15 15:08:56 -05:00
break ;
2017-02-01 09:45:45 -03:00
}
}
}
return importer ;
}
String ResourceFormatImporter : : get_import_base_path ( const String & p_for_file ) const {
2022-08-29 19:34:01 -05:00
return ProjectSettings : : get_singleton ( ) - > get_imported_files_path ( ) . path_join ( p_for_file . get_file ( ) + " - " + p_for_file . md5_text ( ) ) ;
2017-02-01 09:45:45 -03:00
}
2019-02-26 18:43:37 -03:00
bool ResourceFormatImporter : : are_import_settings_valid ( const String & p_path ) const {
bool valid = true ;
PathAndType pat ;
2025-01-27 21:42:02 +02:00
_get_path_and_type ( p_path , pat , false , & valid ) ;
2019-02-26 18:43:37 -03:00
if ( ! valid ) {
return false ;
}
2019-02-27 08:57:37 +01:00
for ( int i = 0 ; i < importers . size ( ) ; i + + ) {
2019-02-26 18:43:37 -03:00
if ( importers [ i ] - > get_importer_name ( ) = = pat . importer ) {
2024-08-16 21:55:03 -04:00
if ( ! importers [ i ] - > are_import_settings_valid ( p_path , pat . metadata ) ) { //importer thinks this is not valid
2019-02-26 18:43:37 -03:00
return false ;
}
}
}
return true ;
}
2019-02-27 08:57:37 +01:00
String ResourceFormatImporter : : get_import_settings_hash ( ) const {
2020-03-17 07:33:00 +01:00
Vector < Ref < ResourceImporter > > sorted_importers = importers ;
2019-02-27 13:31:11 -03:00
sorted_importers . sort_custom < SortImporterByName > ( ) ;
2019-02-26 18:43:37 -03:00
String hash ;
2019-02-27 13:31:11 -03:00
for ( int i = 0 ; i < sorted_importers . size ( ) ; i + + ) {
hash + = " : " + sorted_importers [ i ] - > get_importer_name ( ) + " : " + sorted_importers [ i ] - > get_import_settings_string ( ) ;
2019-02-26 18:43:37 -03:00
}
return hash . md5_text ( ) ;
}
2020-04-02 01:20:12 +02:00
ResourceFormatImporter * ResourceFormatImporter : : singleton = nullptr ;
2017-02-01 09:45:45 -03:00
ResourceFormatImporter : : ResourceFormatImporter ( ) {
singleton = this ;
}
2021-07-23 12:10:32 +02:00
2021-05-13 22:34:34 +02:00
//////////////
2021-07-23 12:10:32 +02:00
void ResourceImporter : : _bind_methods ( ) {
BIND_ENUM_CONSTANT ( IMPORT_ORDER_DEFAULT ) ;
BIND_ENUM_CONSTANT ( IMPORT_ORDER_SCENE ) ;
}
2022-01-19 03:03:47 -08:00
2022-12-05 19:01:59 +01:00
/////
Error ResourceFormatImporterSaver : : set_uid ( const String & p_path , ResourceUID : : ID p_uid ) {
Ref < ConfigFile > cf ;
cf . instantiate ( ) ;
Error err = cf - > load ( p_path + " .import " ) ;
if ( err ! = OK ) {
return err ;
}
cf - > set_value ( " remap " , " uid " , ResourceUID : : get_singleton ( ) - > id_to_text ( p_uid ) ) ;
cf - > save ( p_path + " .import " ) ;
return OK ;
}