From f73f88f4391fa42f800699785de4284f5442411f Mon Sep 17 00:00:00 2001 From: lielfr Date: Mon, 9 Jun 2025 00:30:40 +0300 Subject: [PATCH] get rid of more path function usages from AssetPath --- .../bevy_asset/src/io/file/sync_file_asset.rs | 14 +++++++--- crates/bevy_asset/src/io/processor_gated.rs | 6 ++-- crates/bevy_asset/src/loader.rs | 6 ++-- crates/bevy_asset/src/path.rs | 13 ++++++++- .../bevy_gltf/src/loader/gltf_ext/texture.rs | 2 +- crates/bevy_gltf/src/loader/mod.rs | 28 +++++++------------ crates/bevy_image/src/image_loader.rs | 12 ++++---- .../bevy_render/src/render_resource/shader.rs | 6 ++-- 8 files changed, 49 insertions(+), 38 deletions(-) diff --git a/crates/bevy_asset/src/io/file/sync_file_asset.rs b/crates/bevy_asset/src/io/file/sync_file_asset.rs index 9281d323c8..c5dd22ace7 100644 --- a/crates/bevy_asset/src/io/file/sync_file_asset.rs +++ b/crates/bevy_asset/src/io/file/sync_file_asset.rs @@ -105,7 +105,9 @@ impl AssetReader for FileAssetReader { Ok(file) => Ok(FileReader(file)), Err(e) => { if e.kind() == std::io::ErrorKind::NotFound { - Err(AssetReaderError::NotFound(full_path)) + Err(AssetReaderError::NotFound( + full_path.to_str().unwrap().to_owned(), + )) } else { Err(e.into()) } @@ -120,7 +122,9 @@ impl AssetReader for FileAssetReader { Ok(file) => Ok(FileReader(file)), Err(e) => { if e.kind() == std::io::ErrorKind::NotFound { - Err(AssetReaderError::NotFound(full_path)) + Err(AssetReaderError::NotFound( + full_path.to_str().unwrap().to_owned(), + )) } else { Err(e.into()) } @@ -164,7 +168,9 @@ impl AssetReader for FileAssetReader { } Err(e) => { if e.kind() == std::io::ErrorKind::NotFound { - Err(AssetReaderError::NotFound(full_path)) + Err(AssetReaderError::NotFound( + full_path.to_str().unwrap().to_owned(), + )) } else { Err(e.into()) } @@ -176,7 +182,7 @@ impl AssetReader for FileAssetReader { let full_path = self.root_path.join(path); let metadata = full_path .metadata() - .map_err(|_e| AssetReaderError::NotFound(path.to_owned()))?; + .map_err(|_e| AssetReaderError::NotFound(path.to_str().unwrap().to_owned()))?; Ok(metadata.file_type().is_dir()) } } diff --git a/crates/bevy_asset/src/io/processor_gated.rs b/crates/bevy_asset/src/io/processor_gated.rs index d9820f1178..a40d3f2760 100644 --- a/crates/bevy_asset/src/io/processor_gated.rs +++ b/crates/bevy_asset/src/io/processor_gated.rs @@ -43,9 +43,9 @@ impl ProcessorGatedReader { path: &AssetPath<'static>, ) -> Result, AssetReaderError> { let infos = self.processor_data.asset_infos.read().await; - let info = infos.get(path).ok_or_else(|| { - AssetReaderError::NotFound(PathBuf::from(path.path()).to_str().unwrap().to_owned()) - })?; + let info = infos + .get(path) + .ok_or_else(|| AssetReaderError::NotFound(path.internal_path().to_owned()))?; Ok(info.file_transaction_lock.read_arc().await) } } diff --git a/crates/bevy_asset/src/loader.rs b/crates/bevy_asset/src/loader.rs index 50bbfb5dfc..90c1a76f52 100644 --- a/crates/bevy_asset/src/loader.rs +++ b/crates/bevy_asset/src/loader.rs @@ -357,7 +357,7 @@ impl<'a> LoadContext<'a> { /// # use bevy_reflect::TypePath; /// # #[derive(Asset, TypePath, Default)] /// # struct Image; - /// # let load_context: LoadContext = panic!(); + /// # let mut load_context: LoadContext = panic!(); /// let mut handles = Vec::new(); /// for i in 0..2 { /// let mut labeled = load_context.begin_labeled_asset(); @@ -459,8 +459,8 @@ impl<'a> LoadContext<'a> { } /// Gets the source path for this load context. - pub fn path(&self) -> &Path { - self.asset_path.path() + pub fn path(&self) -> &str { + self.asset_path.internal_path() } /// Gets the source asset path for this load context. diff --git a/crates/bevy_asset/src/path.rs b/crates/bevy_asset/src/path.rs index 640aad2ab7..62d88ed4f5 100644 --- a/crates/bevy_asset/src/path.rs +++ b/crates/bevy_asset/src/path.rs @@ -304,6 +304,10 @@ impl<'a> AssetPath<'a> { Path::new(self.path.as_ref()) } + pub fn internal_path(&self) -> &str { + self.path.as_ref() + } + /// Gets the path to the asset in the "virtual filesystem" without a label (if a label is currently set). #[inline] pub fn without_label(&self) -> AssetPath<'_> { @@ -510,7 +514,14 @@ impl<'a> AssetPath<'a> { /// Returns the file name /// Ex: Returns `"a.json"` for `"a/b/c/a.json"` pub fn file_name(&self) -> Option { - self.path().file_name()?.to_str().map(String::from) + self.path.split("/").last().map(ToString::to_string) + } + + /// Returns a new AssetPath with the additional extension, joined by a `/`. + pub fn join(&self, suffix: &str) -> AssetPath<'a> { + let mut new_path = self.clone(); + new_path.path = CowArc::from(alloc::format!("{new_path}/{suffix}")); + new_path } /// Returns the full extension (including multiple '.' values). diff --git a/crates/bevy_gltf/src/loader/gltf_ext/texture.rs b/crates/bevy_gltf/src/loader/gltf_ext/texture.rs index 0ea16936a6..2a21426ddc 100644 --- a/crates/bevy_gltf/src/loader/gltf_ext/texture.rs +++ b/crates/bevy_gltf/src/loader/gltf_ext/texture.rs @@ -30,7 +30,7 @@ pub(crate) fn texture_handle( if let Ok(_data_uri) = DataUri::parse(uri) { load_context.get_label_handle(texture_label(texture).to_string()) } else { - let parent = load_context.path().parent().unwrap(); + let parent = load_context.asset_path().parent().unwrap(); let image_path = parent.join(uri); load_context.load(image_path) } diff --git a/crates/bevy_gltf/src/loader/mod.rs b/crates/bevy_gltf/src/loader/mod.rs index abc555002a..e32a65e2f3 100644 --- a/crates/bevy_gltf/src/loader/mod.rs +++ b/crates/bevy_gltf/src/loader/mod.rs @@ -11,7 +11,7 @@ use std::{ #[cfg(feature = "bevy_animation")] use bevy_animation::{prelude::*, AnimationTarget, AnimationTargetId}; use bevy_asset::{ - io::Reader, AssetLoadError, AssetLoader, Handle, LoadContext, ReadAssetBytesError, + io::Reader, AssetLoadError, AssetLoader, AssetPath, Handle, LoadContext, ReadAssetBytesError, RenderAssetUsages, }; use bevy_color::{Color, LinearRgba}; @@ -237,15 +237,7 @@ async fn load_gltf<'a, 'b, 'c>( ) -> Result { let gltf = gltf::Gltf::from_slice(bytes)?; - let file_name = load_context - .asset_path() - .path() - .to_str() - .ok_or(GltfError::Gltf(gltf::Error::Io(Error::new( - std::io::ErrorKind::InvalidInput, - "Gltf file name invalid", - ))))? - .to_string(); + let file_name = load_context.asset_path().internal_path().to_string(); let buffer_data = load_buffers(&gltf, load_context).await?; let linear_textures = get_linear_textures(&gltf.document); @@ -531,12 +523,12 @@ async fn load_gltf<'a, 'b, 'c>( let mut _texture_handles = Vec::new(); if gltf.textures().len() == 1 || cfg!(target_arch = "wasm32") { for texture in gltf.textures() { - let parent_path = load_context.path().parent().unwrap(); + let parent_path = load_context.asset_path().parent().unwrap(); let image = load_image( texture, &buffer_data, &linear_textures, - parent_path, + &parent_path, loader.supported_compressed_formats, default_sampler, settings, @@ -549,7 +541,7 @@ async fn load_gltf<'a, 'b, 'c>( IoTaskPool::get() .scope(|scope| { gltf.textures().for_each(|gltf_texture| { - let parent_path = load_context.path().parent().unwrap(); + let parent_path = load_context.asset_path().parent().unwrap(); let linear_textures = &linear_textures; let buffer_data = &buffer_data; scope.spawn(async move { @@ -557,7 +549,7 @@ async fn load_gltf<'a, 'b, 'c>( gltf_texture, buffer_data, linear_textures, - parent_path, + &parent_path, loader.supported_compressed_formats, default_sampler, settings, @@ -970,11 +962,11 @@ async fn load_gltf<'a, 'b, 'c>( } /// Loads a glTF texture as a bevy [`Image`] and returns it together with its label. -async fn load_image<'a, 'b>( +async fn load_image<'a, 'b, 'c>( gltf_texture: gltf::Texture<'a>, buffer_data: &[Vec], linear_textures: &HashSet, - parent_path: &'b Path, + parent_path: &'b AssetPath<'c>, supported_compressed_formats: CompressedImageFormats, default_sampler: &ImageSamplerDescriptor, settings: &GltfLoaderSettings, @@ -1026,7 +1018,7 @@ async fn load_image<'a, 'b>( } else { let image_path = parent_path.join(uri); Ok(ImageOrPath::Path { - path: image_path, + path: PathBuf::from(image_path), is_srgb, sampler_descriptor, }) @@ -1624,7 +1616,7 @@ async fn load_buffers( Ok(_) => return Err(GltfError::BufferFormatUnsupported), Err(()) => { // TODO: Remove this and add dep - let buffer_path = load_context.path().parent().unwrap().join(uri); + let buffer_path = load_context.asset_path().parent().unwrap().join(uri); load_context.read_asset_bytes(buffer_path).await? } }; diff --git a/crates/bevy_image/src/image_loader.rs b/crates/bevy_image/src/image_loader.rs index fe086db674..b175eb0c67 100644 --- a/crates/bevy_image/src/image_loader.rs +++ b/crates/bevy_image/src/image_loader.rs @@ -3,6 +3,7 @@ use bevy_asset::{io::Reader, AssetLoader, LoadContext, RenderAssetUsages}; use thiserror::Error; use super::{CompressedImageFormats, ImageSampler}; +use bevy_ecs::intern::Internable; use serde::{Deserialize, Serialize}; /// Loader for images that can be read by the `image` crate. @@ -151,19 +152,20 @@ impl AssetLoader for ImageLoader { let image_type = match settings.format { ImageFormatSetting::FromExtension => { // use the file extension for the image type - let ext = load_context.path().extension().unwrap().to_str().unwrap(); - ImageType::Extension(ext) + let ext = Box::new(load_context.asset_path().get_full_extension().unwrap()); + // TODO: this is a workaround. There is a better solution for this. + ImageType::Extension(ext.leak()) } ImageFormatSetting::Format(format) => ImageType::Format(format), ImageFormatSetting::Guess => { let format = image::guess_format(&bytes).map_err(|err| FileTextureError { error: err.into(), - path: format!("{}", load_context.path().display()), + path: format!("{}", load_context.path()), })?; ImageType::Format(ImageFormat::from_image_crate_format(format).ok_or_else( || FileTextureError { error: TextureError::UnsupportedTextureFormat(format!("{format:?}")), - path: format!("{}", load_context.path().display()), + path: format!("{}", load_context.path()), }, )?) } @@ -178,7 +180,7 @@ impl AssetLoader for ImageLoader { ) .map_err(|err| FileTextureError { error: err, - path: format!("{}", load_context.path().display()), + path: format!("{}", load_context.path()), })?) } diff --git a/crates/bevy_render/src/render_resource/shader.rs b/crates/bevy_render/src/render_resource/shader.rs index ff8430b951..b0ec5cb8e3 100644 --- a/crates/bevy_render/src/render_resource/shader.rs +++ b/crates/bevy_render/src/render_resource/shader.rs @@ -341,7 +341,7 @@ impl AssetLoader for ShaderLoader { settings: &Self::Settings, load_context: &mut LoadContext<'_>, ) -> Result { - let ext = load_context.path().extension().unwrap().to_str().unwrap(); + let ext = load_context.asset_path().get_full_extension().unwrap(); let path = load_context.asset_path().to_string(); // On windows, the path will inconsistently use \ or /. // TODO: remove this once AssetPath forces cross-platform "slash" consistency. See #10511 @@ -354,8 +354,8 @@ impl AssetLoader for ShaderLoader { The shader defs will be ignored." ); } - let mut shader = match ext { - "spv" => Shader::from_spirv(bytes, load_context.path().to_string_lossy()), + let mut shader = match ext.as_str() { + "spv" => Shader::from_spirv(bytes, load_context.path()), "wgsl" => Shader::from_wgsl_with_defs( String::from_utf8(bytes)?, path,