@@ -58,10 +58,12 @@ use crate::{
58
58
AssetLoadError , AssetMetaCheck , AssetPath , AssetServer , AssetServerMode , DeserializeMetaError ,
59
59
MissingAssetLoaderForExtensionError , UnapprovedPathMode , WriteDefaultMetaError ,
60
60
} ;
61
- use alloc:: { borrow:: ToOwned , boxed:: Box , collections:: VecDeque , sync:: Arc , vec, vec:: Vec } ;
61
+ use alloc:: {
62
+ borrow:: ToOwned , boxed:: Box , collections:: VecDeque , string:: String , sync:: Arc , vec, vec:: Vec ,
63
+ } ;
62
64
use bevy_ecs:: prelude:: * ;
63
65
use bevy_platform:: {
64
- collections:: { HashMap , HashSet } ,
66
+ collections:: { hash_map :: Entry , HashMap , HashSet } ,
65
67
sync:: { PoisonError , RwLock } ,
66
68
} ;
67
69
use bevy_tasks:: IoTaskPool ;
@@ -117,11 +119,27 @@ pub struct AssetProcessorData {
117
119
struct Processors {
118
120
/// Maps the type path of the processor to its instance.
119
121
type_path_to_processor : HashMap < & ' static str , Arc < dyn ErasedProcessor > > ,
122
+ /// Maps the short type path of the processor to its instance.
123
+ short_type_path_to_processor : HashMap < & ' static str , ShortTypeProcessorEntry > ,
120
124
/// Maps the file extension of an asset to the type path of the processor we should use to
121
125
/// process it by default.
122
126
file_extension_to_default_processor : HashMap < Box < str > , & ' static str > ,
123
127
}
124
128
129
+ enum ShortTypeProcessorEntry {
130
+ /// There is a unique processor with the given short type path.
131
+ Unique {
132
+ /// The full type path of the processor.
133
+ type_path : & ' static str ,
134
+ /// The processor itself.
135
+ processor : Arc < dyn ErasedProcessor > ,
136
+ } ,
137
+ /// There are (at least) two processors with the same short type path (storing the full type
138
+ /// paths of all conflicting processors). Users must fully specify the type path in order to
139
+ /// disambiguate.
140
+ Ambiguous ( Vec < & ' static str > ) ,
141
+ }
142
+
125
143
impl AssetProcessor {
126
144
/// Creates a new [`AssetProcessor`] instance.
127
145
pub fn new ( source : & mut AssetSourceBuilders ) -> Self {
@@ -600,9 +618,31 @@ impl AssetProcessor {
600
618
. unwrap_or_else ( PoisonError :: into_inner) ;
601
619
#[ cfg( feature = "trace" ) ]
602
620
let processor = InstrumentedAssetProcessor ( processor) ;
621
+ let processor = Arc :: new ( processor) ;
603
622
processors
604
623
. type_path_to_processor
605
- . insert ( P :: type_path ( ) , Arc :: new ( processor) ) ;
624
+ . insert ( P :: type_path ( ) , processor. clone ( ) ) ;
625
+ match processors
626
+ . short_type_path_to_processor
627
+ . entry ( P :: short_type_path ( ) )
628
+ {
629
+ Entry :: Vacant ( entry) => {
630
+ entry. insert ( ShortTypeProcessorEntry :: Unique {
631
+ type_path : P :: type_path ( ) ,
632
+ processor,
633
+ } ) ;
634
+ }
635
+ Entry :: Occupied ( mut entry) => match entry. get_mut ( ) {
636
+ ShortTypeProcessorEntry :: Unique { type_path, .. } => {
637
+ let type_path = * type_path;
638
+ * entry. get_mut ( ) =
639
+ ShortTypeProcessorEntry :: Ambiguous ( vec ! [ type_path, P :: type_path( ) ] ) ;
640
+ }
641
+ ShortTypeProcessorEntry :: Ambiguous ( type_paths) => {
642
+ type_paths. push ( P :: type_path ( ) ) ;
643
+ }
644
+ } ,
645
+ }
606
646
}
607
647
608
648
/// Set the default processor for the given `extension`. Make sure `P` is registered with [`AssetProcessor::register_processor`].
@@ -631,16 +671,32 @@ impl AssetProcessor {
631
671
}
632
672
633
673
/// Returns the processor with the given `processor_type_name`, if it exists.
634
- pub fn get_processor ( & self , processor_type_name : & str ) -> Option < Arc < dyn ErasedProcessor > > {
674
+ pub fn get_processor (
675
+ & self ,
676
+ processor_type_name : & str ,
677
+ ) -> Result < Arc < dyn ErasedProcessor > , GetProcessorError > {
635
678
let processors = self
636
679
. data
637
680
. processors
638
681
. read ( )
639
682
. unwrap_or_else ( PoisonError :: into_inner) ;
683
+ if let Some ( short_type_processor) = processors
684
+ . short_type_path_to_processor
685
+ . get ( processor_type_name)
686
+ {
687
+ return match short_type_processor {
688
+ ShortTypeProcessorEntry :: Unique { processor, .. } => Ok ( processor. clone ( ) ) ,
689
+ ShortTypeProcessorEntry :: Ambiguous ( examples) => Err ( GetProcessorError :: Ambiguous {
690
+ processor_short_name : processor_type_name. to_owned ( ) ,
691
+ ambiguous_processor_names : examples. clone ( ) ,
692
+ } ) ,
693
+ } ;
694
+ }
640
695
processors
641
696
. type_path_to_processor
642
697
. get ( processor_type_name)
643
698
. cloned ( )
699
+ . ok_or_else ( || GetProcessorError :: Missing ( processor_type_name. to_owned ( ) ) )
644
700
}
645
701
646
702
/// Populates the initial view of each asset by scanning the unprocessed and processed asset folders.
@@ -864,9 +920,7 @@ impl AssetProcessor {
864
920
( meta, None )
865
921
}
866
922
AssetActionMinimal :: Process { processor } => {
867
- let processor = self
868
- . get_processor ( & processor)
869
- . ok_or_else ( || ProcessError :: MissingProcessor ( processor) ) ?;
923
+ let processor = self . get_processor ( & processor) ?;
870
924
let meta = processor. deserialize_meta ( & meta_bytes) ?;
871
925
( meta, Some ( processor) )
872
926
}
@@ -1511,3 +1565,30 @@ pub enum InitializeError {
1511
1565
#[ error( "Failed to validate asset log: {0}" ) ]
1512
1566
ValidateLogError ( #[ from] ValidateLogError ) ,
1513
1567
}
1568
+
1569
+ /// An error when retrieving an asset processor.
1570
+ #[ derive( Error , Debug ) ]
1571
+ pub enum GetProcessorError {
1572
+ #[ error( "The processor '{0}' does not exist" ) ]
1573
+ Missing ( String ) ,
1574
+ #[ error( "The processor '{processor_short_name}' is ambiguous between several processors: {ambiguous_processor_names:?}" ) ]
1575
+ Ambiguous {
1576
+ processor_short_name : String ,
1577
+ ambiguous_processor_names : Vec < & ' static str > ,
1578
+ } ,
1579
+ }
1580
+
1581
+ impl From < GetProcessorError > for ProcessError {
1582
+ fn from ( err : GetProcessorError ) -> Self {
1583
+ match err {
1584
+ GetProcessorError :: Missing ( name) => Self :: MissingProcessor ( name) ,
1585
+ GetProcessorError :: Ambiguous {
1586
+ processor_short_name,
1587
+ ambiguous_processor_names,
1588
+ } => Self :: AmbiguousProcessor {
1589
+ processor_short_name,
1590
+ ambiguous_processor_names,
1591
+ } ,
1592
+ }
1593
+ }
1594
+ }
0 commit comments