Add AppBuilder::asset_loader_from_instance (#580)

* Implement add_asset_loader_from_instance

* Add example of different data loaders
This commit is contained in:
Will Hart 2020-10-02 04:31:06 +10:00 committed by GitHub
parent 056f84a2c1
commit 1beee4fd28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 2 deletions

View file

@ -90,6 +90,7 @@ bevy_gilrs = { path = "crates/bevy_gilrs", optional = true, version = "0.2.1" }
rand = "0.7.3" rand = "0.7.3"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
log = "0.4" log = "0.4"
ron = "0.6"
#wasm #wasm
console_error_panic_hook = "0.1.6" console_error_panic_hook = "0.1.6"
@ -172,6 +173,10 @@ path = "examples/asset/hot_asset_reloading.rs"
name = "asset_loading" name = "asset_loading"
path = "examples/asset/asset_loading.rs" path = "examples/asset/asset_loading.rs"
[[example]]
name = "custom_loader"
path = "examples/asset/custom_asset_loading.rs"
[[example]] [[example]]
name = "audio" name = "audio"
path = "examples/audio/audio.rs" path = "examples/audio/audio.rs"

View file

@ -0,0 +1,3 @@
MyCustomData (
num: 42
)

View file

@ -0,0 +1,3 @@
MySecondCustomData (
is_set: true
)

View file

@ -119,6 +119,10 @@ pub trait AddAsset {
where where
TLoader: AssetLoader<TAsset> + FromResources, TLoader: AssetLoader<TAsset> + FromResources,
TAsset: Send + Sync + 'static; TAsset: Send + Sync + 'static;
fn add_asset_loader_from_instance<TAsset, TLoader>(&mut self, instance: TLoader) -> &mut Self
where
TLoader: AssetLoader<TAsset> + FromResources,
TAsset: Send + Sync + 'static;
} }
impl AddAsset for AppBuilder { impl AddAsset for AppBuilder {
@ -135,7 +139,7 @@ impl AddAsset for AppBuilder {
.add_event::<AssetEvent<T>>() .add_event::<AssetEvent<T>>()
} }
fn add_asset_loader<TAsset, TLoader>(&mut self) -> &mut Self fn add_asset_loader_from_instance<TAsset, TLoader>(&mut self, instance: TLoader) -> &mut Self
where where
TLoader: AssetLoader<TAsset> + FromResources, TLoader: AssetLoader<TAsset> + FromResources,
TAsset: Send + Sync + 'static, TAsset: Send + Sync + 'static,
@ -156,7 +160,7 @@ impl AddAsset for AppBuilder {
.resources() .resources()
.get_mut::<AssetServer>() .get_mut::<AssetServer>()
.expect("AssetServer does not exist. Consider adding it as a resource."); .expect("AssetServer does not exist. Consider adding it as a resource.");
asset_server.add_loader(TLoader::from_resources(self.resources())); asset_server.add_loader(instance);
let handler = ChannelAssetHandler::new( let handler = ChannelAssetHandler::new(
TLoader::from_resources(self.resources()), TLoader::from_resources(self.resources()),
asset_channel.sender.clone(), asset_channel.sender.clone(),
@ -165,4 +169,14 @@ impl AddAsset for AppBuilder {
} }
self self
} }
fn add_asset_loader<TAsset, TLoader>(&mut self) -> &mut Self
where
TLoader: AssetLoader<TAsset> + FromResources,
TAsset: Send + Sync + 'static,
{
self.add_asset_loader_from_instance::<TAsset, TLoader>(TLoader::from_resources(
self.resources(),
))
}
} }

View file

@ -0,0 +1,76 @@
use bevy::{asset::AssetLoader, prelude::*};
use ron::de::from_bytes;
use serde::Deserialize;
use std::path::Path;
#[derive(Deserialize)]
pub struct MyCustomData {
pub num: i32,
}
#[derive(Deserialize)]
pub struct MySecondCustomData {
pub is_set: bool,
}
// create a custom loader for data files
#[derive(Default)]
pub struct DataFileLoader {
matching_extensions: Vec<&'static str>,
}
impl DataFileLoader {
pub fn from_extensions(matching_extensions: Vec<&'static str>) -> Self {
DataFileLoader {
matching_extensions,
}
}
}
impl<TAsset> AssetLoader<TAsset> for DataFileLoader
where
for<'de> TAsset: Deserialize<'de>,
{
fn from_bytes(&self, _asset_path: &Path, bytes: Vec<u8>) -> Result<TAsset, anyhow::Error> {
Ok(from_bytes::<TAsset>(bytes.as_slice())?)
}
fn extensions(&self) -> &[&str] {
self.matching_extensions.as_slice()
}
}
/// This example illustrates various ways to load assets
fn main() {
App::build()
.add_default_plugins()
.add_asset::<MyCustomData>()
.add_asset_loader_from_instance::<MyCustomData, DataFileLoader>(
DataFileLoader::from_extensions(vec!["data1"]),
)
.add_asset::<MySecondCustomData>()
.add_asset_loader_from_instance::<MySecondCustomData, DataFileLoader>(
DataFileLoader::from_extensions(vec!["data2"]),
)
.add_startup_system(setup.system())
.run();
}
fn setup(
asset_server: Res<AssetServer>,
mut data1s: ResMut<Assets<MyCustomData>>,
mut data2s: ResMut<Assets<MySecondCustomData>>,
) {
let data1_handle = asset_server
.load_sync(&mut data1s, "assets/data/test_data.data1")
.unwrap();
let data2_handle = asset_server
.load_sync(&mut data2s, "assets/data/test_data.data2")
.unwrap();
let data1 = data1s.get(&data1_handle).unwrap();
println!("Data 1 loaded with value {}", data1.num);
let data2 = data2s.get(&data2_handle).unwrap();
println!("Data 2 loaded with value {}", data2.is_set);
}