Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bevy_asset_loader doesn't wait for asset dependencies #70

Closed
InnocentusLime opened this issue Jul 12, 2022 · 3 comments
Closed

bevy_asset_loader doesn't wait for asset dependencies #70

InnocentusLime opened this issue Jul 12, 2022 · 3 comments

Comments

@InnocentusLime
Copy link

In this minimal example the app will crash, since neither bevy's AssetServer or bevy_asset_loader wait for asset dependencies. So AssetA gets loaded successfully, but its slow dependency may not be loaded when you enter InGame state.

use bevy::prelude::*;
use bevy_asset_loader::*;
use iyes_loopless::prelude::*;

use anyhow::Error;
use bevy::reflect::TypeUuid;
use bevy::asset::{ 
    AssetLoader as AssetLoaderTrait, LoadContext, BoxedFuture, 
    LoadedAsset, Assets, AssetPath
};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum GameState {
    Boot,
    InGame,
}

// Imagine Asset A is some lightweight fast-to-load asset (like a config)
#[derive(TypeUuid)]
#[uuid="cc570c16-ffd0-11ec-b939-0242ac120003"]
struct AssetA;

// And Asset B is some heavy slow-to-load asset (a quite big texture) 
#[derive(TypeUuid)]
#[uuid="cc570c16-ffd0-11ec-b939-0242ac120002"]
struct AssetB;

#[derive(Clone, Copy, Default)]
struct AssetALoader;
        
impl AssetLoaderTrait for AssetALoader {
    fn load<'a>(
        &'a self, _bytes: &'a [u8], load_context: &'a mut LoadContext
    ) -> BoxedFuture<Result<(), Error>> { 
        Box::pin(async move {
            let mut asset = LoadedAsset::new(AssetA);
            asset.add_dependency("B.b".into());
            load_context.set_default_asset(asset);
            Ok(())
        })
    }

    fn extensions(&self) -> &[&str] { &["a"] }
}

#[derive(Clone, Copy, Default)]
struct AssetBLoader;

impl AssetLoaderTrait for AssetBLoader {
    fn load<'a>(
        &'a self, _bytes: &'a [u8], load_context: &'a mut LoadContext
    ) -> BoxedFuture<Result<(), Error>> { 
        Box::pin(async move {
            use std::time::Duration;

            let asset = LoadedAsset::new(AssetB);
            // Pretend that we are parsing a large file (a .png)
            std::thread::sleep(Duration::from_secs(10));
            load_context.set_default_asset(asset);
            Ok(())
        })
    }

    fn extensions(&self) -> &[&str] { &["b"] }
}

#[derive(AssetCollection)]
struct ACol {
    #[asset(path = "A.a")]
    _asset: Handle<AssetA>,
}

fn test_enter(assets_a: Res<Assets<AssetA>>, assets_b: Res<Assets<AssetB>>) {
    assert!(assets_a.get::<AssetPath>("A.a".into()).is_some());
    println!("asset A loaded");
    assert!(assets_b.get::<AssetPath>("B.b".into()).is_some());
    println!("asset B loaded");
}

fn main() {
    let mut app = App::new();

    app
        .add_plugins(DefaultPlugins)
        .add_asset::<AssetA>()
        .add_asset::<AssetB>()
        .init_asset_loader::<AssetALoader>()
        .init_asset_loader::<AssetBLoader>()
        .add_loopless_state(GameState::Boot)
        .add_enter_system(GameState::InGame, test_enter);
    
    AssetLoader::new(GameState::Boot)
        .continue_to_state(GameState::InGame)
        .with_collection::<ACol>()
        .build(&mut app);

    app.run();
}
@InnocentusLime InnocentusLime changed the title The lib doesn't wait for asset dependencies bevy_asset_loader doesn't wait for asset dependencies Jul 12, 2022
@NiklasEi
Copy link
Owner

This seems to be a duplicate of #63

It also seems like weird behaviour from Bevy itself.

@InnocentusLime
Copy link
Author

I don't know if it is weird or not. Looking through AssetServer code, it is revealed, that bevy handles dependencies asynchronously, but never .awaits them.

@InnocentusLime
Copy link
Author

This seems to be a duplicate of #63

It also seems like weird behaviour from Bevy itself.

Indeed it is! Closing as a duplicate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants