mirror of
https://github.com/bevyengine/bevy
synced 2024-11-13 00:17:27 +00:00
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:
parent
a7e9330af9
commit
93fc2d12cf
9 changed files with 176 additions and 169 deletions
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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!(
|
||||
|
|
Loading…
Reference in a new issue