mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
AssetServer LoadState API consistency (#15237)
# Objective - implements consistently named AssertServer methods for asset, dependency, and recursive dependency load states - returns relevant LoadState when required, including error information for failed loads - resolves #15098 ## Solution - implement consistently named LoadState accessor methods: - load_state, dependency_load_state, recursive_dependency_load_state (return unwrapped load states) - get_load_state, get_dependency_load_state, get_recursive_dependency_load_state (return Option) - is_loaded, is_loaded_with_dependencies, is_loaded_with_recursive_dependencies (return bool) - adds AssetLoadError to DependencyLoadState::Failed and RecursiveDependencyLoadState::Failed ## Testing - Added coverage to existing unit tests
This commit is contained in:
parent
106db47f69
commit
612897becd
3 changed files with 245 additions and 42 deletions
|
@ -1246,13 +1246,19 @@ mod tests {
|
||||||
|
|
||||||
assert!(d_text.is_none());
|
assert!(d_text.is_none());
|
||||||
assert!(matches!(d_load, LoadState::Failed(_)));
|
assert!(matches!(d_load, LoadState::Failed(_)));
|
||||||
assert_eq!(d_deps, DependencyLoadState::Failed);
|
assert!(matches!(d_deps, DependencyLoadState::Failed(_)));
|
||||||
assert_eq!(d_rec_deps, RecursiveDependencyLoadState::Failed);
|
assert!(matches!(
|
||||||
|
d_rec_deps,
|
||||||
|
RecursiveDependencyLoadState::Failed(_)
|
||||||
|
));
|
||||||
|
|
||||||
assert_eq!(a_text.text, "a");
|
assert_eq!(a_text.text, "a");
|
||||||
assert_eq!(a_load, LoadState::Loaded);
|
assert_eq!(a_load, LoadState::Loaded);
|
||||||
assert_eq!(a_deps, DependencyLoadState::Loaded);
|
assert_eq!(a_deps, DependencyLoadState::Loaded);
|
||||||
assert_eq!(a_rec_deps, RecursiveDependencyLoadState::Failed);
|
assert!(matches!(
|
||||||
|
a_rec_deps,
|
||||||
|
RecursiveDependencyLoadState::Failed(_)
|
||||||
|
));
|
||||||
|
|
||||||
assert_eq!(b_text.text, "b");
|
assert_eq!(b_text.text, "b");
|
||||||
assert_eq!(b_load, LoadState::Loaded);
|
assert_eq!(b_load, LoadState::Loaded);
|
||||||
|
@ -1261,9 +1267,127 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(c_text.text, "c");
|
assert_eq!(c_text.text, "c");
|
||||||
assert_eq!(c_load, LoadState::Loaded);
|
assert_eq!(c_load, LoadState::Loaded);
|
||||||
assert_eq!(c_deps, DependencyLoadState::Failed);
|
assert!(matches!(c_deps, DependencyLoadState::Failed(_)));
|
||||||
assert_eq!(c_rec_deps, RecursiveDependencyLoadState::Failed);
|
assert!(matches!(
|
||||||
|
c_rec_deps,
|
||||||
|
RecursiveDependencyLoadState::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.is_loaded(a_id));
|
||||||
|
assert!(asset_server.is_loaded_with_direct_dependencies(a_id));
|
||||||
|
assert!(!asset_server.is_loaded_with_dependencies(a_id));
|
||||||
|
|
||||||
|
Some(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dependency_load_states() {
|
||||||
|
// The particular usage of GatedReader in this test will cause deadlocking if running single-threaded
|
||||||
|
#[cfg(not(feature = "multi_threaded"))]
|
||||||
|
panic!("This test requires the \"multi_threaded\" feature, otherwise it will deadlock.\ncargo test --package bevy_asset --features multi_threaded");
|
||||||
|
|
||||||
|
let a_path = "a.cool.ron";
|
||||||
|
let a_ron = r#"
|
||||||
|
(
|
||||||
|
text: "a",
|
||||||
|
dependencies: [
|
||||||
|
"b.cool.ron",
|
||||||
|
"c.cool.ron",
|
||||||
|
],
|
||||||
|
embedded_dependencies: [],
|
||||||
|
sub_texts: []
|
||||||
|
)"#;
|
||||||
|
let b_path = "b.cool.ron";
|
||||||
|
let b_ron = r#"
|
||||||
|
(
|
||||||
|
text: "b",
|
||||||
|
dependencies: [],
|
||||||
|
MALFORMED
|
||||||
|
embedded_dependencies: [],
|
||||||
|
sub_texts: []
|
||||||
|
)"#;
|
||||||
|
|
||||||
|
let c_path = "c.cool.ron";
|
||||||
|
let c_ron = r#"
|
||||||
|
(
|
||||||
|
text: "c",
|
||||||
|
dependencies: [],
|
||||||
|
embedded_dependencies: [],
|
||||||
|
sub_texts: []
|
||||||
|
)"#;
|
||||||
|
|
||||||
|
let dir = Dir::default();
|
||||||
|
dir.insert_asset_text(Path::new(a_path), a_ron);
|
||||||
|
dir.insert_asset_text(Path::new(b_path), b_ron);
|
||||||
|
dir.insert_asset_text(Path::new(c_path), c_ron);
|
||||||
|
|
||||||
|
let (mut app, gate_opener) = test_app(dir);
|
||||||
|
app.init_asset::<CoolText>()
|
||||||
|
.register_asset_loader(CoolTextLoader);
|
||||||
|
let asset_server = app.world().resource::<AssetServer>().clone();
|
||||||
|
let handle: Handle<CoolText> = asset_server.load(a_path);
|
||||||
|
let a_id = handle.id();
|
||||||
|
app.world_mut().spawn(handle);
|
||||||
|
|
||||||
|
gate_opener.open(a_path);
|
||||||
|
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);
|
||||||
|
Some(())
|
||||||
|
});
|
||||||
|
|
||||||
|
gate_opener.open(b_path);
|
||||||
|
run_app_until(&mut app, |world| {
|
||||||
|
let a_text = get::<CoolText>(world, a_id)?;
|
||||||
|
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(_)) {
|
||||||
|
// 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(_)
|
||||||
|
));
|
||||||
|
Some(())
|
||||||
|
});
|
||||||
|
|
||||||
|
gate_opener.open(c_path);
|
||||||
|
run_app_until(&mut app, |world| {
|
||||||
|
let a_text = get::<CoolText>(world, a_id)?;
|
||||||
|
let c_id = a_text.dependencies[1].id();
|
||||||
|
// wait until c loads
|
||||||
|
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!(
|
||||||
|
matches!(a_deps, DependencyLoadState::Failed(_)),
|
||||||
|
"Successful dependency load should not overwrite a previous failure"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
matches!(a_rec_deps, RecursiveDependencyLoadState::Failed(_)),
|
||||||
|
"Successful dependency load should not overwrite a previous failure"
|
||||||
|
);
|
||||||
Some(())
|
Some(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,8 +388,10 @@ impl AssetInfos {
|
||||||
loaded_asset.value.insert(loaded_asset_id, world);
|
loaded_asset.value.insert(loaded_asset_id, world);
|
||||||
let mut loading_deps = loaded_asset.dependencies;
|
let mut loading_deps = loaded_asset.dependencies;
|
||||||
let mut failed_deps = HashSet::new();
|
let mut failed_deps = HashSet::new();
|
||||||
|
let mut dep_error = None;
|
||||||
let mut loading_rec_deps = loading_deps.clone();
|
let mut loading_rec_deps = loading_deps.clone();
|
||||||
let mut failed_rec_deps = HashSet::new();
|
let mut failed_rec_deps = HashSet::new();
|
||||||
|
let mut rec_dep_error = None;
|
||||||
loading_deps.retain(|dep_id| {
|
loading_deps.retain(|dep_id| {
|
||||||
if let Some(dep_info) = self.get_mut(*dep_id) {
|
if let Some(dep_info) = self.get_mut(*dep_id) {
|
||||||
match dep_info.rec_dep_load_state {
|
match dep_info.rec_dep_load_state {
|
||||||
|
@ -404,7 +406,10 @@ impl AssetInfos {
|
||||||
// If dependency is loaded, reduce our count by one
|
// If dependency is loaded, reduce our count by one
|
||||||
loading_rec_deps.remove(dep_id);
|
loading_rec_deps.remove(dep_id);
|
||||||
}
|
}
|
||||||
RecursiveDependencyLoadState::Failed => {
|
RecursiveDependencyLoadState::Failed(ref error) => {
|
||||||
|
if rec_dep_error.is_none() {
|
||||||
|
rec_dep_error = Some(error.clone());
|
||||||
|
}
|
||||||
failed_rec_deps.insert(*dep_id);
|
failed_rec_deps.insert(*dep_id);
|
||||||
loading_rec_deps.remove(dep_id);
|
loading_rec_deps.remove(dep_id);
|
||||||
}
|
}
|
||||||
|
@ -419,7 +424,10 @@ impl AssetInfos {
|
||||||
// If dependency is loaded, reduce our count by one
|
// If dependency is loaded, reduce our count by one
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
LoadState::Failed(_) => {
|
LoadState::Failed(ref error) => {
|
||||||
|
if dep_error.is_none() {
|
||||||
|
dep_error = Some(error.clone());
|
||||||
|
}
|
||||||
failed_deps.insert(*dep_id);
|
failed_deps.insert(*dep_id);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -437,7 +445,7 @@ impl AssetInfos {
|
||||||
let dep_load_state = match (loading_deps.len(), failed_deps.len()) {
|
let dep_load_state = match (loading_deps.len(), failed_deps.len()) {
|
||||||
(0, 0) => DependencyLoadState::Loaded,
|
(0, 0) => DependencyLoadState::Loaded,
|
||||||
(_loading, 0) => DependencyLoadState::Loading,
|
(_loading, 0) => DependencyLoadState::Loading,
|
||||||
(_loading, _failed) => DependencyLoadState::Failed,
|
(_loading, _failed) => DependencyLoadState::Failed(dep_error.unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let rec_dep_load_state = match (loading_rec_deps.len(), failed_rec_deps.len()) {
|
let rec_dep_load_state = match (loading_rec_deps.len(), failed_rec_deps.len()) {
|
||||||
|
@ -450,7 +458,7 @@ impl AssetInfos {
|
||||||
RecursiveDependencyLoadState::Loaded
|
RecursiveDependencyLoadState::Loaded
|
||||||
}
|
}
|
||||||
(_loading, 0) => RecursiveDependencyLoadState::Loading,
|
(_loading, 0) => RecursiveDependencyLoadState::Loading,
|
||||||
(_loading, _failed) => RecursiveDependencyLoadState::Failed,
|
(_loading, _failed) => RecursiveDependencyLoadState::Failed(rec_dep_error.unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (dependants_waiting_on_load, dependants_waiting_on_rec_load) = {
|
let (dependants_waiting_on_load, dependants_waiting_on_rec_load) = {
|
||||||
|
@ -480,14 +488,14 @@ impl AssetInfos {
|
||||||
info.failed_rec_dependencies = failed_rec_deps;
|
info.failed_rec_dependencies = failed_rec_deps;
|
||||||
info.load_state = LoadState::Loaded;
|
info.load_state = LoadState::Loaded;
|
||||||
info.dep_load_state = dep_load_state;
|
info.dep_load_state = dep_load_state;
|
||||||
info.rec_dep_load_state = rec_dep_load_state;
|
info.rec_dep_load_state = rec_dep_load_state.clone();
|
||||||
if watching_for_changes {
|
if watching_for_changes {
|
||||||
info.loader_dependencies = loaded_asset.loader_dependencies;
|
info.loader_dependencies = loaded_asset.loader_dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
let dependants_waiting_on_rec_load = if matches!(
|
let dependants_waiting_on_rec_load = if matches!(
|
||||||
rec_dep_load_state,
|
rec_dep_load_state,
|
||||||
RecursiveDependencyLoadState::Loaded | RecursiveDependencyLoadState::Failed
|
RecursiveDependencyLoadState::Loaded | RecursiveDependencyLoadState::Failed(_)
|
||||||
) {
|
) {
|
||||||
Some(std::mem::take(
|
Some(std::mem::take(
|
||||||
&mut info.dependants_waiting_on_recursive_dep_load,
|
&mut info.dependants_waiting_on_recursive_dep_load,
|
||||||
|
@ -505,7 +513,9 @@ impl AssetInfos {
|
||||||
for id in dependants_waiting_on_load {
|
for id in dependants_waiting_on_load {
|
||||||
if let Some(info) = self.get_mut(id) {
|
if let Some(info) = self.get_mut(id) {
|
||||||
info.loading_dependencies.remove(&loaded_asset_id);
|
info.loading_dependencies.remove(&loaded_asset_id);
|
||||||
if info.loading_dependencies.is_empty() {
|
if info.loading_dependencies.is_empty()
|
||||||
|
&& !matches!(info.dep_load_state, DependencyLoadState::Failed(_))
|
||||||
|
{
|
||||||
// send dependencies loaded event
|
// send dependencies loaded event
|
||||||
info.dep_load_state = DependencyLoadState::Loaded;
|
info.dep_load_state = DependencyLoadState::Loaded;
|
||||||
}
|
}
|
||||||
|
@ -519,9 +529,9 @@ impl AssetInfos {
|
||||||
Self::propagate_loaded_state(self, loaded_asset_id, dep_id, sender);
|
Self::propagate_loaded_state(self, loaded_asset_id, dep_id, sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RecursiveDependencyLoadState::Failed => {
|
RecursiveDependencyLoadState::Failed(ref error) => {
|
||||||
for dep_id in dependants_waiting_on_rec_load {
|
for dep_id in dependants_waiting_on_rec_load {
|
||||||
Self::propagate_failed_state(self, loaded_asset_id, dep_id);
|
Self::propagate_failed_state(self, loaded_asset_id, dep_id, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RecursiveDependencyLoadState::Loading | RecursiveDependencyLoadState::NotLoaded => {
|
RecursiveDependencyLoadState::Loading | RecursiveDependencyLoadState::NotLoaded => {
|
||||||
|
@ -570,11 +580,12 @@ impl AssetInfos {
|
||||||
infos: &mut AssetInfos,
|
infos: &mut AssetInfos,
|
||||||
failed_id: UntypedAssetId,
|
failed_id: UntypedAssetId,
|
||||||
waiting_id: UntypedAssetId,
|
waiting_id: UntypedAssetId,
|
||||||
|
error: &Arc<AssetLoadError>,
|
||||||
) {
|
) {
|
||||||
let dependants_waiting_on_rec_load = if let Some(info) = infos.get_mut(waiting_id) {
|
let dependants_waiting_on_rec_load = if let Some(info) = infos.get_mut(waiting_id) {
|
||||||
info.loading_rec_dependencies.remove(&failed_id);
|
info.loading_rec_dependencies.remove(&failed_id);
|
||||||
info.failed_rec_dependencies.insert(failed_id);
|
info.failed_rec_dependencies.insert(failed_id);
|
||||||
info.rec_dep_load_state = RecursiveDependencyLoadState::Failed;
|
info.rec_dep_load_state = RecursiveDependencyLoadState::Failed(error.clone());
|
||||||
Some(std::mem::take(
|
Some(std::mem::take(
|
||||||
&mut info.dependants_waiting_on_recursive_dep_load,
|
&mut info.dependants_waiting_on_recursive_dep_load,
|
||||||
))
|
))
|
||||||
|
@ -584,7 +595,7 @@ impl AssetInfos {
|
||||||
|
|
||||||
if let Some(dependants_waiting_on_rec_load) = dependants_waiting_on_rec_load {
|
if let Some(dependants_waiting_on_rec_load) = dependants_waiting_on_rec_load {
|
||||||
for dep_id in dependants_waiting_on_rec_load {
|
for dep_id in dependants_waiting_on_rec_load {
|
||||||
Self::propagate_failed_state(infos, waiting_id, dep_id);
|
Self::propagate_failed_state(infos, waiting_id, dep_id, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,14 +606,15 @@ impl AssetInfos {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let error = Arc::new(error);
|
||||||
let (dependants_waiting_on_load, dependants_waiting_on_rec_load) = {
|
let (dependants_waiting_on_load, dependants_waiting_on_rec_load) = {
|
||||||
let Some(info) = self.get_mut(failed_id) else {
|
let Some(info) = self.get_mut(failed_id) else {
|
||||||
// The asset was already dropped.
|
// The asset was already dropped.
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
info.load_state = LoadState::Failed(Box::new(error));
|
info.load_state = LoadState::Failed(error.clone());
|
||||||
info.dep_load_state = DependencyLoadState::Failed;
|
info.dep_load_state = DependencyLoadState::Failed(error.clone());
|
||||||
info.rec_dep_load_state = RecursiveDependencyLoadState::Failed;
|
info.rec_dep_load_state = RecursiveDependencyLoadState::Failed(error.clone());
|
||||||
(
|
(
|
||||||
std::mem::take(&mut info.dependants_waiting_on_load),
|
std::mem::take(&mut info.dependants_waiting_on_load),
|
||||||
std::mem::take(&mut info.dependants_waiting_on_recursive_dep_load),
|
std::mem::take(&mut info.dependants_waiting_on_recursive_dep_load),
|
||||||
|
@ -613,12 +625,15 @@ impl AssetInfos {
|
||||||
if let Some(info) = self.get_mut(waiting_id) {
|
if let Some(info) = self.get_mut(waiting_id) {
|
||||||
info.loading_dependencies.remove(&failed_id);
|
info.loading_dependencies.remove(&failed_id);
|
||||||
info.failed_dependencies.insert(failed_id);
|
info.failed_dependencies.insert(failed_id);
|
||||||
info.dep_load_state = DependencyLoadState::Failed;
|
// don't overwrite DependencyLoadState if already failed to preserve first error
|
||||||
|
if !(matches!(info.dep_load_state, DependencyLoadState::Failed(_))) {
|
||||||
|
info.dep_load_state = DependencyLoadState::Failed(error.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for waiting_id in dependants_waiting_on_rec_load {
|
for waiting_id in dependants_waiting_on_rec_load {
|
||||||
Self::propagate_failed_state(self, failed_id, waiting_id);
|
Self::propagate_failed_state(self, failed_id, waiting_id, &error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -898,17 +898,20 @@ impl AssetServer {
|
||||||
&self,
|
&self,
|
||||||
id: impl Into<UntypedAssetId>,
|
id: impl Into<UntypedAssetId>,
|
||||||
) -> Option<(LoadState, DependencyLoadState, RecursiveDependencyLoadState)> {
|
) -> Option<(LoadState, DependencyLoadState, RecursiveDependencyLoadState)> {
|
||||||
self.data
|
self.data.infos.read().get(id.into()).map(|i| {
|
||||||
.infos
|
(
|
||||||
.read()
|
i.load_state.clone(),
|
||||||
.get(id.into())
|
i.dep_load_state.clone(),
|
||||||
.map(|i| (i.load_state.clone(), i.dep_load_state, i.rec_dep_load_state))
|
i.rec_dep_load_state.clone(),
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the main [`LoadState`] of a given asset `id`.
|
/// Retrieves the main [`LoadState`] of a given asset `id`.
|
||||||
///
|
///
|
||||||
/// Note that this is "just" the root asset load state. To check if an asset _and_ its recursive
|
/// Note that this is "just" the root asset load state. To get the load state of
|
||||||
/// dependencies have loaded, see [`AssetServer::is_loaded_with_dependencies`].
|
/// its dependencies or recursive dependencies, see [`AssetServer::get_dependency_load_state`]
|
||||||
|
/// and [`AssetServer::get_recursive_dependency_load_state`] respectively.
|
||||||
pub fn get_load_state(&self, id: impl Into<UntypedAssetId>) -> Option<LoadState> {
|
pub fn get_load_state(&self, id: impl Into<UntypedAssetId>) -> Option<LoadState> {
|
||||||
self.data
|
self.data
|
||||||
.infos
|
.infos
|
||||||
|
@ -917,7 +920,27 @@ impl AssetServer {
|
||||||
.map(|i| i.load_state.clone())
|
.map(|i| i.load_state.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the [`RecursiveDependencyLoadState`] of a given asset `id`.
|
/// Retrieves the [`DependencyLoadState`] of a given asset `id`'s dependencies.
|
||||||
|
///
|
||||||
|
/// Note that this is only the load state of direct dependencies of the root asset. To get
|
||||||
|
/// the load state of the root asset itself or its recursive dependencies, see
|
||||||
|
/// [`AssetServer::get_load_state`] and [`AssetServer::get_recursive_dependency_load_state`] respectively.
|
||||||
|
pub fn get_dependency_load_state(
|
||||||
|
&self,
|
||||||
|
id: impl Into<UntypedAssetId>,
|
||||||
|
) -> Option<DependencyLoadState> {
|
||||||
|
self.data
|
||||||
|
.infos
|
||||||
|
.read()
|
||||||
|
.get(id.into())
|
||||||
|
.map(|i| i.dep_load_state.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves the main [`RecursiveDependencyLoadState`] of a given asset `id`'s recursive dependencies.
|
||||||
|
///
|
||||||
|
/// Note that this is only the load state of recursive dependencies of the root asset. To get
|
||||||
|
/// the load state of the root asset itself or its direct dependencies only, see
|
||||||
|
/// [`AssetServer::get_load_state`] and [`AssetServer::get_dependency_load_state`] respectively.
|
||||||
pub fn get_recursive_dependency_load_state(
|
pub fn get_recursive_dependency_load_state(
|
||||||
&self,
|
&self,
|
||||||
id: impl Into<UntypedAssetId>,
|
id: impl Into<UntypedAssetId>,
|
||||||
|
@ -926,15 +949,30 @@ impl AssetServer {
|
||||||
.infos
|
.infos
|
||||||
.read()
|
.read()
|
||||||
.get(id.into())
|
.get(id.into())
|
||||||
.map(|i| i.rec_dep_load_state)
|
.map(|i| i.rec_dep_load_state.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the main [`LoadState`] of a given asset `id`.
|
/// Retrieves the main [`LoadState`] of a given asset `id`.
|
||||||
|
///
|
||||||
|
/// This is the same as [`AssetServer::get_load_state`] except the result is unwrapped. If
|
||||||
|
/// the result is None, [`LoadState::NotLoaded`] is returned.
|
||||||
pub fn load_state(&self, id: impl Into<UntypedAssetId>) -> LoadState {
|
pub fn load_state(&self, id: impl Into<UntypedAssetId>) -> LoadState {
|
||||||
self.get_load_state(id).unwrap_or(LoadState::NotLoaded)
|
self.get_load_state(id).unwrap_or(LoadState::NotLoaded)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieves the [`DependencyLoadState`] of a given asset `id`.
|
||||||
|
///
|
||||||
|
/// This is the same as [`AssetServer::get_dependency_load_state`] except the result is unwrapped. If
|
||||||
|
/// the result is None, [`DependencyLoadState::NotLoaded`] is returned.
|
||||||
|
pub fn dependency_load_state(&self, id: impl Into<UntypedAssetId>) -> DependencyLoadState {
|
||||||
|
self.get_dependency_load_state(id)
|
||||||
|
.unwrap_or(DependencyLoadState::NotLoaded)
|
||||||
|
}
|
||||||
|
|
||||||
/// Retrieves the [`RecursiveDependencyLoadState`] of a given asset `id`.
|
/// Retrieves the [`RecursiveDependencyLoadState`] of a given asset `id`.
|
||||||
|
///
|
||||||
|
/// This is the same as [`AssetServer::get_recursive_dependency_load_state`] except the result is unwrapped. If
|
||||||
|
/// the result is None, [`RecursiveDependencyLoadState::NotLoaded`] is returned.
|
||||||
pub fn recursive_dependency_load_state(
|
pub fn recursive_dependency_load_state(
|
||||||
&self,
|
&self,
|
||||||
id: impl Into<UntypedAssetId>,
|
id: impl Into<UntypedAssetId>,
|
||||||
|
@ -943,11 +981,30 @@ impl AssetServer {
|
||||||
.unwrap_or(RecursiveDependencyLoadState::NotLoaded)
|
.unwrap_or(RecursiveDependencyLoadState::NotLoaded)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the asset and all of its dependencies (recursive) have been loaded.
|
/// Convenience method that returns true if the asset has been loaded.
|
||||||
|
pub fn is_loaded(&self, id: impl Into<UntypedAssetId>) -> bool {
|
||||||
|
matches!(self.load_state(id), LoadState::Loaded)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience method that returns true if the asset and all of its direct dependencies have been loaded.
|
||||||
|
pub fn is_loaded_with_direct_dependencies(&self, id: impl Into<UntypedAssetId>) -> bool {
|
||||||
|
matches!(
|
||||||
|
self.get_load_states(id),
|
||||||
|
Some((LoadState::Loaded, DependencyLoadState::Loaded, _))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience method that returns true if the asset, all of its dependencies, and all of its recursive
|
||||||
|
/// dependencies have been loaded.
|
||||||
pub fn is_loaded_with_dependencies(&self, id: impl Into<UntypedAssetId>) -> bool {
|
pub fn is_loaded_with_dependencies(&self, id: impl Into<UntypedAssetId>) -> bool {
|
||||||
let id = id.into();
|
matches!(
|
||||||
self.load_state(id) == LoadState::Loaded
|
self.get_load_states(id),
|
||||||
&& self.recursive_dependency_load_state(id) == RecursiveDependencyLoadState::Loaded
|
Some((
|
||||||
|
LoadState::Loaded,
|
||||||
|
DependencyLoadState::Loaded,
|
||||||
|
RecursiveDependencyLoadState::Loaded
|
||||||
|
))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an active handle for the given path, if the asset at the given path has already started loading,
|
/// Returns an active handle for the given path, if the asset at the given path has already started loading,
|
||||||
|
@ -1363,12 +1420,14 @@ pub enum LoadState {
|
||||||
Loading,
|
Loading,
|
||||||
/// The asset has been loaded and has been added to the [`World`]
|
/// The asset has been loaded and has been added to the [`World`]
|
||||||
Loaded,
|
Loaded,
|
||||||
/// The asset failed to load.
|
/// The asset failed to load. The underlying [`AssetLoadError`] is
|
||||||
Failed(Box<AssetLoadError>),
|
/// referenced by [`Arc`] clones in all related [`DependencyLoadState`]s
|
||||||
|
/// and [`RecursiveDependencyLoadState`]s in the asset's dependency tree.
|
||||||
|
Failed(Arc<AssetLoadError>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The load state of an asset's dependencies.
|
/// The load state of an asset's dependencies.
|
||||||
#[derive(Component, Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Component, Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum DependencyLoadState {
|
pub enum DependencyLoadState {
|
||||||
/// The asset has not started loading yet
|
/// The asset has not started loading yet
|
||||||
NotLoaded,
|
NotLoaded,
|
||||||
|
@ -1376,12 +1435,14 @@ pub enum DependencyLoadState {
|
||||||
Loading,
|
Loading,
|
||||||
/// Dependencies have all loaded
|
/// Dependencies have all loaded
|
||||||
Loaded,
|
Loaded,
|
||||||
/// One or more dependencies have failed to load
|
/// One or more dependencies have failed to load. The underlying [`AssetLoadError`]
|
||||||
Failed,
|
/// is referenced by [`Arc`] clones in all related [`LoadState`] and
|
||||||
|
/// [`RecursiveDependencyLoadState`]s in the asset's dependency tree.
|
||||||
|
Failed(Arc<AssetLoadError>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The recursive load state of an asset's dependencies.
|
/// The recursive load state of an asset's dependencies.
|
||||||
#[derive(Component, Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Component, Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum RecursiveDependencyLoadState {
|
pub enum RecursiveDependencyLoadState {
|
||||||
/// The asset has not started loading yet
|
/// The asset has not started loading yet
|
||||||
NotLoaded,
|
NotLoaded,
|
||||||
|
@ -1389,8 +1450,11 @@ pub enum RecursiveDependencyLoadState {
|
||||||
Loading,
|
Loading,
|
||||||
/// Dependencies in this asset's dependency tree have all loaded
|
/// Dependencies in this asset's dependency tree have all loaded
|
||||||
Loaded,
|
Loaded,
|
||||||
/// One or more dependencies have failed to load in this asset's dependency tree
|
/// One or more dependencies have failed to load in this asset's dependency
|
||||||
Failed,
|
/// tree. The underlying [`AssetLoadError`] is referenced by [`Arc`] clones
|
||||||
|
/// in all related [`LoadState`]s and [`DependencyLoadState`]s in the asset's
|
||||||
|
/// dependency tree.
|
||||||
|
Failed(Arc<AssetLoadError>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An error that occurs during an [`Asset`] load.
|
/// An error that occurs during an [`Asset`] load.
|
||||||
|
|
Loading…
Reference in a new issue