@@ -257,21 +257,18 @@ impl AssetServer {
257
257
path : impl Into < AssetPath < ' a > > ,
258
258
meta_transform : Option < MetaTransform > ,
259
259
) -> Handle < A > {
260
- let mut path = path. into ( ) . into_owned ( ) ;
260
+ let path = path. into ( ) . into_owned ( ) ;
261
261
let ( handle, should_load) = self . data . infos . write ( ) . get_or_create_path_handle :: < A > (
262
262
path. clone ( ) ,
263
263
HandleLoadingMode :: Request ,
264
264
meta_transform,
265
265
) ;
266
266
267
267
if should_load {
268
- let mut owned_handle = Some ( handle. clone ( ) . untyped ( ) ) ;
268
+ let owned_handle = Some ( handle. clone ( ) . untyped ( ) ) ;
269
269
let server = self . clone ( ) ;
270
270
IoTaskPool :: get ( )
271
271
. spawn ( async move {
272
- if path. take_label ( ) . is_some ( ) {
273
- owned_handle = None ;
274
- }
275
272
if let Err ( err) = server. load_internal ( owned_handle, path, false , None ) . await {
276
273
error ! ( "{}" , err) ;
277
274
}
@@ -291,14 +288,18 @@ impl AssetServer {
291
288
self . load_internal ( None , path, false , None ) . await
292
289
}
293
290
291
+ /// Performs an async asset load.
292
+ ///
293
+ /// `input_handle` must only be [`Some`] if `should_load` was true when retrieving `input_handle`. This is an optimization to
294
+ /// avoid looking up `should_load` twice, but it means you _must_ be sure a load is necessary when calling this function with [`Some`].
294
295
async fn load_internal < ' a > (
295
296
& self ,
296
297
input_handle : Option < UntypedHandle > ,
297
298
path : AssetPath < ' a > ,
298
299
force : bool ,
299
300
meta_transform : Option < MetaTransform > ,
300
301
) -> Result < UntypedHandle , AssetLoadError > {
301
- let mut path = path. into_owned ( ) ;
302
+ let path = path. into_owned ( ) ;
302
303
let path_clone = path. clone ( ) ;
303
304
let ( mut meta, loader, mut reader) = self
304
305
. get_meta_loader_and_reader ( & path_clone)
@@ -312,18 +313,8 @@ impl AssetServer {
312
313
e
313
314
} ) ?;
314
315
315
- let has_label = path. label ( ) . is_some ( ) ;
316
-
317
316
let ( handle, should_load) = match input_handle {
318
317
Some ( handle) => {
319
- if !has_label && handle. type_id ( ) != loader. asset_type_id ( ) {
320
- return Err ( AssetLoadError :: RequestedHandleTypeMismatch {
321
- path : path. into_owned ( ) ,
322
- requested : handle. type_id ( ) ,
323
- actual_asset_name : loader. asset_type_name ( ) ,
324
- loader_name : loader. type_name ( ) ,
325
- } ) ;
326
- }
327
318
// if a handle was passed in, the "should load" check was already done
328
319
( handle, true )
329
320
}
@@ -339,51 +330,67 @@ impl AssetServer {
339
330
}
340
331
} ;
341
332
333
+ if path. label ( ) . is_none ( ) && handle. type_id ( ) != loader. asset_type_id ( ) {
334
+ return Err ( AssetLoadError :: RequestedHandleTypeMismatch {
335
+ path : path. into_owned ( ) ,
336
+ requested : handle. type_id ( ) ,
337
+ actual_asset_name : loader. asset_type_name ( ) ,
338
+ loader_name : loader. type_name ( ) ,
339
+ } ) ;
340
+ }
341
+
342
342
if !should_load && !force {
343
343
return Ok ( handle) ;
344
344
}
345
- let base_asset_id = if has_label {
346
- path. remove_label ( ) ;
347
- // If the path has a label, the current id does not match the asset root type.
348
- // We need to get the actual asset id
345
+
346
+ let ( base_handle, base_path) = if path. label ( ) . is_some ( ) {
349
347
let mut infos = self . data . infos . write ( ) ;
350
- let ( actual_handle, _) = infos. get_or_create_path_handle_untyped (
351
- path. clone ( ) ,
348
+ let base_path = path. without_label ( ) . into_owned ( ) ;
349
+ let ( base_handle, _) = infos. get_or_create_path_handle_untyped (
350
+ base_path. clone ( ) ,
352
351
loader. asset_type_id ( ) ,
353
352
loader. asset_type_name ( ) ,
354
- // ignore current load state ... we kicked off this sub asset load because it needed to be loaded but
355
- // does not currently exist
356
353
HandleLoadingMode :: Force ,
357
354
None ,
358
355
) ;
359
- actual_handle . id ( )
356
+ ( base_handle , base_path )
360
357
} else {
361
- handle. id ( )
358
+ ( handle. clone ( ) , path . clone ( ) )
362
359
} ;
363
360
364
- if let Some ( meta_transform) = handle . meta_transform ( ) {
361
+ if let Some ( meta_transform) = base_handle . meta_transform ( ) {
365
362
( * meta_transform) ( & mut * meta) ;
366
363
}
367
364
368
365
match self
369
- . load_with_meta_loader_and_reader ( & path , meta, & * loader, & mut * reader, true , false )
366
+ . load_with_meta_loader_and_reader ( & base_path , meta, & * loader, & mut * reader, true , false )
370
367
. await
371
368
{
372
369
Ok ( mut loaded_asset) => {
370
+ if let Some ( label) = path. label_cow ( ) {
371
+ if !loaded_asset. labeled_assets . contains_key ( & label) {
372
+ return Err ( AssetLoadError :: MissingLabel {
373
+ base_path,
374
+ label : label. to_string ( ) ,
375
+ } ) ;
376
+ }
377
+ }
373
378
for ( _, labeled_asset) in loaded_asset. labeled_assets . drain ( ) {
374
379
self . send_asset_event ( InternalAssetEvent :: Loaded {
375
380
id : labeled_asset. handle . id ( ) ,
376
381
loaded_asset : labeled_asset. asset ,
377
382
} ) ;
378
383
}
379
384
self . send_asset_event ( InternalAssetEvent :: Loaded {
380
- id : base_asset_id ,
385
+ id : base_handle . id ( ) ,
381
386
loaded_asset,
382
387
} ) ;
383
388
Ok ( handle)
384
389
}
385
390
Err ( err) => {
386
- self . send_asset_event ( InternalAssetEvent :: Failed { id : base_asset_id } ) ;
391
+ self . send_asset_event ( InternalAssetEvent :: Failed {
392
+ id : base_handle. id ( ) ,
393
+ } ) ;
387
394
Err ( err)
388
395
}
389
396
}
@@ -935,6 +942,11 @@ pub enum AssetLoadError {
935
942
loader_name : & ' static str ,
936
943
error : Box < dyn std:: error:: Error + Send + Sync + ' static > ,
937
944
} ,
945
+ #[ error( "The file at '{base_path}' does not contain the labeled asset '{label}'." ) ]
946
+ MissingLabel {
947
+ base_path : AssetPath < ' static > ,
948
+ label : String ,
949
+ } ,
938
950
}
939
951
940
952
/// An error that occurs when an [`AssetLoader`] is not registered for a given extension.
0 commit comments