@@ -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. remove_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 ( & self , path : & AssetPath ) -> bool {
261
284
if let Some ( id) = self . path_to_id . get ( path) {
262
285
if let Some ( info) = self . infos . get ( id) {
@@ -266,12 +289,26 @@ impl AssetInfos {
266
289
false
267
290
}
268
291
292
+ /// Returns `true` if the asset at this path should be reloaded
293
+ pub ( crate ) fn should_reload ( & self , path : & AssetPath ) -> bool {
294
+ if self . is_path_alive ( path) {
295
+ return true ;
296
+ }
297
+
298
+ if let Some ( living) = self . living_labeled_assets . get ( path) {
299
+ !living. is_empty ( )
300
+ } else {
301
+ false
302
+ }
303
+ }
304
+
269
305
// Returns `true` if the asset should be removed from the collection
270
306
pub ( crate ) fn process_handle_drop ( & mut self , id : UntypedAssetId ) -> bool {
271
307
Self :: process_handle_drop_internal (
272
308
& mut self . infos ,
273
309
& mut self . path_to_id ,
274
310
& mut self . loader_dependants ,
311
+ & mut self . living_labeled_assets ,
275
312
self . watching_for_changes ,
276
313
id,
277
314
)
@@ -520,6 +557,7 @@ impl AssetInfos {
520
557
infos : & mut HashMap < UntypedAssetId , AssetInfo > ,
521
558
path_to_id : & mut HashMap < AssetPath < ' static > , UntypedAssetId > ,
522
559
loader_dependants : & mut HashMap < AssetPath < ' static > , HashSet < AssetPath < ' static > > > ,
560
+ living_labeled_assets : & mut HashMap < AssetPath < ' static > , HashSet < String > > ,
523
561
watching_for_changes : bool ,
524
562
id : UntypedAssetId ,
525
563
) -> bool {
@@ -539,6 +577,18 @@ impl AssetInfos {
539
577
dependants. remove ( & path) ;
540
578
}
541
579
}
580
+ if let Some ( label) = path. label ( ) {
581
+ let mut without_label = path. to_owned ( ) ;
582
+ without_label. remove_label ( ) ;
583
+ if let Entry :: Occupied ( mut entry) =
584
+ living_labeled_assets. entry ( without_label)
585
+ {
586
+ entry. get_mut ( ) . remove ( label) ;
587
+ if entry. get ( ) . is_empty ( ) {
588
+ entry. remove ( ) ;
589
+ }
590
+ } ;
591
+ }
542
592
}
543
593
path_to_id. remove ( & path) ;
544
594
}
@@ -565,6 +615,7 @@ impl AssetInfos {
565
615
& mut self . infos ,
566
616
& mut self . path_to_id ,
567
617
& mut self . loader_dependants ,
618
+ & mut self . living_labeled_assets ,
568
619
self . watching_for_changes ,
569
620
id. untyped ( provider. type_id ) ,
570
621
) ;
0 commit comments