Remove incorrect equality comparisons for asset load error types (#15890)

# Objective

The type `AssetLoadError` has `PartialEq` and `Eq` impls, which is
problematic due to the fact that the `AssetLoaderError` and
`AddAsyncError` variants lie in their impls: they will return `true` for
any `Box<dyn Error>` with the same `TypeId`, even if the actual value is
different. This can lead to subtle bugs if a user relies on the equality
comparison to ensure that two values are equal.

The same is true for `DependencyLoadState`,
`RecursiveDependencyLoadState`.

More generally, it is an anti-pattern for large error types involving
dynamic dispatch, such as `AssetLoadError`, to have equality
comparisons. Directly comparing two errors for equality is usually not
desired -- if some logic needs to branch based on the value of an error,
it is usually more correct to check for specific variants and inspect
their fields.

As far as I can tell, the only reason these errors have equality
comparisons is because the `LoadState` enum wraps `AssetLoadError` for
its `Failed` variant. This equality comparison is only used to check for
`== LoadState::Loaded`, which we can easily replace with an `is_loaded`
method.

## Solution

Remove the `{Partial}Eq` impls from `LoadState`, which also allows us to
remove it from the error types.

## Migration Guide

The types `bevy_asset::AssetLoadError` and `bevy_asset::LoadState` no
longer support equality comparisons. If you need to check for an asset's
load state, consider checking for a specific variant using
`LoadState::is_loaded` or the `matches!` macro. Similarly, consider
using the `matches!` macro to check for specific variants of the
`AssetLoadError` type if you need to inspect the value of an asset load
error in your code.

`DependencyLoadState` and `RecursiveDependencyLoadState` are not
released yet, so no migration needed,

---------

Co-authored-by: Joseph <21144246+JoJoJet@users.noreply.github.com>
This commit is contained in:
Benjamin Brienen 2024-10-14 03:00:45 +02:00 committed by GitHub
parent a7e9330af9
commit 93fc2d12cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 176 additions and 169 deletions

View file

@ -617,8 +617,7 @@ mod tests {
},
loader::{AssetLoader, LoadContext},
Asset, AssetApp, AssetEvent, AssetId, AssetLoadError, AssetLoadFailedEvent, AssetPath,
AssetPlugin, AssetServer, Assets, DependencyLoadState, LoadState,
RecursiveDependencyLoadState,
AssetPlugin, AssetServer, Assets,
};
use alloc::sync::Arc;
use bevy_app::{App, Update};
@ -905,17 +904,9 @@ mod tests {
let a_text = get::<CoolText>(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_eq!(
a_deps,
DependencyLoadState::Loading,
"a deps should still be loading"
);
assert_eq!(
a_rec_deps,
RecursiveDependencyLoadState::Loading,
"a recursive deps should still be loading"
);
assert!(a_load.is_loading());
assert!(a_deps.is_loading());
assert!(a_rec_deps.is_loading());
}
// Allow "a" to load ... wait for it to finish loading and validate results
@ -926,25 +917,25 @@ 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_eq!(a_deps, DependencyLoadState::Loading);
assert_eq!(a_rec_deps, RecursiveDependencyLoadState::Loading);
assert!(a_load.is_loaded());
assert!(a_deps.is_loading());
assert!(a_rec_deps.is_loading());
let b_id = a_text.dependencies[0].id();
let b_text = get::<CoolText>(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_eq!(b_deps, DependencyLoadState::Loading);
assert_eq!(b_rec_deps, RecursiveDependencyLoadState::Loading);
assert!(b_load.is_loading());
assert!(b_deps.is_loading());
assert!(b_rec_deps.is_loading());
let c_id = a_text.dependencies[1].id();
let c_text = get::<CoolText>(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_eq!(c_deps, DependencyLoadState::Loading);
assert_eq!(c_rec_deps, RecursiveDependencyLoadState::Loading);
assert!(c_load.is_loading());
assert!(c_deps.is_loading());
assert!(c_rec_deps.is_loading());
Some(())
});
@ -956,25 +947,25 @@ 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_eq!(a_deps, DependencyLoadState::Loading);
assert_eq!(a_rec_deps, RecursiveDependencyLoadState::Loading);
assert!(a_load.is_loaded());
assert!(a_deps.is_loading());
assert!(a_rec_deps.is_loading());
let b_id = a_text.dependencies[0].id();
let b_text = get::<CoolText>(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_eq!(b_deps, DependencyLoadState::Loaded);
assert_eq!(b_rec_deps, RecursiveDependencyLoadState::Loaded);
assert!(b_load.is_loaded());
assert!(b_deps.is_loaded());
assert!(b_rec_deps.is_loaded());
let c_id = a_text.dependencies[1].id();
let c_text = get::<CoolText>(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_eq!(c_deps, DependencyLoadState::Loading);
assert_eq!(c_rec_deps, RecursiveDependencyLoadState::Loading);
assert!(c_load.is_loading());
assert!(c_deps.is_loading());
assert!(c_rec_deps.is_loading());
Some(())
});
@ -991,31 +982,29 @@ 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::<CoolText>(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_eq!(b_deps, DependencyLoadState::Loaded);
assert_eq!(b_rec_deps, RecursiveDependencyLoadState::Loaded);
assert!(b_load.is_loaded());
assert!(b_deps.is_loaded());
assert!(b_rec_deps.is_loaded());
let c_id = a_text.dependencies[1].id();
let c_text = get::<CoolText>(world, c_id)?;
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_eq!(
c_deps,
DependencyLoadState::Loading,
assert!(c_load.is_loaded());
assert!(
c_deps.is_loading(),
"c deps should not be loaded yet because d has not loaded"
);
assert_eq!(
c_rec_deps,
RecursiveDependencyLoadState::Loading,
assert!(
c_rec_deps.is_loading(),
"c rec deps should not be loaded yet because d has not loaded"
);
@ -1025,26 +1014,24 @@ 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_eq!(sub_text_deps, DependencyLoadState::Loaded);
assert_eq!(sub_text_rec_deps, RecursiveDependencyLoadState::Loaded);
assert!(sub_text_load.is_loaded());
assert!(sub_text_deps.is_loaded());
assert!(sub_text_rec_deps.is_loaded());
let d_id = c_text.dependencies[0].id();
let d_text = get::<CoolText>(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_eq!(d_deps, DependencyLoadState::Loading);
assert_eq!(d_rec_deps, RecursiveDependencyLoadState::Loading);
assert!(d_load.is_loading());
assert!(d_deps.is_loading());
assert!(d_rec_deps.is_loading());
assert_eq!(
a_deps,
DependencyLoadState::Loaded,
assert!(
a_deps.is_loaded(),
"If c has been loaded, the a deps should all be considered loaded"
);
assert_eq!(
a_rec_deps,
RecursiveDependencyLoadState::Loading,
assert!(
a_rec_deps.is_loading(),
"d is not loaded, so a's recursive deps should still be loading"
);
world.insert_resource(IdResults { b_id, c_id, d_id });
@ -1067,17 +1054,16 @@ mod tests {
assert_eq!(d_text.text, "d");
assert_eq!(d_text.embedded, "");
assert_eq!(c_load, LoadState::Loaded);
assert_eq!(c_deps, DependencyLoadState::Loaded);
assert_eq!(c_rec_deps, RecursiveDependencyLoadState::Loaded);
assert!(c_load.is_loaded());
assert!(c_deps.is_loaded());
assert!(c_rec_deps.is_loaded());
assert_eq!(d_load, LoadState::Loaded);
assert_eq!(d_deps, DependencyLoadState::Loaded);
assert_eq!(d_rec_deps, RecursiveDependencyLoadState::Loaded);
assert!(d_load.is_loaded());
assert!(d_deps.is_loaded());
assert!(d_rec_deps.is_loaded());
assert_eq!(
a_rec_deps,
RecursiveDependencyLoadState::Loaded,
assert!(
a_rec_deps.is_loaded(),
"d is loaded, so a's recursive deps should be loaded"
);
Some(())
@ -1245,49 +1231,37 @@ mod tests {
let d_id = c_text.dependencies[0].id();
let d_text = get::<CoolText>(world, d_id);
let (d_load, d_deps, d_rec_deps) = asset_server.get_load_states(d_id).unwrap();
if !matches!(d_load, LoadState::Failed(_)) {
if !d_load.is_failed() {
// wait until d has exited the loading state
return None;
}
assert!(d_text.is_none());
assert!(matches!(d_load, LoadState::Failed(_)));
assert!(matches!(d_deps, DependencyLoadState::Failed(_)));
assert!(matches!(
d_rec_deps,
RecursiveDependencyLoadState::Failed(_)
));
assert!(d_load.is_failed());
assert!(d_deps.is_failed());
assert!(d_rec_deps.is_failed());
assert_eq!(a_text.text, "a");
assert_eq!(a_load, LoadState::Loaded);
assert_eq!(a_deps, DependencyLoadState::Loaded);
assert!(matches!(
a_rec_deps,
RecursiveDependencyLoadState::Failed(_)
));
assert!(a_load.is_loaded());
assert!(a_deps.is_loaded());
assert!(a_rec_deps.is_failed());
assert_eq!(b_text.text, "b");
assert_eq!(b_load, LoadState::Loaded);
assert_eq!(b_deps, DependencyLoadState::Loaded);
assert_eq!(b_rec_deps, RecursiveDependencyLoadState::Loaded);
assert!(b_load.is_loaded());
assert!(b_deps.is_loaded());
assert!(b_rec_deps.is_loaded());
assert_eq!(c_text.text, "c");
assert_eq!(c_load, LoadState::Loaded);
assert!(matches!(c_deps, DependencyLoadState::Failed(_)));
assert!(matches!(
c_rec_deps,
RecursiveDependencyLoadState::Failed(_)
));
assert!(c_load.is_loaded());
assert!(c_deps.is_failed());
assert!(c_rec_deps.is_failed());
assert_eq!(asset_server.load_state(a_id), LoadState::Loaded);
assert_eq!(
asset_server.dependency_load_state(a_id),
DependencyLoadState::Loaded
);
assert!(matches!(
asset_server.recursive_dependency_load_state(a_id),
RecursiveDependencyLoadState::Failed(_)
));
assert!(asset_server.load_state(a_id).is_loaded());
assert!(asset_server.dependency_load_state(a_id).is_loaded());
assert!(asset_server
.recursive_dependency_load_state(a_id)
.is_failed());
assert!(asset_server.is_loaded(a_id));
assert!(asset_server.is_loaded_with_direct_dependencies(a_id));
@ -1349,9 +1323,9 @@ mod tests {
run_app_until(&mut app, |world| {
let _a_text = get::<CoolText>(world, a_id)?;
let (a_load, a_deps, a_rec_deps) = asset_server.get_load_states(a_id).unwrap();
assert_eq!(a_load, LoadState::Loaded);
assert_eq!(a_deps, DependencyLoadState::Loading);
assert_eq!(a_rec_deps, RecursiveDependencyLoadState::Loading);
assert!(a_load.is_loaded());
assert!(a_deps.is_loading());
assert!(a_rec_deps.is_loading());
Some(())
});
@ -1361,18 +1335,15 @@ mod tests {
let b_id = a_text.dependencies[0].id();
let (b_load, _b_deps, _b_rec_deps) = asset_server.get_load_states(b_id).unwrap();
if !matches!(b_load, LoadState::Failed(_)) {
if !b_load.is_failed() {
// wait until b fails
return None;
}
let (a_load, a_deps, a_rec_deps) = asset_server.get_load_states(a_id).unwrap();
assert_eq!(a_load, LoadState::Loaded);
assert!(matches!(a_deps, DependencyLoadState::Failed(_)));
assert!(matches!(
a_rec_deps,
RecursiveDependencyLoadState::Failed(_)
));
assert!(a_load.is_loaded());
assert!(a_deps.is_failed());
assert!(a_rec_deps.is_failed());
Some(())
});
@ -1384,13 +1355,13 @@ mod tests {
let _c_text = get::<CoolText>(world, c_id)?;
let (a_load, a_deps, a_rec_deps) = asset_server.get_load_states(a_id).unwrap();
assert_eq!(a_load, LoadState::Loaded);
assert!(a_load.is_loaded());
assert!(
matches!(a_deps, DependencyLoadState::Failed(_)),
a_deps.is_failed(),
"Successful dependency load should not overwrite a previous failure"
);
assert!(
matches!(a_rec_deps, RecursiveDependencyLoadState::Failed(_)),
a_rec_deps.is_failed(),
"Successful dependency load should not overwrite a previous failure"
);
Some(())
@ -1681,7 +1652,7 @@ mod tests {
// Check what just failed
for error in errors.read() {
let (load_state, _, _) = server.get_load_states(error.id).unwrap();
assert!(matches!(load_state, LoadState::Failed(_)));
assert!(load_state.is_failed());
assert_eq!(*error.path.source(), AssetSourceId::Name("unstable".into()));
match &error.error {
AssetLoadError::AssetReaderError(read_error) => match read_error {

View file

@ -498,16 +498,14 @@ impl AssetInfos {
info.loader_dependencies = loaded_asset.loader_dependencies;
}
let dependants_waiting_on_rec_load = if matches!(
rec_dep_load_state,
RecursiveDependencyLoadState::Loaded | RecursiveDependencyLoadState::Failed(_)
) {
Some(core::mem::take(
&mut info.dependants_waiting_on_recursive_dep_load,
))
} else {
None
};
let dependants_waiting_on_rec_load =
if rec_dep_load_state.is_loaded() || rec_dep_load_state.is_failed() {
Some(core::mem::take(
&mut info.dependants_waiting_on_recursive_dep_load,
))
} else {
None
};
(
core::mem::take(&mut info.dependants_waiting_on_load),
@ -518,9 +516,7 @@ impl AssetInfos {
for id in dependants_waiting_on_load {
if let Some(info) = self.get_mut(id) {
info.loading_dependencies.remove(&loaded_asset_id);
if info.loading_dependencies.is_empty()
&& !matches!(info.dep_load_state, DependencyLoadState::Failed(_))
{
if info.loading_dependencies.is_empty() && !info.dep_load_state.is_failed() {
// send dependencies loaded event
info.dep_load_state = DependencyLoadState::Loaded;
}
@ -558,7 +554,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();
@ -631,7 +627,7 @@ impl AssetInfos {
info.loading_dependencies.remove(&failed_id);
info.failed_dependencies.insert(failed_id);
// don't overwrite DependencyLoadState if already failed to preserve first error
if !(matches!(info.dep_load_state, DependencyLoadState::Failed(_))) {
if !info.dep_load_state.is_failed() {
info.dep_load_state = DependencyLoadState::Failed(error.clone());
}
}

View file

@ -25,11 +25,7 @@ use bevy_utils::{
tracing::{error, info},
HashSet,
};
use core::{
any::{Any, TypeId},
future::Future,
panic::AssertUnwindSafe,
};
use core::{any::TypeId, future::Future, panic::AssertUnwindSafe};
use crossbeam_channel::{Receiver, Sender};
use derive_more::derive::{Display, Error, From};
use either::Either;
@ -1486,44 +1482,87 @@ 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,
/// The asset is in the process of loading.
Loading,
/// The asset has been loaded and has been added to the [`World`]
Loaded,
/// The asset failed to load. The underlying [`AssetLoadError`] is
/// referenced by [`Arc`] clones in all related [`DependencyLoadState`]s
/// and [`RecursiveDependencyLoadState`]s in the asset's dependency tree.
Failed(Arc<AssetLoadError>),
}
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)
}
/// 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, Clone, Debug, Eq, PartialEq)]
#[derive(Component, Clone, Debug)]
pub enum DependencyLoadState {
/// The asset has not started loading yet
NotLoaded,
/// Dependencies are still loading
Loading,
/// Dependencies have all loaded
Loaded,
/// One or more dependencies have failed to load. The underlying [`AssetLoadError`]
/// is referenced by [`Arc`] clones in all related [`LoadState`] and
/// [`RecursiveDependencyLoadState`]s in the asset's dependency tree.
Failed(Arc<AssetLoadError>),
}
impl DependencyLoadState {
/// Returns `true` if this instance is [`DependencyLoadState::Loading`]
pub fn is_loading(&self) -> bool {
matches!(self, Self::Loading)
}
/// Returns `true` if this instance is [`DependencyLoadState::Loaded`]
pub fn is_loaded(&self) -> bool {
matches!(self, Self::Loaded)
}
/// Returns `true` if this instance is [`DependencyLoadState::Failed`]
pub fn is_failed(&self) -> bool {
matches!(self, Self::Failed(_))
}
}
/// The recursive load state of an asset's dependencies.
#[derive(Component, Clone, Debug, Eq, PartialEq)]
#[derive(Component, Clone, Debug)]
pub enum RecursiveDependencyLoadState {
/// The asset has not started loading yet
NotLoaded,
/// Dependencies in this asset's dependency tree are still loading
Loading,
/// Dependencies in this asset's dependency tree have all loaded
Loaded,
/// One or more dependencies have failed to load in this asset's dependency
/// tree. The underlying [`AssetLoadError`] is referenced by [`Arc`] clones
/// in all related [`LoadState`]s and [`DependencyLoadState`]s in the asset's
@ -1531,8 +1570,25 @@ pub enum RecursiveDependencyLoadState {
Failed(Arc<AssetLoadError>),
}
impl RecursiveDependencyLoadState {
/// Returns `true` if this instance is [`RecursiveDependencyLoadState::Loading`]
pub fn is_loading(&self) -> bool {
matches!(self, Self::Loading)
}
/// Returns `true` if this instance is [`RecursiveDependencyLoadState::Loaded`]
pub fn is_loaded(&self) -> bool {
matches!(self, Self::Loaded)
}
/// Returns `true` if this instance is [`RecursiveDependencyLoadState::Failed`]
pub fn is_failed(&self) -> bool {
matches!(self, Self::Failed(_))
}
}
/// An error that occurs during an [`Asset`] load.
#[derive(Error, Display, Debug, Clone, PartialEq, Eq, From)]
#[derive(Error, Display, Debug, Clone, From)]
pub enum AssetLoadError {
#[display("Requested handle of type {requested:?} for asset '{path}' does not match actual asset type '{actual_asset_name}', which used loader '{loader_name}'")]
RequestedHandleTypeMismatch {
@ -1598,18 +1654,6 @@ pub struct AssetLoaderError {
error: Arc<dyn core::error::Error + Send + Sync + 'static>,
}
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
@ -1622,16 +1666,6 @@ pub struct AddAsyncError {
error: Arc<dyn core::error::Error + Send + Sync + 'static>,
}
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, Display, Debug, Clone, PartialEq, Eq)]
#[display("no `AssetLoader` found{}", format_missing_asset_ext(extensions))]

View file

@ -2516,14 +2516,14 @@ mod test {
app.update();
run_app_until(&mut app, |_world| {
let load_state = asset_server.get_load_state(handle_id).unwrap();
if matches!(load_state, LoadState::Failed(_)) {
if load_state.is_failed() {
Some(())
} else {
None
}
});
let load_state = asset_server.get_load_state(handle_id).unwrap();
assert!(matches!(load_state, LoadState::Failed(_)));
assert!(load_state.is_failed());
}
#[test]
@ -2558,14 +2558,14 @@ mod test {
app.update();
run_app_until(&mut app, |_world| {
let load_state = asset_server.get_load_state(handle_id).unwrap();
if matches!(load_state, LoadState::Failed(_)) {
if load_state.is_failed() {
Some(())
} else {
None
}
});
let load_state = asset_server.get_load_state(handle_id).unwrap();
assert!(matches!(load_state, LoadState::Failed(_)));
assert!(load_state.is_failed());
}
#[test]

View file

@ -1,6 +1,6 @@
//! This example shows how to configure Physically Based Rendering (PBR) parameters.
use bevy::{asset::LoadState, prelude::*, render::camera::ScalingMode};
use bevy::{prelude::*, render::camera::ScalingMode};
fn main() {
App::new()
@ -129,8 +129,12 @@ fn environment_map_load_finish(
label_query: Query<Entity, With<EnvironmentMapLabel>>,
) {
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();

View file

@ -4,7 +4,6 @@
mod camera_controller;
use bevy::{
asset::LoadState,
core_pipeline::Skybox,
prelude::*,
render::{
@ -146,7 +145,7 @@ fn asset_loaded(
mut cubemap: ResMut<Cubemap>,
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,

View file

@ -210,7 +210,7 @@ fn update_loading_data(
let mut pop_list: Vec<usize> = Vec::new();
for (index, asset) in loading_data.loading_assets.iter().enumerate() {
if let Some(state) = asset_server.get_load_states(asset) {
if let bevy::asset::RecursiveDependencyLoadState::Loaded = state.2 {
if state.2.is_loaded() {
pop_list.push(index);
}
}

View file

@ -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<Assets<ArrayTextureMaterial>>,
) {
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;
}

View file

@ -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::*, fmt};
@ -91,7 +90,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!(