1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use bevy::{asset::LoadState, prelude::*};
use bevy_kira_audio::{
    prelude::{Audio, AudioSource, Volume},
    AudioControl,
};
use de_conf::Configuration;
use de_core::state::AppState;
use iyes_progress::prelude::*;

pub(crate) struct MusicPlugin;

impl Plugin for MusicPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(OnEnter(AppState::AppLoading), setup)
            .add_systems(
                Update,
                load.track_progress().run_if(in_state(AppState::AppLoading)),
            )
            .add_systems(OnExit(AppState::AppLoading), start);
    }
}

#[derive(Resource)]
struct Tracks(Handle<AudioSource>);

fn setup(mut commands: Commands, server: Res<AssetServer>) {
    commands.insert_resource(Tracks(server.load("audio/music/menu_loop.mp3")));
}

fn load(server: Res<AssetServer>, tracks: Res<Tracks>) -> Progress {
    match server.get_load_state(&tracks.0) {
        Some(LoadState::Loaded) => true.into(),
        Some(LoadState::NotLoaded) | Some(LoadState::Loading) => false.into(),
        _ => panic!("Unexpected loading state."),
    }
}

fn start(audio: Res<Audio>, tracks: Res<Tracks>, config: Res<Configuration>) {
    if !config.audio().music_enabled() {
        return;
    }

    audio
        .play(tracks.0.clone())
        .looped()
        .with_volume(Volume::Amplitude(config.audio().music_volume().into()));
}