diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index 5a1c4c7756d5d..b499d8622584c 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -738,7 +738,7 @@ mod tests { let a_text = get::(app.world(), a_id); let (a_load, a_deps, a_rec_deps) = asset_server.get_load_states(a_id).unwrap(); assert!(a_text.is_none(), "a's asset should not exist yet"); - assert_eq!(a_load, LoadState::Loading, "a should still be loading"); + assert!(a_load.is_loading(), "a should still be loading"); assert_eq!( a_deps, DependencyLoadState::Loading, @@ -759,7 +759,7 @@ mod tests { let (a_load, a_deps, a_rec_deps) = asset_server.get_load_states(a_id).unwrap(); assert_eq!(a_text.text, "a"); assert_eq!(a_text.dependencies.len(), 2); - assert_eq!(a_load, LoadState::Loaded, "a is loaded"); + assert!(a_load.is_loaded(), "a is loaded"); assert_eq!(a_deps, DependencyLoadState::Loading); assert_eq!(a_rec_deps, RecursiveDependencyLoadState::Loading); @@ -767,7 +767,7 @@ mod tests { let b_text = get::(world, b_id); let (b_load, b_deps, b_rec_deps) = asset_server.get_load_states(b_id).unwrap(); assert!(b_text.is_none(), "b component should not exist yet"); - assert_eq!(b_load, LoadState::Loading); + assert!(b_load.is_loading()); assert_eq!(b_deps, DependencyLoadState::Loading); assert_eq!(b_rec_deps, RecursiveDependencyLoadState::Loading); @@ -775,7 +775,7 @@ mod tests { let c_text = get::(world, c_id); let (c_load, c_deps, c_rec_deps) = asset_server.get_load_states(c_id).unwrap(); assert!(c_text.is_none(), "c component should not exist yet"); - assert_eq!(c_load, LoadState::Loading); + assert!(c_load.is_loading()); assert_eq!(c_deps, DependencyLoadState::Loading); assert_eq!(c_rec_deps, RecursiveDependencyLoadState::Loading); Some(()) @@ -789,7 +789,7 @@ mod tests { let (a_load, a_deps, a_rec_deps) = asset_server.get_load_states(a_id).unwrap(); assert_eq!(a_text.text, "a"); assert_eq!(a_text.dependencies.len(), 2); - assert_eq!(a_load, LoadState::Loaded); + assert!(a_load.is_loaded()); assert_eq!(a_deps, DependencyLoadState::Loading); assert_eq!(a_rec_deps, RecursiveDependencyLoadState::Loading); @@ -797,7 +797,7 @@ mod tests { let b_text = get::(world, b_id)?; let (b_load, b_deps, b_rec_deps) = asset_server.get_load_states(b_id).unwrap(); assert_eq!(b_text.text, "b"); - assert_eq!(b_load, LoadState::Loaded); + assert!(b_load.is_loaded()); assert_eq!(b_deps, DependencyLoadState::Loaded); assert_eq!(b_rec_deps, RecursiveDependencyLoadState::Loaded); @@ -805,7 +805,7 @@ mod tests { let c_text = get::(world, c_id); let (c_load, c_deps, c_rec_deps) = asset_server.get_load_states(c_id).unwrap(); assert!(c_text.is_none(), "c component should not exist yet"); - assert_eq!(c_load, LoadState::Loading); + assert!(c_load.is_loading()); assert_eq!(c_deps, DependencyLoadState::Loading); assert_eq!(c_rec_deps, RecursiveDependencyLoadState::Loading); Some(()) @@ -824,14 +824,14 @@ mod tests { assert_eq!(a_text.text, "a"); assert_eq!(a_text.embedded, ""); assert_eq!(a_text.dependencies.len(), 2); - assert_eq!(a_load, LoadState::Loaded); + assert!(a_load.is_loaded()); let b_id = a_text.dependencies[0].id(); let b_text = get::(world, b_id)?; let (b_load, b_deps, b_rec_deps) = asset_server.get_load_states(b_id).unwrap(); assert_eq!(b_text.text, "b"); assert_eq!(b_text.embedded, ""); - assert_eq!(b_load, LoadState::Loaded); + assert!(b_load.is_loaded()); assert_eq!(b_deps, DependencyLoadState::Loaded); assert_eq!(b_rec_deps, RecursiveDependencyLoadState::Loaded); @@ -840,7 +840,7 @@ mod tests { let (c_load, c_deps, c_rec_deps) = asset_server.get_load_states(c_id).unwrap(); assert_eq!(c_text.text, "c"); assert_eq!(c_text.embedded, "ab"); - assert_eq!(c_load, LoadState::Loaded); + assert!(c_load.is_loaded()); assert_eq!( c_deps, DependencyLoadState::Loading, @@ -858,7 +858,7 @@ mod tests { assert_eq!(sub_text.text, "hello"); let (sub_text_load, sub_text_deps, sub_text_rec_deps) = asset_server.get_load_states(sub_text_id).unwrap(); - assert_eq!(sub_text_load, LoadState::Loaded); + assert!(sub_text_load.is_loaded()); assert_eq!(sub_text_deps, DependencyLoadState::Loaded); assert_eq!(sub_text_rec_deps, RecursiveDependencyLoadState::Loaded); @@ -866,7 +866,7 @@ mod tests { let d_text = get::(world, d_id); let (d_load, d_deps, d_rec_deps) = asset_server.get_load_states(d_id).unwrap(); assert!(d_text.is_none(), "d component should not exist yet"); - assert_eq!(d_load, LoadState::Loading); + assert!(d_load.is_loading()); assert_eq!(d_deps, DependencyLoadState::Loading); assert_eq!(d_rec_deps, RecursiveDependencyLoadState::Loading); @@ -900,11 +900,11 @@ mod tests { assert_eq!(d_text.text, "d"); assert_eq!(d_text.embedded, ""); - assert_eq!(c_load, LoadState::Loaded); + assert!(c_load.is_loaded()); assert_eq!(c_deps, DependencyLoadState::Loaded); assert_eq!(c_rec_deps, RecursiveDependencyLoadState::Loaded); - assert_eq!(d_load, LoadState::Loaded); + assert!(d_load.is_loaded()); assert_eq!(d_deps, DependencyLoadState::Loaded); assert_eq!(d_rec_deps, RecursiveDependencyLoadState::Loaded); @@ -1089,17 +1089,17 @@ mod tests { assert_eq!(d_rec_deps, RecursiveDependencyLoadState::Failed); assert_eq!(a_text.text, "a"); - assert_eq!(a_load, LoadState::Loaded); + assert!(a_load.is_loaded()); assert_eq!(a_deps, DependencyLoadState::Loaded); assert_eq!(a_rec_deps, RecursiveDependencyLoadState::Failed); assert_eq!(b_text.text, "b"); - assert_eq!(b_load, LoadState::Loaded); + assert!(b_load.is_loaded()); assert_eq!(b_deps, DependencyLoadState::Loaded); assert_eq!(b_rec_deps, RecursiveDependencyLoadState::Loaded); assert_eq!(c_text.text, "c"); - assert_eq!(c_load, LoadState::Loaded); + assert!(c_load.is_loaded()); assert_eq!(c_deps, DependencyLoadState::Failed); assert_eq!(c_rec_deps, RecursiveDependencyLoadState::Failed); diff --git a/crates/bevy_asset/src/server/info.rs b/crates/bevy_asset/src/server/info.rs index 98d92702077c7..2e54c3d317f57 100644 --- a/crates/bevy_asset/src/server/info.rs +++ b/crates/bevy_asset/src/server/info.rs @@ -540,7 +540,7 @@ impl AssetInfos { info.loading_rec_dependencies.remove(&loaded_id); if info.loading_rec_dependencies.is_empty() && info.failed_rec_dependencies.is_empty() { info.rec_dep_load_state = RecursiveDependencyLoadState::Loaded; - if info.load_state == LoadState::Loaded { + if info.load_state.is_loaded() { sender .send(InternalAssetEvent::LoadedWithDependencies { id: waiting_id }) .unwrap(); diff --git a/crates/bevy_asset/src/server/mod.rs b/crates/bevy_asset/src/server/mod.rs index 10b5079de9b20..90ffc2214eed3 100644 --- a/crates/bevy_asset/src/server/mod.rs +++ b/crates/bevy_asset/src/server/mod.rs @@ -27,7 +27,7 @@ use info::*; use loaders::*; use parking_lot::RwLock; use std::future::Future; -use std::{any::Any, path::PathBuf}; +use std::path::PathBuf; use std::{any::TypeId, path::Path, sync::Arc}; use thiserror::Error; @@ -930,7 +930,7 @@ impl AssetServer { /// Returns true if the asset and all of its dependencies (recursive) have been loaded. pub fn is_loaded_with_dependencies(&self, id: impl Into) -> bool { let id = id.into(); - self.load_state(id) == LoadState::Loaded + self.load_state(id).is_loaded() && self.recursive_dependency_load_state(id) == RecursiveDependencyLoadState::Loaded } @@ -1327,7 +1327,7 @@ pub(crate) enum InternalAssetEvent { } /// The load state of an asset. -#[derive(Component, Clone, Debug, PartialEq, Eq)] +#[derive(Component, Clone, Debug)] pub enum LoadState { /// The asset has not started loading yet NotLoaded, @@ -1339,6 +1339,33 @@ pub enum LoadState { Failed(Box), } +impl LoadState { + /// Returns `true` if this instance is [`LoadState::Loading`] + pub fn is_loading(&self) -> bool { + matches!(self, Self::Loading) + } + /// Returns `true` if this instance is [`LoadState::Loaded`] + pub fn is_loaded(&self) -> bool { + matches!(self, Self::Loaded) + } + // NOTE: an `is_not_loaded` method is intentionally not included, as it may mislead some users + // into thinking it is complementary to `is_loaded`. + // `NotLoaded` is a very specific failure mode and in most cases it is not necessary to directly check for it. + // If this is necessary the `matches!` macro can be used instead of a helper method. + + /// Returns `true` if the asset is loaded or in the process of being loaded. If true true, + /// then the asset can be considered to be in a "normal" state: the asset either exists + /// or will exist, and no errors have been encountered yet. + pub fn is_loaded_or_loading(&self) -> bool { + self.is_loaded() || self.is_loading() + } + + /// Returns `true` if this instance is [`LoadState::Failed`] + pub fn is_failed(&self) -> bool { + matches!(self, Self::Failed(_)) + } +} + /// The load state of an asset's dependencies. #[derive(Component, Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub enum DependencyLoadState { @@ -1366,7 +1393,7 @@ pub enum RecursiveDependencyLoadState { } /// An error that occurs during an [`Asset`] load. -#[derive(Error, Debug, Clone, PartialEq, Eq)] +#[derive(Error, Debug, Clone)] pub enum AssetLoadError { #[error("Requested handle of type {requested:?} for asset '{path}' does not match actual asset type '{actual_asset_name}', which used loader '{loader_name}'")] RequestedHandleTypeMismatch { @@ -1429,18 +1456,6 @@ pub struct AssetLoaderError { error: Arc, } -impl PartialEq for AssetLoaderError { - /// Equality comparison for `AssetLoaderError::error` is not full (only through `TypeId`) - #[inline] - fn eq(&self, other: &Self) -> bool { - self.path == other.path - && self.loader_name == other.loader_name - && self.error.type_id() == other.error.type_id() - } -} - -impl Eq for AssetLoaderError {} - impl AssetLoaderError { pub fn path(&self) -> &AssetPath<'static> { &self.path @@ -1453,16 +1468,6 @@ pub struct AddAsyncError { error: Arc, } -impl PartialEq for AddAsyncError { - /// Equality comparison is not full (only through `TypeId`) - #[inline] - fn eq(&self, other: &Self) -> bool { - self.error.type_id() == other.error.type_id() - } -} - -impl Eq for AddAsyncError {} - /// An error that occurs when an [`AssetLoader`] is not registered for a given extension. #[derive(Error, Debug, Clone, PartialEq, Eq)] #[error("no `AssetLoader` found{}", format_missing_asset_ext(.extensions))] diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 4306a48d27f65..7f446b0f9070d 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -2063,7 +2063,7 @@ mod test { app.update(); run_app_until(&mut app, |_world| { let load_state = asset_server.get_load_state(handle_id).unwrap(); - if load_state == LoadState::Loaded { + if load_state.is_loaded() { Some(()) } else { None diff --git a/examples/3d/pbr.rs b/examples/3d/pbr.rs index 3c7a76211903f..f9326cfa200b1 100644 --- a/examples/3d/pbr.rs +++ b/examples/3d/pbr.rs @@ -1,6 +1,6 @@ //! This example shows how to configure Physically Based Rendering (PBR) parameters. -use bevy::{asset::LoadState, prelude::*}; +use bevy::prelude::*; fn main() { App::new() @@ -142,8 +142,12 @@ fn environment_map_load_finish( label_query: Query>, ) { if let Ok(environment_map) = environment_maps.get_single() { - if asset_server.load_state(&environment_map.diffuse_map) == LoadState::Loaded - && asset_server.load_state(&environment_map.specular_map) == LoadState::Loaded + if asset_server + .load_state(&environment_map.diffuse_map) + .is_loaded() + && asset_server + .load_state(&environment_map.specular_map) + .is_loaded() { if let Ok(label_entity) = label_query.get_single() { commands.entity(label_entity).despawn(); diff --git a/examples/3d/skybox.rs b/examples/3d/skybox.rs index 115d378e2e2d6..108ec9793619b 100644 --- a/examples/3d/skybox.rs +++ b/examples/3d/skybox.rs @@ -4,7 +4,6 @@ mod camera_controller; use bevy::{ - asset::LoadState, core_pipeline::Skybox, prelude::*, render::{ @@ -147,7 +146,7 @@ fn asset_loaded( mut cubemap: ResMut, mut skyboxes: Query<&mut Skybox>, ) { - if !cubemap.is_loaded && asset_server.load_state(&cubemap.image_handle) == LoadState::Loaded { + if !cubemap.is_loaded && asset_server.load_state(&cubemap.image_handle).is_loaded() { info!("Swapping to {}...", CUBEMAPS[cubemap.index].0); let image = images.get_mut(&cubemap.image_handle).unwrap(); // NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture, diff --git a/examples/shader/array_texture.rs b/examples/shader/array_texture.rs index 1cd366b092bf3..abae333019294 100644 --- a/examples/shader/array_texture.rs +++ b/examples/shader/array_texture.rs @@ -2,7 +2,6 @@ //! uniform variable. use bevy::{ - asset::LoadState, prelude::*, reflect::TypePath, render::render_resource::{AsBindGroup, ShaderRef}, @@ -57,7 +56,9 @@ fn create_array_texture( mut materials: ResMut>, ) { if loading_texture.is_loaded - || asset_server.load_state(loading_texture.handle.id()) != LoadState::Loaded + || !asset_server + .load_state(loading_texture.handle.id()) + .is_loaded() { return; } diff --git a/examples/tools/scene_viewer/scene_viewer_plugin.rs b/examples/tools/scene_viewer/scene_viewer_plugin.rs index 2ff6af4948928..b54f55ac0c8dd 100644 --- a/examples/tools/scene_viewer/scene_viewer_plugin.rs +++ b/examples/tools/scene_viewer/scene_viewer_plugin.rs @@ -4,8 +4,7 @@ //! - Insert an initialized `SceneHandle` resource into your App's `AssetServer`. use bevy::{ - asset::LoadState, gltf::Gltf, input::common_conditions::input_just_pressed, prelude::*, - scene::InstanceId, + gltf::Gltf, input::common_conditions::input_just_pressed, prelude::*, scene::InstanceId, }; use std::f32::consts::*; @@ -92,7 +91,10 @@ fn scene_load_check( ) { match scene_handle.instance_id { None => { - if asset_server.load_state(&scene_handle.gltf_handle) == LoadState::Loaded { + if asset_server + .load_state(&scene_handle.gltf_handle) + .is_loaded() + { let gltf = gltf_assets.get(&scene_handle.gltf_handle).unwrap(); if gltf.scenes.len() > 1 { info!(