use crate::{
asset::curve::multiplied_curve::{MultipliedCurve, RangeDegrees, RangePercentage},
collection::Collections,
sound::trigger_ref::{CollectSoundTriggers, SoundLevels, SoundTriggerSet},
};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub enum FloatValue {
F32(f32),
Percentage(MultipliedCurve<RangePercentage>),
Degrees(MultipliedCurve<RangeDegrees>),
}
impl Eq for FloatValue {}
impl Default for FloatValue {
fn default() -> Self {
Self::F32(0.0)
}
}
impl FloatValue {
pub fn percentage(&mut self) -> &mut MultipliedCurve<RangePercentage> {
match self {
Self::Percentage(value) => value,
_ => {
*self = Self::Percentage(Default::default());
if let Self::Percentage(value) = self {
value
} else {
unreachable!()
}
}
}
}
pub fn degrees(&mut self) -> &mut MultipliedCurve<RangeDegrees> {
match self {
Self::Degrees(value) => value,
_ => {
*self = Self::Degrees(Default::default());
if let Self::Degrees(value) = self {
value
} else {
unreachable!()
}
}
}
}
pub(crate) fn value(
&self,
beat_progression: f32,
collection: &Collections,
sound_data: &dyn SoundLevels,
) -> f32 {
match self {
Self::F32(value) => *value,
Self::Percentage(value) => value.value(beat_progression, collection, sound_data),
Self::Degrees(value) => value.value(beat_progression, collection, sound_data),
}
}
pub fn normalized_value(
&self,
beat_progression: f32,
collection: &Collections,
sound_data: &dyn SoundLevels,
) -> f32 {
match self {
Self::Degrees(_) => self.value(beat_progression, collection, sound_data) / 360.0,
Self::F32(_) | Self::Percentage(_) => {
self.value(beat_progression, collection, sound_data)
}
}
}
pub fn multiplier(&self) -> f32 {
match self {
Self::F32(value) => *value,
Self::Percentage(curve) => curve.multiplier,
Self::Degrees(curve) => curve.multiplier,
}
}
pub fn set_multiplier(&mut self, multiplier: f32) {
match self {
Self::F32(value) => *value = multiplier,
Self::Percentage(curve) => curve.set_multiplier(multiplier),
Self::Degrees(curve) => curve.set_multiplier(multiplier),
}
}
}
impl CollectSoundTriggers for FloatValue {
fn collect_sound_triggers(&self, triggers: &mut SoundTriggerSet) {
match self {
Self::F32(_) => {}
Self::Percentage(value) => value.collect_sound_triggers(triggers),
Self::Degrees(value) => value.collect_sound_triggers(triggers),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::asset_id::AssetId;
#[test]
fn setting_the_multiplier_keeps_the_curve() {
let curve = Some(AssetId::default());
let mut inner = MultipliedCurve::new_multiplier(1.0);
inner.set_curve(curve);
let mut value = FloatValue::Percentage(inner);
value.set_multiplier(0.25);
assert_eq!(value.multiplier(), 0.25);
assert!(matches!(value, FloatValue::Percentage(ref inner) if inner.curve == curve));
}
#[test]
fn a_plain_value_is_its_own_multiplier() {
let mut value = FloatValue::F32(0.5);
value.set_multiplier(0.75);
assert_eq!(value, FloatValue::F32(0.75));
}
}