@@ -718,8 +718,8 @@ mod tests {
718718 } ,
719719 loader:: { AssetLoader , LoadContext } ,
720720 Asset , AssetApp , AssetEvent , AssetId , AssetLoadError , AssetLoadFailedEvent , AssetPath ,
721- AssetPlugin , AssetServer , Assets , InvalidGenerationError , LoadState , UnapprovedPathMode ,
722- UntypedHandle ,
721+ AssetPlugin , AssetServer , Assets , InvalidGenerationError , LoadState , LoadedAsset ,
722+ UnapprovedPathMode , UntypedHandle ,
723723 } ;
724724 use alloc:: {
725725 boxed:: Box ,
@@ -743,6 +743,7 @@ mod tests {
743743 } ;
744744 use bevy_reflect:: TypePath ;
745745 use core:: time:: Duration ;
746+ use futures_lite:: AsyncReadExt ;
746747 use serde:: { Deserialize , Serialize } ;
747748 use std:: path:: { Path , PathBuf } ;
748749 use thiserror:: Error ;
@@ -762,7 +763,7 @@ mod tests {
762763 pub text : String ,
763764 }
764765
765- #[ derive( Serialize , Deserialize ) ]
766+ #[ derive( Serialize , Deserialize , Default ) ]
766767 pub struct CoolTextRon {
767768 pub text : String ,
768769 pub dependencies : Vec < String > ,
@@ -2644,4 +2645,97 @@ mod tests {
26442645 // assert_eq!(get_started_load_count(app.world()), 1);
26452646 assert_eq ! ( get_started_load_count( app. world( ) ) , 2 ) ;
26462647 }
2648+
2649+ #[ test]
2650+ fn immediate_nested_asset_loads_dependency ( ) {
2651+ let ( mut app, dir) = create_app ( ) ;
2652+
2653+ /// This asset holds a handle to its dependency.
2654+ #[ derive( Asset , TypePath ) ]
2655+ struct DeferredNested ( Handle < TestAsset > ) ;
2656+
2657+ struct DeferredNestedLoader ;
2658+
2659+ impl AssetLoader for DeferredNestedLoader {
2660+ type Asset = DeferredNested ;
2661+ type Settings = ( ) ;
2662+ type Error = std:: io:: Error ;
2663+
2664+ async fn load (
2665+ & self ,
2666+ reader : & mut dyn Reader ,
2667+ _: & Self :: Settings ,
2668+ load_context : & mut LoadContext < ' _ > ,
2669+ ) -> Result < Self :: Asset , Self :: Error > {
2670+ let mut nested_path = String :: new ( ) ;
2671+ reader. read_to_string ( & mut nested_path) . await ?;
2672+ Ok ( DeferredNested ( load_context. load ( nested_path) ) )
2673+ }
2674+
2675+ fn extensions ( & self ) -> & [ & str ] {
2676+ & [ "defer" ]
2677+ }
2678+ }
2679+
2680+ /// This asset holds a handle a dependency of one of its dependencies.
2681+ #[ derive( Asset , TypePath ) ]
2682+ struct ImmediateNested ( Handle < TestAsset > ) ;
2683+
2684+ struct ImmediateNestedLoader ;
2685+
2686+ impl AssetLoader for ImmediateNestedLoader {
2687+ type Asset = ImmediateNested ;
2688+ type Settings = ( ) ;
2689+ type Error = std:: io:: Error ;
2690+
2691+ async fn load (
2692+ & self ,
2693+ reader : & mut dyn Reader ,
2694+ _: & Self :: Settings ,
2695+ load_context : & mut LoadContext < ' _ > ,
2696+ ) -> Result < Self :: Asset , Self :: Error > {
2697+ let mut nested_path = String :: new ( ) ;
2698+ reader. read_to_string ( & mut nested_path) . await ?;
2699+ let deferred_nested: LoadedAsset < DeferredNested > = load_context
2700+ . loader ( )
2701+ . immediate ( )
2702+ . load ( nested_path)
2703+ . await
2704+ . unwrap ( ) ;
2705+ Ok ( ImmediateNested ( deferred_nested. get ( ) . 0 . clone ( ) ) )
2706+ }
2707+
2708+ fn extensions ( & self ) -> & [ & str ] {
2709+ & [ "immediate" ]
2710+ }
2711+ }
2712+
2713+ app. init_asset :: < TestAsset > ( )
2714+ . init_asset :: < DeferredNested > ( )
2715+ . init_asset :: < ImmediateNested > ( )
2716+ . register_asset_loader ( TrivialLoader )
2717+ . register_asset_loader ( DeferredNestedLoader )
2718+ . register_asset_loader ( ImmediateNestedLoader ) ;
2719+
2720+ dir. insert_asset_text ( Path :: new ( "a.immediate" ) , "b.defer" ) ;
2721+ dir. insert_asset_text ( Path :: new ( "b.defer" ) , "c.txt" ) ;
2722+ dir. insert_asset_text ( Path :: new ( "c.txt" ) , "hiya" ) ;
2723+
2724+ let server = app. world ( ) . resource :: < AssetServer > ( ) . clone ( ) ;
2725+ let immediate_handle: Handle < ImmediateNested > = server. load ( "a.immediate" ) ;
2726+
2727+ run_app_until ( & mut app, |world| {
2728+ let immediate_assets = world. resource :: < Assets < ImmediateNested > > ( ) ;
2729+ let immediate = immediate_assets. get ( & immediate_handle) ?;
2730+
2731+ let test_asset_handle = immediate. 0 . clone ( ) ;
2732+ world
2733+ . resource :: < Assets < TestAsset > > ( )
2734+ . get ( & test_asset_handle) ?;
2735+
2736+ // The immediate asset is loaded, and the asset it got from its immediate load is also
2737+ // loaded.
2738+ Some ( ( ) )
2739+ } ) ;
2740+ }
26472741}
0 commit comments