use crate::{AudioSource, Decodable, Volume};
use bevy_asset::{Asset, Handle};
use bevy_ecs::prelude::*;
use bevy_math::Vec3;
use bevy_reflect::prelude::*;
use bevy_transform::components::Transform;
#[derive(Debug, Clone, Copy, Reflect)]
#[reflect(Clone)]
pub enum PlaybackMode {
Once,
Loop,
Despawn,
Remove,
}
#[derive(Component, Clone, Copy, Debug, Reflect)]
#[reflect(Clone, Default, Component, Debug)]
pub struct PlaybackSettings {
pub mode: PlaybackMode,
pub volume: Volume,
pub speed: f32,
pub paused: bool,
pub muted: bool,
pub spatial: bool,
pub spatial_scale: Option<SpatialScale>,
pub start_position: Option<core::time::Duration>,
pub duration: Option<core::time::Duration>,
}
impl Default for PlaybackSettings {
fn default() -> Self {
Self::ONCE
}
}
impl PlaybackSettings {
pub const ONCE: PlaybackSettings = PlaybackSettings {
mode: PlaybackMode::Once,
volume: Volume::Linear(1.0),
speed: 1.0,
paused: false,
muted: false,
spatial: false,
spatial_scale: None,
start_position: None,
duration: None,
};
pub const LOOP: PlaybackSettings = PlaybackSettings {
mode: PlaybackMode::Loop,
..PlaybackSettings::ONCE
};
pub const DESPAWN: PlaybackSettings = PlaybackSettings {
mode: PlaybackMode::Despawn,
..PlaybackSettings::ONCE
};
pub const REMOVE: PlaybackSettings = PlaybackSettings {
mode: PlaybackMode::Remove,
..PlaybackSettings::ONCE
};
pub const fn paused(mut self) -> Self {
self.paused = true;
self
}
pub const fn muted(mut self) -> Self {
self.muted = true;
self
}
pub const fn with_volume(mut self, volume: Volume) -> Self {
self.volume = volume;
self
}
pub const fn with_speed(mut self, speed: f32) -> Self {
self.speed = speed;
self
}
pub const fn with_spatial(mut self, spatial: bool) -> Self {
self.spatial = spatial;
self
}
pub const fn with_spatial_scale(mut self, spatial_scale: SpatialScale) -> Self {
self.spatial_scale = Some(spatial_scale);
self
}
pub const fn with_start_position(mut self, start_position: core::time::Duration) -> Self {
self.start_position = Some(start_position);
self
}
pub const fn with_duration(mut self, duration: core::time::Duration) -> Self {
self.duration = Some(duration);
self
}
}
#[derive(Component, Clone, Debug, Reflect)]
#[require(Transform)]
#[reflect(Clone, Default, Component, Debug)]
pub struct SpatialListener {
pub left_ear_offset: Vec3,
pub right_ear_offset: Vec3,
}
impl Default for SpatialListener {
fn default() -> Self {
Self::new(4.)
}
}
impl SpatialListener {
pub fn new(gap: f32) -> Self {
SpatialListener {
left_ear_offset: Vec3::X * gap / -2.0,
right_ear_offset: Vec3::X * gap / 2.0,
}
}
}
#[derive(Clone, Copy, Debug, Reflect)]
#[reflect(Clone, Default)]
pub struct SpatialScale(pub Vec3);
impl SpatialScale {
pub const fn new(scale: f32) -> Self {
Self(Vec3::splat(scale))
}
pub const fn new_2d(scale: f32) -> Self {
Self(Vec3::new(scale, scale, 0.0))
}
}
impl Default for SpatialScale {
fn default() -> Self {
Self(Vec3::ONE)
}
}
#[derive(Resource, Default, Clone, Copy, Reflect)]
#[reflect(Resource, Default, Clone)]
pub struct DefaultSpatialScale(pub SpatialScale);
#[derive(Component, Reflect)]
#[reflect(Component, Clone)]
#[require(PlaybackSettings)]
pub struct AudioPlayer<Source = AudioSource>(pub Handle<Source>)
where
Source: Asset + Decodable;
impl<Source> Clone for AudioPlayer<Source>
where
Source: Asset + Decodable,
{
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl AudioPlayer<AudioSource> {
pub fn new(source: Handle<AudioSource>) -> Self {
Self(source)
}
}