use std::time::Duration;
use bevy::audio::{PlaybackMode, PlaybackSettings};
use pybevy_core::{ComponentStorage, PyComponent};
use pybevy_macros::component_storage;
use pyo3::prelude::*;
use crate::{PyPlaybackMode, PySpatialScale, PyVolume};
#[component_storage(PlaybackSettings)]
#[pyclass(name = "PlaybackSettings", extends = PyComponent)]
#[derive(Clone)]
pub struct PyPlaybackSettings {
pub(crate) storage: ComponentStorage<PlaybackSettings>,
}
#[pymethods]
impl PyPlaybackSettings {
#[new]
#[pyo3(signature = (
*,
mode = None,
volume = None,
speed = 1.0,
paused = false,
muted = false,
spatial = false,
start_position = None,
duration = None,
spatial_scale = None,
))]
pub fn new(
mode: Option<PyPlaybackMode>,
volume: Option<PyVolume>,
speed: f32,
paused: bool,
muted: bool,
spatial: bool,
start_position: Option<Duration>,
duration: Option<Duration>,
spatial_scale: Option<PySpatialScale>,
) -> (Self, PyComponent) {
let settings = PlaybackSettings {
mode: mode.map(Into::into).unwrap_or(PlaybackMode::Once),
volume: volume.map(Into::into).unwrap_or_default(),
speed,
paused,
muted,
spatial,
start_position,
duration,
spatial_scale: spatial_scale.map(|s| s.inner),
};
Self::from_owned(settings)
}
#[staticmethod]
#[pyo3(name = "ONCE")]
pub fn once(py: Python) -> PyResult<Py<PyPlaybackSettings>> {
Py::new(py, Self::from_owned(PlaybackSettings::ONCE))
}
#[staticmethod]
#[pyo3(name = "LOOP")]
pub fn loop_settings(py: Python) -> PyResult<Py<PyPlaybackSettings>> {
Py::new(py, Self::from_owned(PlaybackSettings::LOOP))
}
#[staticmethod]
#[pyo3(name = "DESPAWN")]
pub fn despawn(py: Python) -> PyResult<Py<PyPlaybackSettings>> {
Py::new(py, Self::from_owned(PlaybackSettings::DESPAWN))
}
#[staticmethod]
#[pyo3(name = "REMOVE")]
pub fn remove(py: Python) -> PyResult<Py<PyPlaybackSettings>> {
Py::new(py, Self::from_owned(PlaybackSettings::REMOVE))
}
#[getter]
pub fn mode(&self) -> PyResult<PyPlaybackMode> {
Ok(self.as_ref()?.mode.into())
}
#[setter]
pub fn set_mode(&mut self, mode: PyPlaybackMode) -> PyResult<()> {
self.as_mut()?.mode = mode.into();
Ok(())
}
#[getter]
pub fn volume(&self) -> PyResult<PyVolume> {
Ok(self.as_ref()?.volume.into())
}
#[setter]
pub fn set_volume(&mut self, volume: PyVolume) -> PyResult<()> {
self.as_mut()?.volume = volume.into();
Ok(())
}
#[getter]
pub fn speed(&self) -> PyResult<f32> {
Ok(self.as_ref()?.speed)
}
#[setter]
pub fn set_speed(&mut self, speed: f32) -> PyResult<()> {
self.as_mut()?.speed = speed;
Ok(())
}
#[getter]
pub fn paused(&self) -> PyResult<bool> {
Ok(self.as_ref()?.paused)
}
#[setter]
pub fn set_paused(&mut self, paused: bool) -> PyResult<()> {
self.as_mut()?.paused = paused;
Ok(())
}
#[getter]
pub fn muted(&self) -> PyResult<bool> {
Ok(self.as_ref()?.muted)
}
#[setter]
pub fn set_muted(&mut self, muted: bool) -> PyResult<()> {
self.as_mut()?.muted = muted;
Ok(())
}
#[getter]
pub fn spatial(&self) -> PyResult<bool> {
Ok(self.as_ref()?.spatial)
}
#[setter]
pub fn set_spatial(&mut self, spatial: bool) -> PyResult<()> {
self.as_mut()?.spatial = spatial;
Ok(())
}
#[getter]
pub fn start_position(&self) -> PyResult<Option<Duration>> {
Ok(self.as_ref()?.start_position)
}
#[setter]
pub fn set_start_position(&mut self, pos: Option<Duration>) -> PyResult<()> {
self.as_mut()?.start_position = pos;
Ok(())
}
#[getter]
pub fn duration(&self) -> PyResult<Option<Duration>> {
Ok(self.as_ref()?.duration)
}
#[setter]
pub fn set_duration(&mut self, duration: Option<Duration>) -> PyResult<()> {
self.as_mut()?.duration = duration;
Ok(())
}
#[getter]
pub fn spatial_scale(&self) -> PyResult<Option<PySpatialScale>> {
Ok(self.as_ref()?.spatial_scale.map(|s| s.into()))
}
#[setter]
pub fn set_spatial_scale(&mut self, scale: Option<PySpatialScale>) -> PyResult<()> {
self.as_mut()?.spatial_scale = scale.map(|s| s.inner);
Ok(())
}
#[pyo3(name = "with_volume")]
pub fn with_volume(slf: Py<Self>, py: Python, volume: PyVolume) -> PyResult<Py<Self>> {
slf.borrow_mut(py).as_mut()?.volume = volume.into();
Ok(slf)
}
#[pyo3(name = "with_speed")]
pub fn with_speed(slf: Py<Self>, py: Python, speed: f32) -> PyResult<Py<Self>> {
slf.borrow_mut(py).as_mut()?.speed = speed;
Ok(slf)
}
#[pyo3(name = "with_spatial")]
pub fn with_spatial(slf: Py<Self>, py: Python, spatial: bool) -> PyResult<Py<Self>> {
slf.borrow_mut(py).as_mut()?.spatial = spatial;
Ok(slf)
}
#[pyo3(name = "with_start_position")]
pub fn with_start_position(
slf: Py<Self>,
py: Python,
start_position: Duration,
) -> PyResult<Py<Self>> {
slf.borrow_mut(py).as_mut()?.start_position = Some(start_position);
Ok(slf)
}
#[pyo3(name = "with_duration")]
pub fn with_duration(slf: Py<Self>, py: Python, duration: Duration) -> PyResult<Py<Self>> {
slf.borrow_mut(py).as_mut()?.duration = Some(duration);
Ok(slf)
}
#[pyo3(name = "with_spatial_scale")]
pub fn with_spatial_scale(
slf: Py<Self>,
py: Python,
spatial_scale: PySpatialScale,
) -> PyResult<Py<Self>> {
slf.borrow_mut(py).as_mut()?.spatial_scale = Some(spatial_scale.inner);
Ok(slf)
}
fn __repr__(&self) -> String {
match self.as_ref() {
Ok(settings) => format!(
"PlaybackSettings(mode={:?}, volume={:?}, speed={}, paused={}, muted={}, spatial={})",
settings.mode,
settings.volume,
settings.speed,
settings.paused,
settings.muted,
settings.spatial
),
Err(_) => "PlaybackSettings(<invalid>)".to_string(),
}
}
}