use bevy::{asset::ErasedLoadedAsset, platform::collections::HashMap, prelude::*};
use std::pin::Pin;
use super::{AssetsBundle, BundleEntry};
use crate::prelude::*;
pub trait LoadAssetFrom: Asset + Sized {
fn load_from<'a>(
key: String,
entry: BundleEntry,
load_context: &'a mut bevy::asset::LoadContext<'_>,
) -> Pin<Box<dyn Future<Output = Result<Self, Error>> + Send + 'a>>;
}
impl LoadAssetFrom for crate::assets::Text {
fn load_from<'a>(
key: String,
entry: BundleEntry,
load_context: &'a mut bevy::asset::LoadContext<'_>,
) -> Pin<Box<dyn Future<Output = Result<Self, Error>> + Send + 'a>> {
Box::pin(async move {
match entry {
BundleEntry::File(path) => {
let path = load_context.path().parent().unwrap().resolve(&path)?;
Ok(load_context.loader().immediate().load(path).await?.take())
}
BundleEntry::Text(content) => Ok(Self::new(content)),
_ => Err(Error::IncompatibleEntry { key }),
}
})
}
}
#[cfg(feature = "atlas_layout")]
impl LoadAssetFrom for TextureAtlasLayout {
fn load_from<'a>(
key: String,
entry: BundleEntry,
load_context: &'a mut bevy::asset::LoadContext<'_>,
) -> Pin<Box<dyn Future<Output = Result<Self, Error>> + Send + 'a>> {
Box::pin(async move {
match entry {
BundleEntry::File(path) => {
let path = load_context.path().parent().unwrap().resolve(&path)?;
Ok(load_context.loader().immediate().load(path).await?.take())
}
BundleEntry::TextureAtlasLayout(layout) => Ok(layout.into()),
_ => Err(Error::IncompatibleEntry { key }),
}
})
}
}
impl LoadAssetFrom for AssetsBundle {
fn load_from<'a>(
key: String,
entry: BundleEntry,
load_context: &'a mut bevy::asset::LoadContext<'_>,
) -> Pin<Box<dyn Future<Output = Result<AssetsBundle, Error>> + Send + 'a>> {
Box::pin(async move {
match entry {
BundleEntry::File(path) => {
let path = load_context.path().parent().unwrap().resolve(&path)?;
Ok(load_context.loader().immediate().load(path).await?.take())
}
BundleEntry::Bundle(assets) => {
let mut loaded_assets: HashMap<String, ErasedLoadedAsset> = Default::default();
for (k, v) in assets.into_iter() {
let asset = v.load_asset(&k, load_context).await?;
loaded_assets.insert(k, asset);
}
Ok(AssetsBundle {
assets: loaded_assets,
})
}
_ => Err(Error::IncompatibleEntry { key }),
}
})
}
}