You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
1.9 KiB
Rust

use super::*;
/// Systems run during loading state
pub struct LoadingPlugin;
impl Plugin for LoadingPlugin {
fn build(&self, app: &mut App) {
// PERF: We check all asset classes every frame, should be event based
app.init_resource::<TrackLoadingProgress>()
.init_state::<LoadingState>()
.add_systems(PreUpdate, reset_progress)
.add_systems(
Update,
(
track_loading::<AnimationClip>,
track_loading::<AudioSource>,
track_loading::<Font>,
track_loading::<Gltf>,
track_loading::<Image>,
track_loading::<Shader>,
)
.run_if(in_state(LoadingState::Active)),
)
.add_systems(PostUpdate, check_progress);
}
}
#[derive(States, Clone, PartialEq, Eq, Hash, Debug, Default)]
pub enum LoadingState {
#[default]
Active,
Idle,
}
/// Resource for tracking asset loading progress
#[derive(Resource, Default)]
struct TrackLoadingProgress(Vec<bool>);
/// At the start of the update clear progress
fn reset_progress(mut progress: ResMut<TrackLoadingProgress>) {
progress.0.clear()
}
/// Track the progress of all assets in this asset class
fn track_loading<A: Asset>(
assets: Res<Assets<A>>,
server: Res<AssetServer>,
mut progress: ResMut<TrackLoadingProgress>,
) {
let all_loaded = assets
.ids()
.map(|id| server.load_state(id))
.all(|load_state| !load_state.is_loading() && !load_state.is_failed());
progress.0.push(all_loaded);
}
/// At the end of the frame check if all asset classes are loaded
fn check_progress(
progress: Res<TrackLoadingProgress>,
mut next_state: ResMut<NextState<LoadingState>>,
) {
if progress.0.iter().all(|x| *x) {
next_state.set(LoadingState::Idle);
}
}