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::() .init_state::() .add_systems(PreUpdate, reset_progress) .add_systems( Update, ( track_loading::, track_loading::, track_loading::, track_loading::, track_loading::, track_loading::, ) .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); /// At the start of the update clear progress fn reset_progress(mut progress: ResMut) { progress.0.clear() } /// Track the progress of all assets in this asset class fn track_loading( assets: Res>, server: Res, mut progress: ResMut, ) { 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, mut next_state: ResMut>, ) { if progress.0.iter().all(|x| *x) { next_state.set(LoadingState::Idle); } }