From 1beee4fd28b934edea8622b985ea038ea6c7ee41 Mon Sep 17 00:00:00 2001 From: Will Hart Date: Fri, 2 Oct 2020 04:31:06 +1000 Subject: [PATCH] Add AppBuilder::asset_loader_from_instance (#580) * Implement add_asset_loader_from_instance * Add example of different data loaders --- Cargo.toml | 5 ++ assets/data/test_data.data1 | 3 + assets/data/test_data.data2 | 3 + crates/bevy_asset/src/assets.rs | 18 +++++- examples/asset/custom_asset_loading.rs | 76 ++++++++++++++++++++++++++ 5 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 assets/data/test_data.data1 create mode 100644 assets/data/test_data.data2 create mode 100644 examples/asset/custom_asset_loading.rs diff --git a/Cargo.toml b/Cargo.toml index 89acfcf086..f7242c21e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,6 +90,7 @@ bevy_gilrs = { path = "crates/bevy_gilrs", optional = true, version = "0.2.1" } rand = "0.7.3" serde = { version = "1", features = ["derive"] } log = "0.4" +ron = "0.6" #wasm console_error_panic_hook = "0.1.6" @@ -172,6 +173,10 @@ path = "examples/asset/hot_asset_reloading.rs" name = "asset_loading" path = "examples/asset/asset_loading.rs" +[[example]] +name = "custom_loader" +path = "examples/asset/custom_asset_loading.rs" + [[example]] name = "audio" path = "examples/audio/audio.rs" diff --git a/assets/data/test_data.data1 b/assets/data/test_data.data1 new file mode 100644 index 0000000000..e2d4dc7121 --- /dev/null +++ b/assets/data/test_data.data1 @@ -0,0 +1,3 @@ + MyCustomData ( + num: 42 +) \ No newline at end of file diff --git a/assets/data/test_data.data2 b/assets/data/test_data.data2 new file mode 100644 index 0000000000..885d7fa253 --- /dev/null +++ b/assets/data/test_data.data2 @@ -0,0 +1,3 @@ + MySecondCustomData ( + is_set: true +) \ No newline at end of file diff --git a/crates/bevy_asset/src/assets.rs b/crates/bevy_asset/src/assets.rs index 68393f6fc1..cd7ad98f07 100644 --- a/crates/bevy_asset/src/assets.rs +++ b/crates/bevy_asset/src/assets.rs @@ -119,6 +119,10 @@ pub trait AddAsset { where TLoader: AssetLoader + FromResources, TAsset: Send + Sync + 'static; + fn add_asset_loader_from_instance(&mut self, instance: TLoader) -> &mut Self + where + TLoader: AssetLoader + FromResources, + TAsset: Send + Sync + 'static; } impl AddAsset for AppBuilder { @@ -135,7 +139,7 @@ impl AddAsset for AppBuilder { .add_event::>() } - fn add_asset_loader(&mut self) -> &mut Self + fn add_asset_loader_from_instance(&mut self, instance: TLoader) -> &mut Self where TLoader: AssetLoader + FromResources, TAsset: Send + Sync + 'static, @@ -156,7 +160,7 @@ impl AddAsset for AppBuilder { .resources() .get_mut::() .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( TLoader::from_resources(self.resources()), asset_channel.sender.clone(), @@ -165,4 +169,14 @@ impl AddAsset for AppBuilder { } self } + + fn add_asset_loader(&mut self) -> &mut Self + where + TLoader: AssetLoader + FromResources, + TAsset: Send + Sync + 'static, + { + self.add_asset_loader_from_instance::(TLoader::from_resources( + self.resources(), + )) + } } diff --git a/examples/asset/custom_asset_loading.rs b/examples/asset/custom_asset_loading.rs new file mode 100644 index 0000000000..276d2062fb --- /dev/null +++ b/examples/asset/custom_asset_loading.rs @@ -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 AssetLoader for DataFileLoader +where + for<'de> TAsset: Deserialize<'de>, +{ + fn from_bytes(&self, _asset_path: &Path, bytes: Vec) -> Result { + Ok(from_bytes::(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::() + .add_asset_loader_from_instance::( + DataFileLoader::from_extensions(vec!["data1"]), + ) + .add_asset::() + .add_asset_loader_from_instance::( + DataFileLoader::from_extensions(vec!["data2"]), + ) + .add_startup_system(setup.system()) + .run(); +} + +fn setup( + asset_server: Res, + mut data1s: ResMut>, + mut data2s: ResMut>, +) { + 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); +}