Skip to content

Commit 6b17d95

Browse files
committed
- resovles #15098
- implements consistently named AssertServer methods for asset, dependency, and recursive dependency load states - adds error to DependencyLoadState::Failed and RecursiveDependencyLoadState::Failed
1 parent 5a0c09d commit 6b17d95

File tree

3 files changed

+125
-36
lines changed

3 files changed

+125
-36
lines changed

crates/bevy_asset/src/lib.rs

+28-5
Original file line numberDiff line numberDiff line change
@@ -1095,13 +1095,19 @@ mod tests {
10951095

10961096
assert!(d_text.is_none());
10971097
assert!(matches!(d_load, LoadState::Failed(_)));
1098-
assert_eq!(d_deps, DependencyLoadState::Failed);
1099-
assert_eq!(d_rec_deps, RecursiveDependencyLoadState::Failed);
1098+
assert!(matches!(d_deps, DependencyLoadState::Failed(_)));
1099+
assert!(matches!(
1100+
d_rec_deps,
1101+
RecursiveDependencyLoadState::Failed(_)
1102+
));
11001103

11011104
assert_eq!(a_text.text, "a");
11021105
assert_eq!(a_load, LoadState::Loaded);
11031106
assert_eq!(a_deps, DependencyLoadState::Loaded);
1104-
assert_eq!(a_rec_deps, RecursiveDependencyLoadState::Failed);
1107+
assert!(matches!(
1108+
a_rec_deps,
1109+
RecursiveDependencyLoadState::Failed(_)
1110+
));
11051111

11061112
assert_eq!(b_text.text, "b");
11071113
assert_eq!(b_load, LoadState::Loaded);
@@ -1110,8 +1116,25 @@ mod tests {
11101116

11111117
assert_eq!(c_text.text, "c");
11121118
assert_eq!(c_load, LoadState::Loaded);
1113-
assert_eq!(c_deps, DependencyLoadState::Failed);
1114-
assert_eq!(c_rec_deps, RecursiveDependencyLoadState::Failed);
1119+
assert!(matches!(c_deps, DependencyLoadState::Failed(_)));
1120+
assert!(matches!(
1121+
c_rec_deps,
1122+
RecursiveDependencyLoadState::Failed(_)
1123+
));
1124+
1125+
assert_eq!(asset_server.load_state(a_id), LoadState::Loaded);
1126+
assert_eq!(
1127+
asset_server.dependency_load_state(a_id),
1128+
DependencyLoadState::Loaded
1129+
);
1130+
assert!(matches!(
1131+
asset_server.recursive_dependency_load_state(a_id),
1132+
RecursiveDependencyLoadState::Failed(_)
1133+
));
1134+
1135+
assert!(asset_server.is_loaded(a_id));
1136+
assert!(asset_server.is_loaded_with_dependencies(a_id));
1137+
assert!(!asset_server.is_loaded_with_recursive_dependencies(a_id));
11151138

11161139
Some(())
11171140
});

crates/bevy_asset/src/server/info.rs

