Skip to content
Snippets Groups Projects
lib.rs 3.39 KiB
Newer Older
Louis's avatar
Louis committed
//! micro_musicbox provides a convenience wrapper around bevy_kira_audio, handling all the
//! setup for the common game audio scenario. This includes channel management, giving you
//! control of the audio levels for your music, ambiance, sound effects and UI separately
//! from the start.
//!
//! ## Quickstart
//!
//! - Implement `SuppliesAudio` for a resource (or use the built-in impl on `AssetServer`)
//! - Include the MusixBocPlugin plugin, or the CombinedAudioPlugins plugin group in your app, providing your `SuppliesAudio` impl as the generic parameter
//! - Use `MusicBox<T: SuppliesAudio>` as a parameter on a system
//! - Call one of the `MusicBox::play_*` methods to play sounds
//!
//! ```rust
//! # use bevy::prelude::*;
//! # use micro_musicbox::prelude::*;
//! # use micro_musicbox::CombinedAudioPlugins;
//! fn main() {
//!     App::new()
//!         .add_plugins(CombinedAudioPlugins::<AssetServer>::new())
//!         .add_startup_system(|mut music_box: MusicBox<AssetServer>| {
//!             music_box.play_music("music/bing_bong.mp3");
//!         });
//! }
//! ```

Louis's avatar
Louis committed
use std::marker::PhantomData;

use bevy::app::{App, CoreStage, Plugin, PluginGroup, PluginGroupBuilder};
use bevy_kira_audio::{AudioApp, AudioPlugin};

use crate::channels::{
Louis's avatar
Louis committed
	AmbianceAudioChannel, MusicAudioChannel, SfxAudioChannel, UiSfxAudioChannel,
Louis's avatar
Louis committed
use crate::music_box::MusicBoxState;
use crate::utilities::{AudioSettings, SuppliesAudio};
Louis's avatar
Louis committed
/// The available channels that you can play audio on
pub mod channels;
pub mod music_box;
pub mod utilities;

pub mod prelude {
Louis's avatar
Louis committed
	pub use bevy_kira_audio::{
		AudioChannel, AudioControl, AudioEasing, AudioInstance, AudioSettings as KiraAudioSettings,
		AudioSource, AudioTween,
	};

	pub use super::channels::*;
	pub use super::music_box::MusicBox;
Louis's avatar
Louis committed
	pub use super::utilities::AudioSettings;
Louis's avatar
Louis committed
/// A Bevy plugin that sets up all of the audio channels,
/// creates the required settings resources, and configures
/// syncing volume levels for a `MusicBox` that uses the supplied
/// `T` parameter for fetching audio
Louis's avatar
Louis committed
pub struct MusicBoxPlugin<T: SuppliesAudio> {
	_t: PhantomData<T>,
}

impl<T: SuppliesAudio> Default for MusicBoxPlugin<T> {
	fn default() -> Self {
		Self {
			_t: PhantomData::default(),
		}
	}
}

impl<T: SuppliesAudio> MusicBoxPlugin<T> {
Louis's avatar
Louis committed
	/// Create a new MusicBoxPlugin
Louis's avatar
Louis committed
	pub fn new() -> MusicBoxPlugin<T> {
		Default::default()
	}
}
Louis's avatar
Louis committed
impl<T: SuppliesAudio> Plugin for MusicBoxPlugin<T> {
	fn build(&self, app: &mut App) {
Louis's avatar
Louis committed
		app.add_audio_channel::<MusicAudioChannel>()
			.add_audio_channel::<AmbianceAudioChannel>()
			.add_audio_channel::<SfxAudioChannel>()
			.add_audio_channel::<UiSfxAudioChannel>()
			.insert_resource(AudioSettings::default())
Louis's avatar
Louis committed
			.insert_resource(MusicBoxState::default())
			.add_system_to_stage(CoreStage::Last, utilities::sync_music_volume::<T>);
Louis's avatar
Louis committed
/// A Bevy plugin group that adds `bevy_kira_audio` as well as the
/// plugin required to be able to use a `MusicBox`
Louis's avatar
Louis committed
pub struct CombinedAudioPlugins<T: SuppliesAudio> {
	_t: PhantomData<T>,
}

impl<T: SuppliesAudio> Default for CombinedAudioPlugins<T> {
	fn default() -> Self {
		Self {
			_t: PhantomData::default(),
		}
	}
}

impl<T: SuppliesAudio> CombinedAudioPlugins<T> {
	pub fn new() -> CombinedAudioPlugins<T> {
		Default::default()
	}
}

impl<T: SuppliesAudio> PluginGroup for CombinedAudioPlugins<T> {
	fn build(&mut self, group: &mut PluginGroupBuilder) {
Louis's avatar
Louis committed
		group.add(AudioPlugin).add(MusicBoxPlugin::<T>::new());