@@ -69,6 +69,9 @@ pub(crate) struct AssetInfos {
6969 /// Tracks assets that depend on the "key" asset path inside their asset loaders ("loader dependencies")
7070 /// This should only be set when watching for changes to avoid unnecessary work.
7171 pub ( crate ) loader_dependants : HashMap < AssetPath < ' static > , HashSet < AssetPath < ' static > > > ,
72+ /// Tracks living labeled assets for a given source asset.
73+ /// This should only be set when watching for changes to avoid unnecessary work.
74+ pub ( crate ) living_labeled_assets : HashMap < AssetPath < ' static > , HashSet < String > > ,
7275 pub ( crate ) handle_providers : HashMap < TypeId , AssetHandleProvider > ,
7376 pub ( crate ) dependency_loaded_event_sender : HashMap < TypeId , fn ( & mut World , UntypedAssetId ) > ,
7477}
@@ -88,6 +91,8 @@ impl AssetInfos {
8891 Self :: create_handle_internal (
8992 & mut self . infos ,
9093 & self . handle_providers ,
94+ & mut self . living_labeled_assets ,
95+ self . watching_for_changes ,
9196 TypeId :: of :: < A > ( ) ,
9297 None ,
9398 None ,
@@ -107,6 +112,8 @@ impl AssetInfos {
107112 Self :: create_handle_internal (
108113 & mut self . infos ,
109114 & self . handle_providers ,
115+ & mut self . living_labeled_assets ,
116+ self . watching_for_changes ,
110117 type_id,
111118 None ,
112119 None ,
@@ -116,9 +123,12 @@ impl AssetInfos {
116123 )
117124 }
118125
126+ #[ allow( clippy:: too_many_arguments) ]
119127 fn create_handle_internal (
120128 infos : & mut HashMap < UntypedAssetId , AssetInfo > ,
121129 handle_providers : & HashMap < TypeId , AssetHandleProvider > ,
130+ living_labeled_assets : & mut HashMap < AssetPath < ' static > , HashSet < String > > ,
131+ watching_for_changes : bool ,
122132 type_id : TypeId ,
123133 path : Option < AssetPath < ' static > > ,
124134 meta_transform : Option < MetaTransform > ,
@@ -128,6 +138,16 @@ impl AssetInfos {
128138 . get ( & type_id)
129139 . ok_or ( MissingHandleProviderError ( type_id) ) ?;
130140
141+ if watching_for_changes {
142+ if let Some ( path) = & path {
143+ let mut without_label = path. to_owned ( ) ;
144+ if let Some ( label) = without_label. remove_label ( ) {
145+ let labels = living_labeled_assets. entry ( without_label) . or_default ( ) ;
146+ labels. insert ( label. to_string ( ) ) ;
147+ }
148+ }
149+ }
150+
131151 let handle = provider. reserve_handle_internal ( true , path. clone ( ) , meta_transform) ;
132152 let mut info = AssetInfo :: new ( Arc :: downgrade ( & handle) , path) ;
133153 if loading {
@@ -136,6 +156,7 @@ impl AssetInfos {
136156 info. rec_dep_load_state = RecursiveDependencyLoadState :: Loading ;
137157 }
138158 infos. insert ( handle. id , info) ;
159+
139160 Ok ( UntypedHandle :: Strong ( handle) )
140161 }
141162
@@ -226,6 +247,8 @@ impl AssetInfos {
226247 let handle = Self :: create_handle_internal (
227248 & mut self . infos ,
228249 & self . handle_providers ,
250+ & mut self . living_labeled_assets ,
251+ self . watching_for_changes ,
229252 type_id,
230253 Some ( path) ,
231254 meta_transform,
@@ -256,7 +279,7 @@ impl AssetInfos {
256279 Some ( UntypedHandle :: Strong ( strong_handle) )
257280 }
258281
259- /// Returns `true` if this path has
282+ /// Returns `true` if the asset this path points to is still alive
260283 pub ( crate ) fn is_path_alive < ' a > ( & self , path : impl Into < AssetPath < ' a > > ) -> bool {
261284 let path = path. into ( ) ;
262285 if let Some ( id) = self . path_to_id . get ( & path) {
@@ -267,12 +290,26 @@ impl AssetInfos {
267290 false
268291 }
269292
293+ /// Returns `true` if the asset at this path should be reloaded
294+ pub ( crate ) fn should_reload ( & self , path : & AssetPath ) -> bool {
295+ if self . is_path_alive ( path) {
296+ return true ;
297+ }
298+
299+ if let Some ( living) = self . living_labeled_assets . get ( path) {
300+ !living. is_empty ( )
301+ } else {
302+ false
303+ }
304+ }
305+
270306 // Returns `true` if the asset should be removed from the collection
271307 pub ( crate ) fn process_handle_drop ( & mut self , id : UntypedAssetId ) -> bool {
272308 Self :: process_handle_drop_internal (
273309 & mut self . infos ,
274310 & mut self . path_to_id ,
275311 & mut self . loader_dependants ,
312+ & mut self . living_labeled_assets ,
276313 self . watching_for_changes ,
277314 id,
278315 )
@@ -521,6 +558,7 @@ impl AssetInfos {
521558 infos : & mut HashMap < UntypedAssetId , AssetInfo > ,
522559 path_to_id : & mut HashMap < AssetPath < ' static > , UntypedAssetId > ,
523560 loader_dependants : & mut HashMap < AssetPath < ' static > , HashSet < AssetPath < ' static > > > ,
561+ living_labeled_assets : & mut HashMap < AssetPath < ' static > , HashSet < String > > ,
524562 watching_for_changes : bool ,
525563 id : UntypedAssetId ,
526564 ) -> bool {
@@ -540,6 +578,18 @@ impl AssetInfos {
540578 dependants. remove ( & path) ;
541579 }
542580 }
581+ if let Some ( label) = path. label ( ) {
582+ let mut without_label = path. to_owned ( ) ;
583+ without_label. remove_label ( ) ;
584+ if let Entry :: Occupied ( mut entry) =
585+ living_labeled_assets. entry ( without_label)
586+ {
587+ entry. get_mut ( ) . remove ( label) ;
588+ if entry. get ( ) . is_empty ( ) {
589+ entry. remove ( ) ;
590+ }
591+ } ;
592+ }
543593 }
544594 path_to_id. remove ( & path) ;
545595 }
@@ -566,6 +616,7 @@ impl AssetInfos {
566616 & mut self . infos ,
567617 & mut self . path_to_id ,
568618 & mut self . loader_dependants ,
619+ & mut self . living_labeled_assets ,
569620 self . watching_for_changes ,
570621 id. untyped ( provider. type_id ) ,
571622 ) ;
0 commit comments