diff --git a/crates/bevy_asset/Cargo.toml b/crates/bevy_asset/Cargo.toml index 7ee8cbf2ef..7022eb4d5a 100644 --- a/crates/bevy_asset/Cargo.toml +++ b/crates/bevy_asset/Cargo.toml @@ -22,6 +22,7 @@ trace = [] bevy_app = { path = "../bevy_app", version = "0.16.0-dev" } bevy_asset_macros = { path = "macros", version = "0.16.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" } +bevy_log = { path = "../bevy_log", version = "0.16.0-dev" } bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [ "uuid", ] } @@ -69,9 +70,6 @@ uuid = { version = "1.13.1", default-features = false, features = ["js"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] notify-debouncer-full = { version = "0.5.0", optional = true } -[dev-dependencies] -bevy_log = { path = "../bevy_log", version = "0.16.0-dev" } - [lints] workspace = true diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index 2328691904..f0b8e92a93 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -725,7 +725,7 @@ mod tests { .map_err(|_| Self::Error::CannotLoadDependency { dependency: dep.into(), })?; - let cool = loaded.get(); + let cool = loaded.get_asset().get(); embedded.push_str(&cool.text); } Ok(CoolText { diff --git a/crates/bevy_asset/src/loader.rs b/crates/bevy_asset/src/loader.rs index 75192159a8..3be672e0c1 100644 --- a/crates/bevy_asset/src/loader.rs +++ b/crates/bevy_asset/src/loader.rs @@ -13,6 +13,7 @@ use alloc::{ }; use atomicow::CowArc; use bevy_ecs::world::World; +use bevy_log::warn; use bevy_platform_support::collections::{HashMap, HashSet}; use bevy_tasks::{BoxedFuture, ConditionalSendFuture}; use core::any::{Any, TypeId}; @@ -60,7 +61,7 @@ pub trait ErasedAssetLoader: Send + Sync + 'static { load_context: LoadContext<'a>, ) -> BoxedFuture< 'a, - Result>, + Result>, >; /// Returns a list of extensions supported by this asset loader, without the preceding dot. @@ -91,7 +92,7 @@ where mut load_context: LoadContext<'a>, ) -> BoxedFuture< 'a, - Result>, + Result>, > { Box::pin(async move { let settings = meta @@ -152,7 +153,6 @@ pub struct LoadedAsset { pub(crate) value: A, pub(crate) dependencies: HashSet, pub(crate) loader_dependencies: HashMap, AssetHash>, - pub(crate) labeled_assets: HashMap, LabeledAsset>, } impl LoadedAsset { @@ -166,7 +166,6 @@ impl LoadedAsset { value, dependencies, loader_dependencies: HashMap::default(), - labeled_assets: HashMap::default(), } } @@ -179,19 +178,6 @@ impl LoadedAsset { pub fn get(&self) -> &A { &self.value } - - /// Returns the [`ErasedLoadedAsset`] for the given label, if it exists. - pub fn get_labeled( - &self, - label: impl Into>, - ) -> Option<&ErasedLoadedAsset> { - self.labeled_assets.get(&label.into()).map(|a| &a.asset) - } - - /// Iterate over all labels for "labeled assets" in the loaded asset - pub fn iter_labels(&self) -> impl Iterator { - self.labeled_assets.keys().map(|s| &**s) - } } impl From for LoadedAsset { @@ -205,7 +191,6 @@ pub struct ErasedLoadedAsset { pub(crate) value: Box, pub(crate) dependencies: HashSet, pub(crate) loader_dependencies: HashMap, AssetHash>, - pub(crate) labeled_assets: HashMap, LabeledAsset>, } impl From> for ErasedLoadedAsset { @@ -214,7 +199,6 @@ impl From> for ErasedLoadedAsset { value: Box::new(asset.value), dependencies: asset.dependencies, loader_dependencies: asset.loader_dependencies, - labeled_assets: asset.labeled_assets, } } } @@ -241,19 +225,6 @@ impl ErasedLoadedAsset { self.value.asset_type_name() } - /// Returns the [`ErasedLoadedAsset`] for the given label, if it exists. - pub fn get_labeled( - &self, - label: impl Into>, - ) -> Option<&ErasedLoadedAsset> { - self.labeled_assets.get(&label.into()).map(|a| &a.asset) - } - - /// Iterate over all labels for "labeled assets" in the loaded asset - pub fn iter_labels(&self) -> impl Iterator { - self.labeled_assets.keys().map(|s| &**s) - } - /// Cast this loaded asset as the given type. If the type does not match, /// the original type-erased asset is returned. pub fn downcast(mut self) -> Result, ErasedLoadedAsset> { @@ -262,7 +233,6 @@ impl ErasedLoadedAsset { value: *value, dependencies: self.dependencies, loader_dependencies: self.loader_dependencies, - labeled_assets: self.labeled_assets, }), Err(value) => { self.value = value; @@ -290,6 +260,100 @@ impl AssetContainer for A { } } +/// A loaded asset and all its loaded subassets. +pub struct CompleteLoadedAsset { + /// The loaded asset. + pub(crate) asset: LoadedAsset, + /// The subassets by their label. + pub(crate) labeled_assets: HashMap, LabeledAsset>, +} + +impl CompleteLoadedAsset { + /// Take ownership of the stored [`Asset`] value. + pub fn take(self) -> A { + self.asset.value + } + + /// Returns the stored asset. + pub fn get_asset(&self) -> &LoadedAsset { + &self.asset + } + + /// Returns the [`ErasedLoadedAsset`] for the given label, if it exists. + pub fn get_labeled( + &self, + label: impl Into>, + ) -> Option<&ErasedLoadedAsset> { + self.labeled_assets.get(&label.into()).map(|a| &a.asset) + } + + /// Iterate over all labels for "labeled assets" in the loaded asset + pub fn iter_labels(&self) -> impl Iterator { + self.labeled_assets.keys().map(|s| &**s) + } +} + +/// A "type erased / boxed" counterpart to [`CompleteLoadedAsset`]. This is used in places where the +/// loaded type is not statically known. +pub struct CompleteErasedLoadedAsset { + /// The loaded asset. + pub(crate) asset: ErasedLoadedAsset, + /// The subassets by their label. + pub(crate) labeled_assets: HashMap, LabeledAsset>, +} + +impl CompleteErasedLoadedAsset { + /// Cast (and take ownership) of the [`Asset`] value of the given type. This will return + /// [`Some`] if the stored type matches `A` and [`None`] if it does not. + pub fn take(self) -> Option { + self.asset.take() + } + + /// Returns the stored asset. + pub fn get_asset(&self) -> &ErasedLoadedAsset { + &self.asset + } + + /// Returns the [`ErasedLoadedAsset`] for the given label, if it exists. + pub fn get_labeled( + &self, + label: impl Into>, + ) -> Option<&ErasedLoadedAsset> { + self.labeled_assets.get(&label.into()).map(|a| &a.asset) + } + + /// Iterate over all labels for "labeled assets" in the loaded asset + pub fn iter_labels(&self) -> impl Iterator { + self.labeled_assets.keys().map(|s| &**s) + } + + /// Cast this loaded asset as the given type. If the type does not match, + /// the original type-erased asset is returned. + pub fn downcast( + mut self, + ) -> Result, CompleteErasedLoadedAsset> { + match self.asset.downcast::() { + Ok(asset) => Ok(CompleteLoadedAsset { + asset, + labeled_assets: self.labeled_assets, + }), + Err(asset) => { + self.asset = asset; + Err(self) + } + } + } +} + +impl From> for CompleteErasedLoadedAsset { + fn from(value: CompleteLoadedAsset) -> Self { + Self { + asset: value.asset.into(), + labeled_assets: value.labeled_assets, + } + } +} + /// An error that occurs when attempting to call [`NestedLoader::load`] which /// is configured to work [immediately]. /// @@ -397,8 +461,8 @@ impl<'a> LoadContext<'a> { ) -> Handle { let mut context = self.begin_labeled_asset(); let asset = load(&mut context); - let loaded_asset = context.finish(asset); - self.add_loaded_labeled_asset(label, loaded_asset) + let complete_asset = context.finish(asset); + self.add_loaded_labeled_asset(label, complete_asset) } /// This will add the given `asset` as a "labeled [`Asset`]" with the `label` label. @@ -423,10 +487,14 @@ impl<'a> LoadContext<'a> { pub fn add_loaded_labeled_asset( &mut self, label: impl Into>, - loaded_asset: LoadedAsset, + loaded_asset: CompleteLoadedAsset, ) -> Handle { let label = label.into(); - let loaded_asset: ErasedLoadedAsset = loaded_asset.into(); + let CompleteLoadedAsset { + asset, + labeled_assets, + } = loaded_asset; + let loaded_asset: ErasedLoadedAsset = asset.into(); let labeled_path = self.asset_path.clone().with_label(label.clone()); let handle = self .asset_server @@ -438,6 +506,11 @@ impl<'a> LoadContext<'a> { handle: handle.clone().untyped(), }, ); + for (label, asset) in labeled_assets { + if self.labeled_assets.insert(label.clone(), asset).is_some() { + warn!("A labeled asset with the label \"{label}\" already exists. Replacing with the new asset."); + } + } handle } @@ -450,11 +523,13 @@ impl<'a> LoadContext<'a> { } /// "Finishes" this context by populating the final [`Asset`] value. - pub fn finish(self, value: A) -> LoadedAsset { - LoadedAsset { - value, - dependencies: self.dependencies, - loader_dependencies: self.loader_dependencies, + pub fn finish(self, value: A) -> CompleteLoadedAsset { + CompleteLoadedAsset { + asset: LoadedAsset { + value, + dependencies: self.dependencies, + loader_dependencies: self.loader_dependencies, + }, labeled_assets: self.labeled_assets, } } @@ -525,8 +600,8 @@ impl<'a> LoadContext<'a> { meta: &dyn AssetMetaDyn, loader: &dyn ErasedAssetLoader, reader: &mut dyn Reader, - ) -> Result { - let loaded_asset = self + ) -> Result { + let complete_asset = self .asset_server .load_with_meta_loader_and_reader( &path, @@ -544,7 +619,7 @@ impl<'a> LoadContext<'a> { let info = meta.processed_info().as_ref(); let hash = info.map(|i| i.full_hash).unwrap_or_default(); self.loader_dependencies.insert(path, hash); - Ok(loaded_asset) + Ok(complete_asset) } /// Create a builder for loading nested assets in this context. diff --git a/crates/bevy_asset/src/loader_builders.rs b/crates/bevy_asset/src/loader_builders.rs index 3d75027f5d..630ab1f92c 100644 --- a/crates/bevy_asset/src/loader_builders.rs +++ b/crates/bevy_asset/src/loader_builders.rs @@ -4,8 +4,8 @@ use crate::{ io::Reader, meta::{meta_transform_settings, AssetMetaDyn, MetaTransform, Settings}, - Asset, AssetLoadError, AssetPath, ErasedAssetLoader, ErasedLoadedAsset, Handle, LoadContext, - LoadDirectError, LoadedAsset, LoadedUntypedAsset, UntypedHandle, + Asset, AssetLoadError, AssetPath, CompleteErasedLoadedAsset, CompleteLoadedAsset, + ErasedAssetLoader, Handle, LoadContext, LoadDirectError, LoadedUntypedAsset, UntypedHandle, }; use alloc::{borrow::ToOwned, boxed::Box, sync::Arc}; use core::any::TypeId; @@ -57,11 +57,11 @@ impl ReaderRef<'_> { /// If you know the type ID of the asset at runtime, but not at compile time, /// use [`with_dynamic_type`] followed by [`load`] to start loading an asset /// of that type. This lets you get an [`UntypedHandle`] (via [`Deferred`]), -/// or a [`ErasedLoadedAsset`] (via [`Immediate`]). +/// or a [`CompleteErasedLoadedAsset`] (via [`Immediate`]). /// /// - in [`UnknownTyped`]: loading either a type-erased version of the asset -/// ([`ErasedLoadedAsset`]), or a handle *to a handle* of the actual asset -/// ([`LoadedUntypedAsset`]). +/// ([`CompleteErasedLoadedAsset`]), or a handle *to a handle* of the actual +/// asset ([`LoadedUntypedAsset`]). /// /// If you have no idea what type of asset you will be loading (not even at /// runtime with a [`TypeId`]), use this. @@ -386,7 +386,7 @@ impl<'builder, 'reader, T> NestedLoader<'_, '_, T, Immediate<'builder, 'reader>> self, path: &AssetPath<'static>, asset_type_id: Option, - ) -> Result<(Arc, ErasedLoadedAsset), LoadDirectError> { + ) -> Result<(Arc, CompleteErasedLoadedAsset), LoadDirectError> { let (mut meta, loader, mut reader) = if let Some(reader) = self.mode.reader { let loader = if let Some(asset_type_id) = asset_type_id { self.load_context @@ -448,7 +448,7 @@ impl NestedLoader<'_, '_, StaticTyped, Immediate<'_, '_>> { pub async fn load<'p, A: Asset>( self, path: impl Into>, - ) -> Result, LoadDirectError> { + ) -> Result, LoadDirectError> { let path = path.into().into_owned(); self.load_internal(&path, Some(TypeId::of::())) .await @@ -476,7 +476,7 @@ impl NestedLoader<'_, '_, DynamicTyped, Immediate<'_, '_>> { pub async fn load<'p>( self, path: impl Into>, - ) -> Result { + ) -> Result { let path = path.into().into_owned(); let asset_type_id = Some(self.typing.asset_type_id); self.load_internal(&path, asset_type_id) @@ -492,7 +492,7 @@ impl NestedLoader<'_, '_, UnknownTyped, Immediate<'_, '_>> { pub async fn load<'p>( self, path: impl Into>, - ) -> Result { + ) -> Result { let path = path.into().into_owned(); self.load_internal(&path, None) .await diff --git a/crates/bevy_asset/src/processor/process.rs b/crates/bevy_asset/src/processor/process.rs index b37265d0fb..d2202d2334 100644 --- a/crates/bevy_asset/src/processor/process.rs +++ b/crates/bevy_asset/src/processor/process.rs @@ -7,7 +7,7 @@ use crate::{ processor::AssetProcessor, saver::{AssetSaver, SavedAsset}, transformer::{AssetTransformer, IdentityAssetTransformer, TransformedAsset}, - AssetLoadError, AssetLoader, AssetPath, DeserializeMetaError, ErasedLoadedAsset, + AssetLoadError, AssetLoader, AssetPath, CompleteErasedLoadedAsset, DeserializeMetaError, MissingAssetLoaderForExtensionError, MissingAssetLoaderForTypeNameError, }; use alloc::{ @@ -305,15 +305,15 @@ impl<'a> ProcessContext<'a> { pub async fn load_source_asset( &mut self, meta: AssetMeta, - ) -> Result { + ) -> Result { let server = &self.processor.server; let loader_name = core::any::type_name::(); let loader = server.get_asset_loader_with_type_name(loader_name).await?; let mut reader = SliceReader::new(self.asset_bytes); - let loaded_asset = server + let complete_asset = server .load_with_meta_loader_and_reader(self.path, &meta, &*loader, &mut reader, false, true) .await?; - for (path, full_hash) in &loaded_asset.loader_dependencies { + for (path, full_hash) in &complete_asset.asset.loader_dependencies { self.new_processed_info .process_dependencies .push(ProcessDependencyInfo { @@ -321,7 +321,7 @@ impl<'a> ProcessContext<'a> { path: path.to_owned(), }); } - Ok(loaded_asset) + Ok(complete_asset) } /// The path of the asset being processed. diff --git a/crates/bevy_asset/src/saver.rs b/crates/bevy_asset/src/saver.rs index c8b308a544..3b187e96ef 100644 --- a/crates/bevy_asset/src/saver.rs +++ b/crates/bevy_asset/src/saver.rs @@ -1,6 +1,6 @@ use crate::{ io::Writer, meta::Settings, transformer::TransformedAsset, Asset, AssetLoader, - ErasedLoadedAsset, Handle, LabeledAsset, UntypedHandle, + CompleteErasedLoadedAsset, ErasedLoadedAsset, Handle, LabeledAsset, UntypedHandle, }; use alloc::boxed::Box; use atomicow::CowArc; @@ -44,7 +44,7 @@ pub trait ErasedAssetSaver: Send + Sync + 'static { fn save<'a>( &'a self, writer: &'a mut Writer, - asset: &'a ErasedLoadedAsset, + complete_asset: &'a CompleteErasedLoadedAsset, settings: &'a dyn Settings, ) -> BoxedFuture<'a, Result<(), Box>>; @@ -56,14 +56,14 @@ impl ErasedAssetSaver for S { fn save<'a>( &'a self, writer: &'a mut Writer, - asset: &'a ErasedLoadedAsset, + complete_asset: &'a CompleteErasedLoadedAsset, settings: &'a dyn Settings, ) -> BoxedFuture<'a, Result<(), Box>> { Box::pin(async move { let settings = settings .downcast_ref::() .expect("AssetLoader settings should match the loader type"); - let saved_asset = SavedAsset::::from_loaded(asset).unwrap(); + let saved_asset = SavedAsset::::from_loaded(complete_asset).unwrap(); if let Err(err) = self.save(writer, saved_asset, settings).await { return Err(err.into()); } @@ -91,11 +91,11 @@ impl<'a, A: Asset> Deref for SavedAsset<'a, A> { impl<'a, A: Asset> SavedAsset<'a, A> { /// Creates a new [`SavedAsset`] from `asset` if its internal value matches `A`. - pub fn from_loaded(asset: &'a ErasedLoadedAsset) -> Option { - let value = asset.value.downcast_ref::()?; + pub fn from_loaded(complete_asset: &'a CompleteErasedLoadedAsset) -> Option { + let value = complete_asset.asset.value.downcast_ref::()?; Some(SavedAsset { value, - labeled_assets: &asset.labeled_assets, + labeled_assets: &complete_asset.labeled_assets, }) } @@ -114,17 +114,13 @@ impl<'a, A: Asset> SavedAsset<'a, A> { } /// Returns the labeled asset, if it exists and matches this type. - pub fn get_labeled(&self, label: &Q) -> Option> + pub fn get_labeled(&self, label: &Q) -> Option<&B> where CowArc<'static, str>: Borrow, Q: ?Sized + Hash + Eq, { let labeled = self.labeled_assets.get(label)?; - let value = labeled.asset.value.downcast_ref::()?; - Some(SavedAsset { - value, - labeled_assets: &labeled.asset.labeled_assets, - }) + labeled.asset.value.downcast_ref::() } /// Returns the type-erased labeled asset, if it exists and matches this type. diff --git a/crates/bevy_asset/src/server/mod.rs b/crates/bevy_asset/src/server/mod.rs index 0a5c59c629..07c9eed9b4 100644 --- a/crates/bevy_asset/src/server/mod.rs +++ b/crates/bevy_asset/src/server/mod.rs @@ -14,8 +14,8 @@ use crate::{ }, path::AssetPath, Asset, AssetEvent, AssetHandleProvider, AssetId, AssetLoadFailedEvent, AssetMetaCheck, Assets, - DeserializeMetaError, ErasedLoadedAsset, Handle, LoadedUntypedAsset, UntypedAssetId, - UntypedAssetLoadFailedEvent, UntypedHandle, + CompleteErasedLoadedAsset, DeserializeMetaError, ErasedLoadedAsset, Handle, LoadedUntypedAsset, + UntypedAssetId, UntypedAssetLoadFailedEvent, UntypedHandle, }; use alloc::{borrow::ToOwned, boxed::Box, vec, vec::Vec}; use alloc::{ @@ -697,12 +697,18 @@ impl AssetServer { /// Sends a load event for the given `loaded_asset` and does the same recursively for all /// labeled assets. - fn send_loaded_asset(&self, id: UntypedAssetId, mut loaded_asset: ErasedLoadedAsset) { - for (_, labeled_asset) in loaded_asset.labeled_assets.drain() { - self.send_loaded_asset(labeled_asset.handle.id(), labeled_asset.asset); + fn send_loaded_asset(&self, id: UntypedAssetId, mut complete_asset: CompleteErasedLoadedAsset) { + for (_, labeled_asset) in complete_asset.labeled_assets.drain() { + self.send_asset_event(InternalAssetEvent::Loaded { + id: labeled_asset.handle.id(), + loaded_asset: labeled_asset.asset, + }); } - self.send_asset_event(InternalAssetEvent::Loaded { id, loaded_asset }); + self.send_asset_event(InternalAssetEvent::Loaded { + id, + loaded_asset: complete_asset.asset, + }); } /// Kicks off a reload of the asset stored at the given path. This will only reload the asset if it currently loaded. @@ -1326,7 +1332,7 @@ impl AssetServer { reader: &mut dyn Reader, load_dependencies: bool, populate_hashes: bool, - ) -> Result { + ) -> Result { // TODO: experiment with this let asset_path = asset_path.clone_owned(); let load_context = diff --git a/crates/bevy_asset/src/transformer.rs b/crates/bevy_asset/src/transformer.rs index 8b2a8d09be..77daa7423c 100644 --- a/crates/bevy_asset/src/transformer.rs +++ b/crates/bevy_asset/src/transformer.rs @@ -1,4 +1,7 @@ -use crate::{meta::Settings, Asset, ErasedLoadedAsset, Handle, LabeledAsset, UntypedHandle}; +use crate::{ + meta::Settings, Asset, CompleteErasedLoadedAsset, ErasedLoadedAsset, Handle, LabeledAsset, + UntypedHandle, +}; use alloc::boxed::Box; use atomicow::CowArc; use bevy_platform_support::collections::HashMap; @@ -56,11 +59,11 @@ impl DerefMut for TransformedAsset { impl TransformedAsset { /// Creates a new [`TransformedAsset`] from `asset` if its internal value matches `A`. - pub fn from_loaded(asset: ErasedLoadedAsset) -> Option { - if let Ok(value) = asset.value.downcast::() { + pub fn from_loaded(complete_asset: CompleteErasedLoadedAsset) -> Option { + if let Ok(value) = complete_asset.asset.value.downcast::() { return Some(TransformedAsset { value: *value, - labeled_assets: asset.labeled_assets, + labeled_assets: complete_asset.labeled_assets, }); } None @@ -87,117 +90,13 @@ impl TransformedAsset { &mut self.value } /// Returns the labeled asset, if it exists and matches this type. - pub fn get_labeled(&mut self, label: &Q) -> Option> + pub fn get_labeled(&mut self, label: &'_ Q) -> Option<&mut B> where CowArc<'static, str>: Borrow, Q: ?Sized + Hash + Eq, { let labeled = self.labeled_assets.get_mut(label)?; - let value = labeled.asset.value.downcast_mut::()?; - Some(TransformedSubAsset { - value, - labeled_assets: &mut labeled.asset.labeled_assets, - }) - } - /// Returns the type-erased labeled asset, if it exists and matches this type. - pub fn get_erased_labeled(&self, label: &Q) -> Option<&ErasedLoadedAsset> - where - CowArc<'static, str>: Borrow, - Q: ?Sized + Hash + Eq, - { - let labeled = self.labeled_assets.get(label)?; - Some(&labeled.asset) - } - /// Returns the [`UntypedHandle`] of the labeled asset with the provided 'label', if it exists. - pub fn get_untyped_handle(&self, label: &Q) -> Option - where - CowArc<'static, str>: Borrow, - Q: ?Sized + Hash + Eq, - { - let labeled = self.labeled_assets.get(label)?; - Some(labeled.handle.clone()) - } - /// Returns the [`Handle`] of the labeled asset with the provided 'label', if it exists and is an asset of type `B` - pub fn get_handle(&self, label: &Q) -> Option> - where - CowArc<'static, str>: Borrow, - Q: ?Sized + Hash + Eq, - { - let labeled = self.labeled_assets.get(label)?; - if let Ok(handle) = labeled.handle.clone().try_typed::() { - return Some(handle); - } - None - } - /// Adds `asset` as a labeled sub asset using `label` and `handle` - pub fn insert_labeled( - &mut self, - label: impl Into>, - handle: impl Into, - asset: impl Into, - ) { - let labeled = LabeledAsset { - asset: asset.into(), - handle: handle.into(), - }; - self.labeled_assets.insert(label.into(), labeled); - } - /// Iterate over all labels for "labeled assets" in the loaded asset - pub fn iter_labels(&self) -> impl Iterator { - self.labeled_assets.keys().map(|s| &**s) - } -} - -/// A labeled sub-asset of [`TransformedAsset`] -pub struct TransformedSubAsset<'a, A: Asset> { - value: &'a mut A, - labeled_assets: &'a mut HashMap, LabeledAsset>, -} - -impl<'a, A: Asset> Deref for TransformedSubAsset<'a, A> { - type Target = A; - fn deref(&self) -> &Self::Target { - self.value - } -} - -impl<'a, A: Asset> DerefMut for TransformedSubAsset<'a, A> { - fn deref_mut(&mut self) -> &mut Self::Target { - self.value - } -} - -impl<'a, A: Asset> TransformedSubAsset<'a, A> { - /// Creates a new [`TransformedSubAsset`] from `asset` if its internal value matches `A`. - pub fn from_loaded(asset: &'a mut ErasedLoadedAsset) -> Option { - let value = asset.value.downcast_mut::()?; - Some(TransformedSubAsset { - value, - labeled_assets: &mut asset.labeled_assets, - }) - } - /// Retrieves the value of this asset. - #[inline] - pub fn get(&self) -> &A { - self.value - } - /// Mutably retrieves the value of this asset. - #[inline] - pub fn get_mut(&mut self) -> &mut A { - self.value - } - /// Returns the labeled asset, if it exists and matches this type. - pub fn get_labeled(&mut self, label: &Q) -> Option> - where - CowArc<'static, str>: Borrow, - Q: ?Sized + Hash + Eq, - { - let labeled = self.labeled_assets.get_mut(label)?; - let value = labeled.asset.value.downcast_mut::()?; - Some(TransformedSubAsset { - value, - labeled_assets: &mut labeled.asset.labeled_assets, - }) + labeled.asset.value.downcast_mut::() } /// Returns the type-erased labeled asset, if it exists and matches this type. pub fn get_erased_labeled(&self, label: &Q) -> Option<&ErasedLoadedAsset> diff --git a/examples/asset/asset_decompression.rs b/examples/asset/asset_decompression.rs index e514924ca9..edc42ab853 100644 --- a/examples/asset/asset_decompression.rs +++ b/examples/asset/asset_decompression.rs @@ -3,7 +3,7 @@ use bevy::{ asset::{ io::{Reader, VecReader}, - AssetLoader, ErasedLoadedAsset, LoadContext, LoadDirectError, + AssetLoader, CompleteErasedLoadedAsset, LoadContext, LoadDirectError, }, prelude::*, reflect::TypePath, @@ -14,7 +14,7 @@ use thiserror::Error; #[derive(Asset, TypePath)] struct GzAsset { - uncompressed: ErasedLoadedAsset, + uncompressed: CompleteErasedLoadedAsset, } #[derive(Default)] diff --git a/examples/asset/processing/asset_processing.rs b/examples/asset/processing/asset_processing.rs index 47a12fc6bb..b24f7afb14 100644 --- a/examples/asset/processing/asset_processing.rs +++ b/examples/asset/processing/asset_processing.rs @@ -149,15 +149,15 @@ impl AssetLoader for CoolTextLoader { let ron: CoolTextRon = ron::de::from_bytes(&bytes)?; let mut base_text = ron.text; for embedded in ron.embedded_dependencies { - let loaded = load_context + let complete_loaded = load_context .loader() .immediate() .load::(&embedded) .await?; - base_text.push_str(&loaded.get().0); + base_text.push_str(&complete_loaded.get_asset().get().0); } for (path, settings_override) in ron.dependencies_with_settings { - let loaded = load_context + let complete_loaded = load_context .loader() .with_settings(move |settings| { *settings = settings_override.clone(); @@ -165,7 +165,7 @@ impl AssetLoader for CoolTextLoader { .immediate() .load::(&path) .await?; - base_text.push_str(&loaded.get().0); + base_text.push_str(&complete_loaded.get_asset().get().0); } Ok(CoolText { text: base_text,