Skip to content
Snippets Groups Projects
mod.rs 3.2 KiB
Newer Older
Louis's avatar
Louis committed
use bevy::app::Plugin;
use bevy::asset::{Handle, LoadState};
use bevy::ecs::schedule::ShouldRun;
use bevy::prelude::*;
use bevy_kira_audio::AudioSource;

/// We store our asset handles in this to avoid Bevy from dropping the assets and reloading
/// when we switch tracks
pub struct AudioResources {
	pub white_kitty: Handle<AudioSource>,
	pub great_madeja: Handle<AudioSource>,
}

#[derive(Default, Eq, PartialEq, Debug, Clone, Hash)]
pub enum AppState {
	#[default]
	Loading,
	Running,
}

pub fn load_resources(mut commands: Commands, assets: Res<AssetServer>) {
	let white_kitty = assets.load("The-White-Kitty.mp3");
	let great_madeja = assets.load("The-Great-Madeja.mp3");

	commands.insert_resource(AudioResources {
		white_kitty,
		great_madeja,
	})
}

pub fn check_load_state(
	assets: Res<AssetServer>,
	resources: Res<AudioResources>,
	mut appstate: ResMut<State<AppState>>,
) {
	let load_state =
		assets.get_group_load_state(vec![resources.white_kitty.id, resources.great_madeja.id]);

	match load_state {
		LoadState::Loaded => {
			appstate.set(AppState::Running);
		}
		LoadState::Loading => {}
		_ => {
			log::error!("The resources are in a bad state! This is a problem");
		}
	}
}

pub fn has_audio_resources(res: Option<Res<AudioResources>>) -> ShouldRun {
	res.is_some().into()
}
pub fn is_state_loading(state: Res<AppState>) -> ShouldRun {
	(*state == AppState::Loading).into()
}
pub fn is_state_running(state: Res<AppState>) -> ShouldRun {
	(*state == AppState::Running).into()
}

/// This component allows us to easily grab the on screen text
#[derive(Component)]
pub struct TextMarker;
/// This component allows us to easily grab the blank details text area
#[derive(Component)]
pub struct DetailsMarker;

pub fn create_ui(mut commands: Commands, assets: Res<AssetServer>) {
	commands.spawn_bundle(Camera2dBundle::default());
	commands
		.spawn_bundle(NodeBundle {
			style: Style {
				size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
				justify_content: JustifyContent::Center,
				align_items: AlignItems::Center,
				flex_direction: FlexDirection::Column,
				..Default::default()
			},
			..Default::default()
		})
		.with_children(|children| {
			children
				.spawn_bundle(TextBundle {
					text: Text::from_section(
						"Loading Audio Tracks",
						TextStyle {
							color: Color::BLACK,
							font_size: 48.0,
							font: assets.load("KenneyBlocks.ttf"),
						},
					),
					..Default::default()
				})
				.insert(TextMarker);
			children
				.spawn_bundle(TextBundle {
					text: Text::from_section(
						"...",
						TextStyle {
							color: Color::BLACK,
							font_size: 32.0,
							font: assets.load("KenneyBlocks.ttf"),
						},
					),
					..Default::default()
				})
				.insert(DetailsMarker);
		});
}

pub struct SetupPlugin;
impl Plugin for SetupPlugin {
	fn build(&self, app: &mut App) {
		app.add_state(AppState::Loading)
			.insert_resource(WindowDescriptor {
				width: 800.0,
				height: 600.0,
				title: String::from("Kitchen Sink Example"),
				..Default::default()
			})
			.add_startup_system(load_resources)
			.add_startup_system(create_ui)
			.add_system_set(
				SystemSet::on_update(AppState::Loading)
					.with_run_criteria(has_audio_resources)
					.with_system(check_load_state),
			);
	}
}