use std::marker::PhantomData;
use bevy_asset::prelude::*;
use bevy_asset::{LoadState, UntypedAssetId};
use bevy_ecs::prelude::*;
use bevy_state::state::FreelyMutableState;
use bevy_platform::collections::HashSet;
use crate::prelude::*;
#[derive(SystemSet, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AssetsTrackProgress;
#[derive(Resource)]
pub struct AssetsLoading<S: FreelyMutableState> {
pending: HashSet<UntypedAssetId>,
done: HashSet<UntypedAssetId>,
pub allow_failures: bool,
pub track_dependencies: bool,
_pd: PhantomData<S>,
}
impl<S: FreelyMutableState> Default for AssetsLoading<S> {
fn default() -> Self {
AssetsLoading {
pending: Default::default(),
done: Default::default(),
allow_failures: true,
track_dependencies: true,
_pd: PhantomData,
}
}
}
impl<S: FreelyMutableState> AssetsLoading<S> {
pub fn add<T: Into<UntypedAssetId>>(&mut self, handle: T) {
let asset_id = handle.into();
if !self.done.contains(&asset_id) {
self.pending.insert(asset_id);
}
}
pub fn is_ready(&self) -> bool {
self.pending.is_empty()
}
}
pub(crate) fn assets_progress<S: FreelyMutableState>(
mut loading: ResMut<AssetsLoading<S>>,
server: Res<AssetServer>,
) -> Progress {
let mut any_changed = false;
{
let loading = loading.bypass_change_detection();
loading.pending.retain(|aid| {
let loaded = server.load_state(*aid);
let ready = match loaded {
LoadState::NotLoaded => true,
LoadState::Loading => false,
LoadState::Loaded => {
if loading.track_dependencies {
let loaded_deps =
server.recursive_dependency_load_state(*aid);
if loading.allow_failures && loaded_deps.is_failed() {
true
} else {
loaded_deps.is_loaded()
}
} else {
true
}
}
LoadState::Failed(_) => loading.allow_failures,
};
if ready {
loading.done.insert(*aid);
any_changed = true;
}
!ready
});
}
if any_changed {
loading.set_changed();
}
Progress {
done: loading.done.len() as u32,
total: loading.done.len() as u32 + loading.pending.len() as u32,
}
}
pub fn assets_loading_reset<S: FreelyMutableState>(
mut loading: ResMut<AssetsLoading<S>>,
) {
*loading = AssetsLoading::default();
}