+23-14
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,7 @@ impl AssetInfos {
390390
let mut failed_deps = HashSet::new();
391391
let mut loading_rec_deps = loading_deps.clone();
392392
let mut failed_rec_deps = HashSet::new();
393+
let mut first_rec_error = None;
393394
loading_deps.retain(|dep_id| {
394395
if let Some(dep_info) = self.get_mut(*dep_id) {
395396
match dep_info.rec_dep_load_state {
@@ -404,7 +405,10 @@ impl AssetInfos {
404405
// If dependency is loaded, reduce our count by one
405406
loading_rec_deps.remove(dep_id);
406407
}
407-
RecursiveDependencyLoadState::Failed => {
408+
RecursiveDependencyLoadState::Failed(ref error) => {
409+
if first_rec_error.is_none() {
410+
first_rec_error = Some(error.clone());
411+
}
408412
failed_rec_deps.insert(*dep_id);
409413
loading_rec_deps.remove(dep_id);
410414
}
@@ -437,7 +441,7 @@ impl AssetInfos {
437441
let dep_load_state = match (loading_deps.len(), failed_deps.len()) {
438442
(0, 0) => DependencyLoadState::Loaded,
439443
(_loading, 0) => DependencyLoadState::Loading,
440-
(_loading, _failed) => DependencyLoadState::Failed,
444+
(_loading, _failed) => DependencyLoadState::Failed(first_rec_error.clone().unwrap()),
441445
};
442446

443447
let rec_dep_load_state = match (loading_rec_deps.len(), failed_rec_deps.len()) {
@@ -450,7 +454,7 @@ impl AssetInfos {
450454
RecursiveDependencyLoadState::Loaded
451455
}
452456
(_loading, 0) => RecursiveDependencyLoadState::Loading,
453-
(_loading, _failed) => RecursiveDependencyLoadState::Failed,
457+
(_loading, _failed) => RecursiveDependencyLoadState::Failed(first_rec_error.unwrap()),
454458
};
455459

456460
let (dependants_waiting_on_load, dependants_waiting_on_rec_load) = {
@@ -480,14 +484,14 @@ impl AssetInfos {
480484
info.failed_rec_dependencies = failed_rec_deps;
481485
info.load_state = LoadState::Loaded;
482486
info.dep_load_state = dep_load_state;
483-
info.rec_dep_load_state = rec_dep_load_state;
487+
info.rec_dep_load_state = rec_dep_load_state.clone();
484488
if watching_for_changes {
485489
info.loader_dependencies = loaded_asset.loader_dependencies;
486490
}
487491

488492
let dependants_waiting_on_rec_load = if matches!(
489493
rec_dep_load_state,
490-
RecursiveDependencyLoadState::Loaded | RecursiveDependencyLoadState::Failed
494+
RecursiveDependencyLoadState::Loaded | RecursiveDependencyLoadState::Failed(_)
491495
) {
492496
Some(std::mem::take(
493497
&mut info.dependants_waiting_on_recursive_dep_load,
@@ -519,9 +523,9 @@ impl AssetInfos {
519523
Self::propagate_loaded_state(self, loaded_asset_id, dep_id, sender);
520524
}
521525
}
522-
RecursiveDependencyLoadState::Failed => {
526+
RecursiveDependencyLoadState::Failed(error) => {
523527
for dep_id in dependants_waiting_on_rec_load {
524-
Self::propagate_failed_state(self, loaded_asset_id, dep_id);
528+
Self::propagate_failed_state(self, loaded_asset_id, dep_id, &error);
525529
}
526530
}
527531
RecursiveDependencyLoadState::Loading | RecursiveDependencyLoadState::NotLoaded => {
@@ -570,11 +574,12 @@ impl AssetInfos {
570574
infos: &mut AssetInfos,
571575
failed_id: UntypedAssetId,
572576
waiting_id: UntypedAssetId,
577+
error: &Arc<AssetLoadError>,
573578
) {
574579
let dependants_waiting_on_rec_load = if let Some(info) = infos.get_mut(waiting_id) {
575580
info.loading_rec_dependencies.remove(&failed_id);
576581
info.failed_rec_dependencies.insert(failed_id);
577-
info.rec_dep_load_state = RecursiveDependencyLoadState::Failed;
582+
info.rec_dep_load_state = RecursiveDependencyLoadState::Failed(error.clone());
578583
Some(std::mem::take(
579584
&mut info.dependants_waiting_on_recursive_dep_load,
580585
))
@@ -584,7 +589,7 @@ impl AssetInfos {
584589

585590
if let Some(dependants_waiting_on_rec_load) = dependants_waiting_on_rec_load {
586591
for dep_id in dependants_waiting_on_rec_load {
587-
Self::propagate_failed_state(infos, waiting_id, dep_id);
592+
Self::propagate_failed_state(infos, waiting_id, dep_id, error);
588593
}
589594
}
590595
}
@@ -595,14 +600,15 @@ impl AssetInfos {
595600
return;
596601
}
597602

603+
let error = Arc::new(error);
598604
let (dependants_waiting_on_load, dependants_waiting_on_rec_load) = {
599605
let Some(info) = self.get_mut(failed_id) else {
600606
// The asset was already dropped.
601607
return;
602608
};
603-
info.load_state = LoadState::Failed(Box::new(error));
604-
info.dep_load_state = DependencyLoadState::Failed;
605-
info.rec_dep_load_state = RecursiveDependencyLoadState::Failed;
609+
info.load_state = LoadState::Failed(error.clone());
610+
info.dep_load_state = DependencyLoadState::Failed(error.clone());
611+
info.rec_dep_load_state = RecursiveDependencyLoadState::Failed(error.clone());
606612
(
607613
std::mem::take(&mut info.dependants_waiting_on_load),
608614
std::mem::take(&mut info.dependants_waiting_on_recursive_dep_load),
@@ -613,12 +619,15 @@ impl AssetInfos {
613619
if let Some(info) = self.get_mut(waiting_id) {
614620
info.loading_dependencies.remove(&failed_id);
615621
info.failed_dependencies.insert(failed_id);
616-
info.dep_load_state = DependencyLoadState::Failed;
622+
// don't overwrite DependencyLoadState if already failed to preserve first error
623+
if !(matches!(info.dep_load_state, DependencyLoadState::Failed(_))) {
624+
info.dep_load_state = DependencyLoadState::Failed(error.clone());
625+
}
617626
}
618627
}
619628

620629
for waiting_id in dependants_waiting_on_rec_load {
621-
Self::propagate_failed_state(self, failed_id, waiting_id);
630+
Self::propagate_failed_state(self, failed_id, waiting_id, &error);
622631
}
623632
}
624633

crates/bevy_asset/src/server/mod.rs

+74-17
Original file line numberDiff line numberDiff line change
@@ -895,26 +895,49 @@ impl AssetServer {
895895
&self,
896896
id: impl Into<UntypedAssetId>,
897897
) -> Option<(LoadState, DependencyLoadState, RecursiveDependencyLoadState)> {
898+
self.data.infos.read().get(id.into()).map(|i| {
899+
(
900+
i.load_state.clone(),
901+
i.dep_load_state.clone(),
902+
i.rec_dep_load_state.clone(),
903+
)
904+
})
905+
}
906+
907+
/// Retrieves the main [`LoadState`] of a given asset `id`.
908+
///
909+
/// Note that this is "just" the root asset load state. To get the load state of
910+
/// its dependencies or recursive dependencies, see [`AssetServer::get_dependency_load_state`]
911+
/// and [`AssetServer::get_recursive_dependency_load_state`] respectively.
912+
pub fn get_load_state(&self, id: impl Into<UntypedAssetId>) -> Option<LoadState> {
898913
self.data
899914
.infos
900915
.read()
901916
.get(id.into())
902-
.map(|i| (i.load_state.clone(), i.dep_load_state, i.rec_dep_load_state))
917+
.map(|i| i.load_state.clone())
903918
}
904919

905-
/// Retrieves the main [`LoadState`] of a given asset `id`.
920+
/// Retrieves the [`DependencyLoadState`] of a given asset `id`'s dependencies.
906921
///
907-
/// Note that this is "just" the root asset load state. To check if an asset _and_ its recursive
908-
/// dependencies have loaded, see [`AssetServer::is_loaded_with_dependencies`].
909-
pub fn get_load_state(&self, id: impl Into<UntypedAssetId>) -> Option<LoadState> {
922+
/// Note that this is only the load state of direct dependencies of the root asset. To get
923+
/// the load state of the root asset itself or its recursive dependencies, see
924+
/// [`AssetServer::get_load_state`] and [`AssetServer::get_recursive_dependency_load_state`] respectively.
925+
pub fn get_dependency_load_state(
926+
&self,
927+
id: impl Into<UntypedAssetId>,
928+
) -> Option<DependencyLoadState> {
910929
self.data
911930
.infos
912931
.read()
913932
.get(id.into())
914-
.map(|i| i.load_state.clone())
933+
.map(|i| i.dep_load_state.clone())
915934
}
916935

917-
/// Retrieves the [`RecursiveDependencyLoadState`] of a given asset `id`.
936+
/// Retrieves the main [`RecursiveDependencyLoadState`] of a given asset `id`'s recursive dependencies.
937+
///
938+
/// Note that this is only the load state of recursive dependencies of the root asset. To get
939+
/// the load state of the root asset itself or its direct dependencies only, see
940+
/// [`AssetServer::get_load_state`] and [`AssetServer::get_dependency_load_state`] respectively.
918941
pub fn get_recursive_dependency_load_state(
919942
&self,
920943
id: impl Into<UntypedAssetId>,
@@ -923,15 +946,30 @@ impl AssetServer {
923946
.infos
924947
.read()
925948
.get(id.into())
926-
.map(|i| i.rec_dep_load_state)
949+
.map(|i| i.rec_dep_load_state.clone())
927950
}
928951

929952
/// Retrieves the main [`LoadState`] of a given asset `id`.
953+
///
954+
/// This is the same as [`AssetServer::get_load_state`] except the result is unwrapped. If
955+
/// the result is None, [`LoadState::NotLoaded`] is returned.
930956
pub fn load_state(&self, id: impl Into<UntypedAssetId>) -> LoadState {
931957
self.get_load_state(id).unwrap_or(LoadState::NotLoaded)
932958
}
933959

960+
/// Retrieves the [`DependencyLoadState`] of a given asset `id`.
961+
///
962+
/// This is the same as [`AssetServer::get_dependency_load_state`] except the result is unwrapped. If
963+
/// the result is None, [`DependencyLoadState::NotLoaded`] is returned.
964+
pub fn dependency_load_state(&self, id: impl Into<UntypedAssetId>) -> DependencyLoadState {
965+
self.get_dependency_load_state(id)
966+
.unwrap_or(DependencyLoadState::NotLoaded)
967+
}
968+
934969
/// Retrieves the [`RecursiveDependencyLoadState`] of a given asset `id`.
970+
///
971+
/// This is the same as [`AssetServer::get_recursive_dependency_load_state`] except the result is unwrapped. If
972+
/// the result is None, [`RecursiveDependencyLoadState::NotLoaded`] is returned.
935973
pub fn recursive_dependency_load_state(
936974
&self,
937975
id: impl Into<UntypedAssetId>,
@@ -940,11 +978,30 @@ impl AssetServer {
940978
.unwrap_or(RecursiveDependencyLoadState::NotLoaded)
941979
}
942980

943-
/// Returns true if the asset and all of its dependencies (recursive) have been loaded.
981+
/// Convenience method that returns true if the asset has been loaded.
982+
pub fn is_loaded(&self, id: impl Into<UntypedAssetId>) -> bool {
983+
matches!(self.load_state(id), LoadState::Loaded)
984+
}
985+
986+
/// Convenience method that returns true if the asset and all of its direct dependencies have been loaded.
944987
pub fn is_loaded_with_dependencies(&self, id: impl Into<UntypedAssetId>) -> bool {
945-
let id = id.into();
946-
self.load_state(id) == LoadState::Loaded
947-
&& self.recursive_dependency_load_state(id) == RecursiveDependencyLoadState::Loaded
988+
matches!(
989+
self.get_load_states(id),
990+
Some((LoadState::Loaded, DependencyLoadState::Loaded, _))
991+
)
992+
}
993+
994+
/// Convenience method that returns true if the asset, all of its dependencies, and all of its recursive
995+
/// dependencies have been loaded.
996+
pub fn is_loaded_with_recursive_dependencies(&self, id: impl Into<UntypedAssetId>) -> bool {
997+
matches!(
998+
self.get_load_states(id),
999+
Some((
1000+
LoadState::Loaded,
1001+
DependencyLoadState::Loaded,
1002+
RecursiveDependencyLoadState::Loaded
1003+
))
1004+
)
9481005
}
9491006

9501007
/// Returns an active handle for the given path, if the asset at the given path has already started loading,
@@ -1361,11 +1418,11 @@ pub enum LoadState {
13611418
/// The asset has been loaded and has been added to the [`World`]
13621419
Loaded,
13631420
/// The asset failed to load.
1364-
Failed(Box<AssetLoadError>),
1421+
Failed(Arc<AssetLoadError>),
13651422
}
13661423

13671424
/// The load state of an asset's dependencies.
1368-
#[derive(Component, Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
1425+
#[derive(Component, Clone, Debug, Eq, PartialEq)]
13691426
pub enum DependencyLoadState {
13701427
/// The asset has not started loading yet
13711428
NotLoaded,
@@ -1374,11 +1431,11 @@ pub enum DependencyLoadState {
13741431
/// Dependencies have all loaded
13751432
Loaded,
13761433
/// One or more dependencies have failed to load
1377-
Failed,
1434+
Failed(Arc<AssetLoadError>),
13781435
}
13791436

13801437
/// The recursive load state of an asset's dependencies.
1381-
#[derive(Component, Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
1438+
#[derive(Component, Clone, Debug, Eq, PartialEq)]
13821439
pub enum RecursiveDependencyLoadState {
13831440
/// The asset has not started loading yet
13841441
NotLoaded,
@@ -1387,7 +1444,7 @@ pub enum RecursiveDependencyLoadState {
13871444
/// Dependencies in this asset's dependency tree have all loaded
13881445
Loaded,
13891446
/// One or more dependencies have failed to load in this asset's dependency tree
1390-
Failed,
1447+
Failed(Arc<AssetLoadError>),
13911448
}
13921449

13931450
/// An error that occurs during an [`Asset`] load.

0 commit comments

Comments
 (0)