@@ -69,6 +69,9 @@ pub(crate) struct AssetInfos {
69
69
/// Tracks assets that depend on the "key" asset path inside their asset loaders ("loader dependencies")
70
70
/// This should only be set when watching for changes to avoid unnecessary work.
71
71
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 > > ,
72
75
pub ( crate ) handle_providers : HashMap < TypeId , AssetHandleProvider > ,
73
76
pub ( crate ) dependency_loaded_event_sender : HashMap < TypeId , fn ( & mut World , UntypedAssetId ) > ,
74
77
}
@@ -88,6 +91,8 @@ impl AssetInfos {
88
91
Self :: create_handle_internal (
89
92
& mut self . infos ,
90
93
& self . handle_providers ,
94
+ & mut self . living_labeled_assets ,
95
+ self . watching_for_changes ,
91
96
TypeId :: of :: < A > ( ) ,
92
97
None ,
93
98
None ,
@@ -107,6 +112,8 @@ impl AssetInfos {
107
112
Self :: create_handle_internal (
108
113
& mut self . infos ,
109
114
& self . handle_providers ,
115
+ & mut self . living_labeled_assets ,
116
+ self . watching_for_changes ,
110
117
type_id,
111
118
None ,
112
119
None ,
@@ -116,9 +123,12 @@ impl AssetInfos {
116
123
)
117
124
}
118
125
126
+ #[ allow( clippy:: too_many_arguments) ]
119
127
fn create_handle_internal (
120
128
infos : & mut HashMap < UntypedAssetId , AssetInfo > ,
121
129
handle_providers : & HashMap < TypeId , AssetHandleProvider > ,
130
+ living_labeled_assets : & mut HashMap < AssetPath < ' static > , HashSet < String > > ,
131
+ watching_for_changes : bool ,
122
132
type_id : TypeId ,
123
133
path : Option < AssetPath < ' static > > ,
124
134
meta_transform : Option < MetaTransform > ,
@@ -128,6 +138,16 @@ impl AssetInfos {
128
138
. get ( & type_id)
129
139
. ok_or ( MissingHandleProviderError ( type_id) ) ?;
130
140
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. take_label ( ) {
145
+ let labels = living_labeled_assets. entry ( without_label) . or_default ( ) ;
146
+ labels. insert ( label. to_string ( ) ) ;
147
+ }
148
+ }
149
+ }
150
+
131
151
let handle = provider. reserve_handle_internal ( true , path. clone ( ) , meta_transform) ;
132
152
let mut info = AssetInfo :: new ( Arc :: downgrade ( & handle) , path) ;
133
153
if loading {
@@ -136,6 +156,7 @@ impl AssetInfos {
136
156
info. rec_dep_load_state = RecursiveDependencyLoadState :: Loading ;
137
157
}
138
158
infos. insert ( handle. id , info) ;
159
+
139
160
Ok ( UntypedHandle :: Strong ( handle) )
140
161
}
141
162
@@ -226,6 +247,8 @@ impl AssetInfos {
226
247
let handle = Self :: create_handle_internal (
227
248
& mut self . infos ,
228
249
& self . handle_providers ,
250
+ & mut self . living_labeled_assets ,
251
+ self . watching_for_changes ,
229
252
type_id,
230
253
Some ( path) ,
231
254
meta_transform,
@@ -256,7 +279,7 @@ impl AssetInfos {
256
279
Some ( UntypedHandle :: Strong ( strong_handle) )
257
280
}
258
281
259
- /// Returns `true` if this path has
282
+ /// Returns `true` if the asset this path points to is still alive
260
283
pub ( crate ) fn is_path_alive < ' a > ( & self , path : impl Into < AssetPath < ' a > > ) -> bool {
261
284
let path = path. into ( ) ;
262
285
if let Some ( id) = self . path_to_id . get ( & path) {
@@ -267,12 +290,26 @@ impl AssetInfos {
267
290
false
268
291
}
269
292
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
+
270
306
// Returns `true` if the asset should be removed from the collection
271
307
pub ( crate ) fn process_handle_drop ( & mut self , id : UntypedAssetId ) -> bool {
272
308
Self :: process_handle_drop_internal (
273
309
& mut self . infos ,
274
310
& mut self . path_to_id ,
275
311
& mut self . loader_dependants ,
312
+ & mut self . living_labeled_assets ,
276
313
self . watching_for_changes ,
277
314
id,
278
315
)
@@ -521,6 +558,7 @@ impl AssetInfos {
521
558
infos : & mut HashMap < UntypedAssetId , AssetInfo > ,
522
559
path_to_id : & mut HashMap < AssetPath < ' static > , UntypedAssetId > ,
523
560
loader_dependants : & mut HashMap < AssetPath < ' static > , HashSet < AssetPath < ' static > > > ,
561
+ living_labeled_assets : & mut HashMap < AssetPath < ' static > , HashSet < String > > ,
524
562
watching_for_changes : bool ,
525
563
id : UntypedAssetId ,
526
564
) -> bool {
@@ -540,6 +578,18 @@ impl AssetInfos {
540
578
dependants. remove ( & path) ;
541
579
}
542
580
}
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
+ }
543
593
}
544
594
path_to_id. remove ( & path) ;
545
595
}
@@ -566,6 +616,7 @@ impl AssetInfos {
566
616
& mut self . infos ,
567
617
& mut self . path_to_id ,
568
618
& mut self . loader_dependants ,
619
+ & mut self . living_labeled_assets ,
569
620
self . watching_for_changes ,
570
621
id. untyped ( provider. type_id ) ,
571
622
) ;
0 commit comments