diff --git a/Cargo.toml b/Cargo.toml index 7233f78..6311b6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_embedded_assets" -version = "0.10.2" +version = "0.11.0" authors = ["François Mockers "] edition = "2021" license = "MIT OR Apache-2.0" @@ -18,13 +18,14 @@ default = ["default-source"] default-source = ["futures-io", "futures-lite"] [dependencies.bevy] -version = "0.13" +version = "0.14.0-rc.2" default-features = false features = ["bevy_asset"] [dependencies] futures-io = { version = "0.3", optional = true } futures-lite = { version = "2.0", optional = true } +thiserror = "1.0" [build-dependencies] cargo-emit = "0.2.1" diff --git a/README.md b/README.md index 37b521f..6b957ec 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ fn main() { |Bevy|bevy_embedded_assets| |---|---| |main|main| +|0.14|0.11| |0.13|0.10| |0.12|0.9| |0.11|0.8| diff --git a/src/asset_reader.rs b/src/asset_reader.rs index 82f7326..3d56c90 100644 --- a/src/asset_reader.rs +++ b/src/asset_reader.rs @@ -6,11 +6,12 @@ use std::{ }; use bevy::{ - asset::io::{AssetReader, AssetReaderError, PathStream, Reader}, + asset::io::{AssetReader, AssetReaderError, ErasedAssetReader, PathStream, Reader}, utils::HashMap, }; -use futures_io::AsyncRead; +use futures_io::{AsyncRead, AsyncSeek}; use futures_lite::Stream; +use thiserror::Error; use crate::{include_all_assets, EmbeddedRegistry}; @@ -36,7 +37,7 @@ use crate::{include_all_assets, EmbeddedRegistry}; #[allow(clippy::module_name_repetitions)] pub struct EmbeddedAssetReader { loaded: HashMap<&'static Path, &'static [u8]>, - fallback: Option>, + fallback: Option>, } impl std::fmt::Debug for EmbeddedAssetReader { @@ -86,7 +87,7 @@ impl EmbeddedAssetReader { /// Create an [`EmbeddedAssetReader`] loaded with all the assets found by the build script. #[must_use] pub(crate) fn preloaded_with_default( - mut default: impl FnMut() -> Box + Send + Sync + 'static, + mut default: impl FnMut() -> Box + Send + Sync + 'static, ) -> Self { let mut new = Self { loaded: HashMap::default(), @@ -157,6 +158,25 @@ impl AsyncRead for DataReader { } } +impl AsyncSeek for DataReader { + fn poll_seek( + self: Pin<&mut Self>, + _: &mut std::task::Context<'_>, + _pos: futures_io::SeekFrom, + ) -> Poll> { + Poll::Ready(Err(futures_io::Error::new( + futures_io::ErrorKind::Other, + EmbeddedDataReaderError::SeekNotSupported, + ))) + } +} + +#[derive(Error, Debug)] +enum EmbeddedDataReaderError { + #[error("Seek is not supported when embeded")] + SeekNotSupported, +} + struct DirReader(Vec); impl Stream for DirReader { @@ -183,60 +203,45 @@ pub(crate) fn get_meta_path(path: &Path) -> PathBuf { } impl AssetReader for EmbeddedAssetReader { - fn read<'a>( - &'a self, - path: &'a Path, - ) -> bevy::utils::BoxedFuture<'a, Result>, AssetReaderError>> { + async fn read<'a>(&'a self, path: &'a Path) -> Result>, AssetReaderError> { if self.has_file_sync(path) { - Box::pin(async move { - self.load_path_sync(path).map(|reader| { - let boxed: Box = Box::new(reader); - boxed - }) + self.load_path_sync(path).map(|reader| { + let boxed: Box = Box::new(reader); + boxed }) } else if let Some(fallback) = self.fallback.as_ref() { - fallback.read(path) + fallback.read(path).await } else { - Box::pin(async move { Err(AssetReaderError::NotFound(path.to_path_buf())) }) + Err(AssetReaderError::NotFound(path.to_path_buf())) } } - fn read_meta<'a>( - &'a self, - path: &'a Path, - ) -> bevy::utils::BoxedFuture<'a, Result>, AssetReaderError>> { + async fn read_meta<'a>(&'a self, path: &'a Path) -> Result>, AssetReaderError> { let meta_path = get_meta_path(path); if self.has_file_sync(&meta_path) { - Box::pin(async move { - self.load_path_sync(&meta_path).map(|reader| { - let boxed: Box = Box::new(reader); - boxed - }) + self.load_path_sync(&meta_path).map(|reader| { + let boxed: Box = Box::new(reader); + boxed }) } else if let Some(fallback) = self.fallback.as_ref() { - fallback.read_meta(path) + fallback.read_meta(path).await } else { - Box::pin(async move { Err(AssetReaderError::NotFound(meta_path)) }) + Err(AssetReaderError::NotFound(meta_path)) } } - fn read_directory<'a>( + async fn read_directory<'a>( &'a self, path: &'a Path, - ) -> bevy::utils::BoxedFuture<'a, Result, AssetReaderError>> { - Box::pin(async move { - self.read_directory_sync(path).map(|read_dir| { - let boxed: Box = Box::new(read_dir); - boxed - }) + ) -> Result, AssetReaderError> { + self.read_directory_sync(path).map(|read_dir| { + let boxed: Box = Box::new(read_dir); + boxed }) } - fn is_directory<'a>( - &'a self, - path: &'a Path, - ) -> bevy::utils::BoxedFuture<'a, Result> { - Box::pin(async move { Ok(self.is_directory_sync(path)) }) + async fn is_directory<'a>(&'a self, path: &'a Path) -> Result { + Ok(self.is_directory_sync(path)) } } diff --git a/src/lib.rs b/src/lib.rs index 652d293..055d4be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,7 +50,7 @@ include!(concat!(env!("OUT_DIR"), "/include_all_assets.rs")); /// # let mut app = App::new(); /// app.add_plugins((EmbeddedAssetPlugin::default(), DefaultPlugins)); /// # app.init_asset::(); -/// # let asset_server: Mut<'_, AssetServer> = app.world.resource_mut::(); +/// # let asset_server: Mut<'_, AssetServer> = app.world_mut().resource_mut::(); /// let handle: Handle = asset_server.load("embedded://example_asset.test"); /// # } /// ``` @@ -69,7 +69,7 @@ include!(concat!(env!("OUT_DIR"), "/include_all_assets.rs")); /// # let mut app = App::new(); /// app.add_plugins((EmbeddedAssetPlugin { mode: PluginMode::ReplaceDefault }, DefaultPlugins)); /// # app.init_asset::(); -/// # let asset_server: Mut<'_, AssetServer> = app.world.resource_mut::(); +/// # let asset_server: Mut<'_, AssetServer> = app.world_mut().resource_mut::(); /// let handle: Handle = asset_server.load("example_asset.test"); /// # } /// ``` @@ -124,7 +124,7 @@ impl Plugin for EmbeddedAssetPlugin { match &self.mode { PluginMode::AutoLoad => { if app.is_plugin_added::() { - let mut registry = app.world.resource_mut::(); + let mut registry = app.world_mut().resource_mut::(); include_all_assets(registry.as_mut()); app.init_resource::(); } @@ -165,9 +165,12 @@ impl Plugin for EmbeddedAssetPlugin { fn finish(&self, app: &mut App) { if matches!(self.mode, PluginMode::AutoLoad) - && app.world.remove_resource::().is_none() + && app + .world_mut() + .remove_resource::() + .is_none() { - let mut registry = app.world.resource_mut::(); + let mut registry = app.world_mut().resource_mut::(); include_all_assets(registry.as_mut()); } } diff --git a/tests/as_default.rs b/tests/as_default.rs index 7afae97..f44a929 100644 --- a/tests/as_default.rs +++ b/tests/as_default.rs @@ -2,8 +2,9 @@ use std::fmt::Display; -use bevy::{prelude::*, utils::thiserror::Error}; +use bevy::prelude::*; use bevy_embedded_assets::{EmbeddedAssetPlugin, PluginMode}; +use thiserror::Error; #[derive(Asset, TypePath, Debug)] pub struct TestAsset { @@ -26,21 +27,19 @@ impl bevy::asset::AssetLoader for TestAssetLoader { type Asset = TestAsset; type Settings = (); type Error = TestError; - fn load<'a>( + async fn load<'a>( &'a self, - reader: &'a mut bevy::asset::io::Reader, + reader: &'a mut bevy::asset::io::Reader<'_>, _: &'a (), - _: &'a mut bevy::asset::LoadContext, - ) -> bevy::utils::BoxedFuture<'a, Result> { - Box::pin(async move { - let mut bytes = Vec::new(); - bevy::asset::AsyncReadExt::read_to_end(reader, &mut bytes) - .await - .unwrap(); + _: &'a mut bevy::asset::LoadContext<'_>, + ) -> Result { + let mut bytes = Vec::new(); + bevy::asset::AsyncReadExt::read_to_end(reader, &mut bytes) + .await + .unwrap(); - Ok(TestAsset { - value: String::from_utf8(bytes).unwrap(), - }) + Ok(TestAsset { + value: String::from_utf8(bytes).unwrap(), }) } @@ -63,17 +62,17 @@ fn work_with_embedded_source_plugin_before() { .init_asset_loader::(); app.finish(); - let asset_server = app.world.resource_mut::(); + let asset_server = app.world_mut().resource_mut::(); let handle_1: Handle = asset_server.load("example_asset.test"); let handle_2: Handle = asset_server.load("açèt.test"); let handle_3: Handle = asset_server.load("subdir/other_asset.test"); app.update(); - let test_assets = app.world.resource_mut::>(); - let asset = test_assets.get(handle_1).unwrap(); + let test_assets = app.world_mut().resource_mut::>(); + let asset = test_assets.get(&handle_1).unwrap(); assert_eq!(asset.value, "hello"); - let asset = test_assets.get(handle_2).unwrap(); + let asset = test_assets.get(&handle_2).unwrap(); assert_eq!(asset.value, "with special chars"); - let asset = test_assets.get(handle_3).unwrap(); + let asset = test_assets.get(&handle_3).unwrap(); assert_eq!(asset.value, "in subdirectory"); } @@ -92,11 +91,11 @@ fn work_with_embedded_source_plugin_after() { .init_asset_loader::(); app.finish(); - let asset_server = app.world.resource_mut::(); + let asset_server = app.world_mut().resource_mut::(); let handle_1: Handle = asset_server.load("example_asset.test"); app.update(); - let test_assets = app.world.resource_mut::>(); - test_assets.get(handle_1).unwrap(); + let test_assets = app.world_mut().resource_mut::>(); + test_assets.get(&handle_1).unwrap(); } // #[test] @@ -108,16 +107,16 @@ fn work_with_embedded_source_plugin_after() { // .init_asset_loader::(); // app.finish(); -// let asset_server = app.world.resource_mut::(); +// let asset_server = app.world_mut().resource_mut::(); // let handle_1: Handle = asset_server.load("example_asset.test"); // let handle_2: Handle = asset_server.load("açèt.test"); // let handle_3: Handle = asset_server.load("subdir/other_asset.test"); // app.update(); -// let test_assets = app.world.resource_mut::>(); -// let asset = test_assets.get(handle_1).unwrap(); +// let test_assets = app.world_mut().resource_mut::>(); +// let asset = test_assets.get(&handle_1).unwrap(); // assert_eq!(asset.value, "hello"); -// let asset = test_assets.get(handle_2).unwrap(); +// let asset = test_assets.get(&handle_2).unwrap(); // assert_eq!(asset.value, "with special chars"); -// let asset = test_assets.get(handle_3).unwrap(); +// let asset = test_assets.get(&handle_3).unwrap(); // assert_eq!(asset.value, "in subdirectory"); // } diff --git a/tests/as_default_with_fallback.rs b/tests/as_default_with_fallback.rs index ba7c5f4..0a94fc8 100644 --- a/tests/as_default_with_fallback.rs +++ b/tests/as_default_with_fallback.rs @@ -2,8 +2,9 @@ use std::fmt::Display; -use bevy::{prelude::*, utils::thiserror::Error}; +use bevy::prelude::*; use bevy_embedded_assets::{EmbeddedAssetPlugin, PluginMode}; +use thiserror::Error; #[derive(Asset, TypePath, Debug)] pub struct TestAsset { @@ -26,21 +27,19 @@ impl bevy::asset::AssetLoader for TestAssetLoader { type Asset = TestAsset; type Settings = (); type Error = TestError; - fn load<'a>( + async fn load<'a>( &'a self, - reader: &'a mut bevy::asset::io::Reader, + reader: &'a mut bevy::asset::io::Reader<'_>, _: &'a (), - _: &'a mut bevy::asset::LoadContext, - ) -> bevy::utils::BoxedFuture<'a, Result> { - Box::pin(async move { - let mut bytes = Vec::new(); - bevy::asset::AsyncReadExt::read_to_end(reader, &mut bytes) - .await - .unwrap(); + _: &'a mut bevy::asset::LoadContext<'_>, + ) -> Result { + let mut bytes = Vec::new(); + bevy::asset::AsyncReadExt::read_to_end(reader, &mut bytes) + .await + .unwrap(); - Ok(TestAsset { - value: String::from_utf8(bytes).unwrap(), - }) + Ok(TestAsset { + value: String::from_utf8(bytes).unwrap(), }) } @@ -65,19 +64,19 @@ fn work_with_embedded_source_plugin_before() { .init_asset_loader::(); app.finish(); - let asset_server = app.world.resource_mut::(); + let asset_server = app.world_mut().resource_mut::(); let handle_1: Handle = asset_server.load("example_asset.test"); let handle_2: Handle = asset_server.load("açèt.test"); let handle_3: Handle = asset_server.load("subdir/other_asset.test"); let handle_4: Handle = asset_server.load("asset.test"); app.update(); - let test_assets = app.world.resource_mut::>(); - let asset = test_assets.get(handle_1).unwrap(); + let test_assets = app.world_mut().resource_mut::>(); + let asset = test_assets.get(&handle_1).unwrap(); assert_eq!(asset.value, "hello"); - let asset = test_assets.get(handle_2).unwrap(); + let asset = test_assets.get(&handle_2).unwrap(); assert_eq!(asset.value, "with special chars"); - let asset = test_assets.get(handle_3).unwrap(); + let asset = test_assets.get(&handle_3).unwrap(); assert_eq!(asset.value, "in subdirectory"); - let asset = test_assets.get(handle_4).unwrap(); + let asset = test_assets.get(&handle_4).unwrap(); assert_eq!(asset.value, "at runtime"); } diff --git a/tests/embedded.rs b/tests/embedded.rs index 90e7e9d..ed5ce2e 100644 --- a/tests/embedded.rs +++ b/tests/embedded.rs @@ -1,7 +1,8 @@ use std::fmt::Display; -use bevy::{prelude::*, utils::thiserror::Error}; +use bevy::prelude::*; use bevy_embedded_assets::EmbeddedAssetPlugin; +use thiserror::Error; #[derive(Asset, TypePath, Debug)] pub struct TestAsset { @@ -24,21 +25,19 @@ impl bevy::asset::AssetLoader for TestAssetLoader { type Asset = TestAsset; type Settings = (); type Error = TestError; - fn load<'a>( + async fn load<'a>( &'a self, - reader: &'a mut bevy::asset::io::Reader, + reader: &'a mut bevy::asset::io::Reader<'_>, _: &'a (), - _: &'a mut bevy::asset::LoadContext, - ) -> bevy::utils::BoxedFuture<'a, Result> { - Box::pin(async move { - let mut bytes = Vec::new(); - bevy::asset::AsyncReadExt::read_to_end(reader, &mut bytes) - .await - .unwrap(); + _: &'a mut bevy::asset::LoadContext<'_>, + ) -> Result { + let mut bytes = Vec::new(); + bevy::asset::AsyncReadExt::read_to_end(reader, &mut bytes) + .await + .unwrap(); - Ok(TestAsset { - value: String::from_utf8(bytes).unwrap(), - }) + Ok(TestAsset { + value: String::from_utf8(bytes).unwrap(), }) } @@ -56,17 +55,17 @@ fn work_with_embedded_source_plugin_before() { .init_asset_loader::(); app.finish(); - let asset_server = app.world.resource_mut::(); + let asset_server = app.world_mut().resource_mut::(); let handle_1: Handle = asset_server.load("embedded://example_asset.test"); let handle_2: Handle = asset_server.load("embedded://açèt.test"); let handle_3: Handle = asset_server.load("embedded://subdir/other_asset.test"); app.update(); - let test_assets = app.world.resource_mut::>(); - let asset = test_assets.get(handle_1).unwrap(); + let test_assets = app.world_mut().resource_mut::>(); + let asset = test_assets.get(&handle_1).unwrap(); assert_eq!(asset.value, "hello"); - let asset = test_assets.get(handle_2).unwrap(); + let asset = test_assets.get(&handle_2).unwrap(); assert_eq!(asset.value, "with special chars"); - let asset = test_assets.get(handle_3).unwrap(); + let asset = test_assets.get(&handle_3).unwrap(); assert_eq!(asset.value, "in subdirectory"); } @@ -79,17 +78,17 @@ fn work_with_embedded_source_plugin_after() { .init_asset_loader::(); app.finish(); - let asset_server = app.world.resource_mut::(); + let asset_server = app.world_mut().resource_mut::(); let handle_1: Handle = asset_server.load("embedded://example_asset.test"); let handle_2: Handle = asset_server.load("embedded://açèt.test"); let handle_3: Handle = asset_server.load("embedded://subdir/other_asset.test"); app.update(); - let test_assets = app.world.resource_mut::>(); - let asset = test_assets.get(handle_1).unwrap(); + let test_assets = app.world_mut().resource_mut::>(); + let asset = test_assets.get(&handle_1).unwrap(); assert_eq!(asset.value, "hello"); - let asset = test_assets.get(handle_2).unwrap(); + let asset = test_assets.get(&handle_2).unwrap(); assert_eq!(asset.value, "with special chars"); - let asset = test_assets.get(handle_3).unwrap(); + let asset = test_assets.get(&handle_3).unwrap(); assert_eq!(asset.value, "in subdirectory"); } @@ -102,16 +101,16 @@ fn doesnt_work_with_plugin() { .init_asset_loader::(); app.finish(); - let asset_server = app.world.resource_mut::(); + let asset_server = app.world_mut().resource_mut::(); let handle_1: Handle = asset_server.load("embedded://example_asset.test"); let handle_2: Handle = asset_server.load("embedded://açèt.test"); let handle_3: Handle = asset_server.load("embedded://subdir/other_asset.test"); app.update(); - let test_assets = app.world.resource_mut::>(); - let asset = test_assets.get(handle_1).unwrap(); + let test_assets = app.world_mut().resource_mut::>(); + let asset = test_assets.get(&handle_1).unwrap(); assert_eq!(asset.value, "hello"); - let asset = test_assets.get(handle_2).unwrap(); + let asset = test_assets.get(&handle_2).unwrap(); assert_eq!(asset.value, "with special chars"); - let asset = test_assets.get(handle_3).unwrap(); + let asset = test_assets.get(&handle_3).unwrap(); assert_eq!(asset.value, "in subdirectory"); }