@@ -226,8 +226,10 @@ where
226
226
pub mod export_info_functions {
227
227
use crate :: builtin:: GString ;
228
228
use crate :: global:: PropertyHint ;
229
- use crate :: meta:: PropertyHintInfo ;
229
+ use crate :: meta:: { GodotType , PropertyHintInfo , PropertyInfo } ;
230
+ use crate :: obj:: EngineEnum ;
230
231
use crate :: registry:: property:: Export ;
232
+ use godot_ffi:: VariantType ;
231
233
232
234
/// Turn a list of variables into a comma separated string containing only the identifiers corresponding
233
235
/// to a true boolean variable.
@@ -416,19 +418,67 @@ pub mod export_info_functions {
416
418
is_global : bool ,
417
419
filter : impl AsRef < str > ,
418
420
) -> PropertyHintInfo {
421
+ let field_ty = T :: Via :: property_info ( "" ) ;
419
422
let filter = filter. as_ref ( ) ;
420
423
debug_assert ! ( is_file || filter. is_empty( ) ) ; // Dir never has filter.
421
424
425
+ export_file_or_dir_inner ( & field_ty, is_file, is_global, filter)
426
+ }
427
+
428
+ pub fn export_file_or_dir_inner (
429
+ field_ty : & PropertyInfo ,
430
+ is_file : bool ,
431
+ is_global : bool ,
432
+ filter : & str ,
433
+ ) -> PropertyHintInfo {
422
434
let hint = match ( is_file, is_global) {
423
435
( true , true ) => PropertyHint :: GLOBAL_FILE ,
424
436
( true , false ) => PropertyHint :: FILE ,
425
437
( false , true ) => PropertyHint :: GLOBAL_DIR ,
426
438
( false , false ) => PropertyHint :: DIR ,
427
439
} ;
428
440
441
+ // Returned value depends on field type.
442
+ match field_ty. variant_type {
443
+ // GString field:
444
+ // { "type": 4, "hint": 13, "hint_string": "*.png" }
445
+ VariantType :: STRING => PropertyHintInfo {
446
+ hint,
447
+ hint_string : GString :: from ( filter) ,
448
+ } ,
449
+
450
+ // Array<GString> or PackedStringArray field:
451
+ // { "type": 28, "hint": 23, "hint_string": "4/13:*.png" }
452
+ VariantType :: PACKED_STRING_ARRAY => to_string_array_hint ( hint, filter) ,
453
+ VariantType :: ARRAY if field_ty. is_array_of_elem :: < GString > ( ) => {
454
+ to_string_array_hint ( hint, filter)
455
+ }
456
+
457
+ _ => {
458
+ // E.g. `global_file`.
459
+ let attribute_name = hint. as_str ( ) . to_lowercase ( ) ;
460
+
461
+ // TODO nicer error handling.
462
+ // Compile time may be difficult (at least without extra traits... maybe const fn?). But at least more context info, field name etc.
463
+ panic ! (
464
+ "#[export({attribute_name})] only supports GString, Array<String> or PackedStringArray field types\n \
465
+ encountered: {field_ty:?}"
466
+ ) ;
467
+ }
468
+ }
469
+ }
470
+
471
+ /// For `Array<GString>` and `PackedStringArray` fields using one of the `@export[_global]_{file|dir}` annotations.
472
+ ///
473
+ /// Formats: `"4/13:"`, `"4/15:*.png"`, ...
474
+ fn to_string_array_hint ( hint : PropertyHint , filter : & str ) -> PropertyHintInfo {
475
+ let variant_ord = VariantType :: STRING . ord ( ) ; // "4"
476
+ let hint_ord = hint. ord ( ) ;
477
+ let hint_string = format ! ( "{variant_ord}/{hint_ord}" ) ;
478
+
429
479
PropertyHintInfo {
430
- hint,
431
- hint_string : GString :: from ( filter) ,
480
+ hint : PropertyHint :: TYPE_STRING ,
481
+ hint_string : format ! ( "{hint_string}:{ filter}" ) . into ( ) ,
432
482
}
433
483
}
434
484
@@ -603,9 +653,9 @@ pub(crate) fn builtin_type_string<T: GodotType>() -> String {
603
653
604
654
// Godot 4.3 changed representation for type hints, see https://github.com/godotengine/godot/pull/90716.
605
655
if sys:: GdextBuild :: since_api ( "4.3" ) {
606
- format ! ( "{}:" , variant_type. sys ( ) )
656
+ format ! ( "{}:" , variant_type. ord ( ) )
607
657
} else {
608
- format ! ( "{}:{}" , variant_type. sys ( ) , T :: godot_type_name( ) )
658
+ format ! ( "{}:{}" , variant_type. ord ( ) , T :: godot_type_name( ) )
609
659
}
610
660
}
611
661
0 commit comments