Add loading state handler, very rough

main
Elijah Voigt 4 months ago
parent bb7794e52a
commit c14f2484e6

@ -27,7 +27,7 @@ fn main() {
control_ball, control_ball,
process_events, process_events,
sync_resource_to_ui::<InsideArea>.run_if(resource_changed::<InsideArea>), sync_resource_to_ui::<InsideArea>.run_if(resource_changed::<InsideArea>),
), ).run_if(in_state(GameState::Main)),
) )
.run(); .run();
} }

@ -9,10 +9,19 @@ impl Plugin for BaseGamePlugin {
.add_plugins(DebuggingPlugin) .add_plugins(DebuggingPlugin)
.add_plugins(MeshPickingPlugin) .add_plugins(MeshPickingPlugin)
.add_plugins(RapierPhysicsPlugin::<NoUserData>::default()) .add_plugins(RapierPhysicsPlugin::<NoUserData>::default())
.add_systems(Startup, setup_camera); .add_plugins(LoadingPlugin)
.add_systems(Startup, setup_camera)
.init_state::<GameState>();
} }
} }
#[derive(States, Clone, PartialEq, Eq, Hash, Debug, Default)]
pub enum GameState {
#[default]
Loading,
Main,
}
/// System to toggle the visibility of entities based on their state /// System to toggle the visibility of entities based on their state
pub fn toggle_state_visibility<S: States + Component>( pub fn toggle_state_visibility<S: States + Component>(
mut q: Query<(Entity, &mut Visibility, &S)>, mut q: Query<(Entity, &mut Visibility, &S)>,

@ -3,12 +3,14 @@
mod base_game; mod base_game;
mod debug; mod debug;
mod loading;
mod scheduling; mod scheduling;
mod ui; mod ui;
pub use std::fmt::Display; pub use std::fmt::Display;
pub use bevy::{ pub use bevy::{
asset::LoadState,
color::palettes::css::{BLACK, RED, WHITE}, color::palettes::css::{BLACK, RED, WHITE},
input::{ButtonState, keyboard::KeyboardInput, mouse::MouseMotion}, input::{ButtonState, keyboard::KeyboardInput, mouse::MouseMotion},
prelude::*, prelude::*,
@ -17,5 +19,6 @@ pub use bevy_rapier3d::prelude::*;
pub use base_game::*; pub use base_game::*;
pub use debug::*; pub use debug::*;
pub use loading::*;
pub use scheduling::*; pub use scheduling::*;
pub use ui::*; pub use ui::*;

@ -0,0 +1,62 @@
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>()
.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(GameState::Loading)),
)
.add_systems(PostUpdate, check_progress);
}
}
/// 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<GameState>>,
) {
if progress.0.iter().all(|x| *x) {
next_state.set(GameState::Main);
}
}
Loading…
Cancel
Save