Skip to main content

gled_model/asset/animation/config/
float_value.rs

1use crate::{
2    asset::curve::multiplied_curve::{MultipliedCurve, RangeDegrees, RangePercentage},
3    collection::Collections,
4    sound::trigger_ref::{CollectSoundTriggers, SoundLevels, SoundTriggerSet},
5};
6use serde::{Deserialize, Serialize};
7
8#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
9pub enum FloatValue {
10    F32(f32),
11    Percentage(MultipliedCurve<RangePercentage>),
12    Degrees(MultipliedCurve<RangeDegrees>),
13}
14
15impl Eq for FloatValue {}
16
17impl Default for FloatValue {
18    fn default() -> Self {
19        Self::F32(0.0)
20    }
21}
22
23impl FloatValue {
24    pub fn percentage(&mut self) -> &mut MultipliedCurve<RangePercentage> {
25        match self {
26            Self::Percentage(value) => value,
27            _ => {
28                *self = Self::Percentage(Default::default());
29                if let Self::Percentage(value) = self {
30                    value
31                } else {
32                    unreachable!()
33                }
34            }
35        }
36    }
37
38    pub fn degrees(&mut self) -> &mut MultipliedCurve<RangeDegrees> {
39        match self {
40            Self::Degrees(value) => value,
41            _ => {
42                *self = Self::Degrees(Default::default());
43                if let Self::Degrees(value) = self {
44                    value
45                } else {
46                    unreachable!()
47                }
48            }
49        }
50    }
51
52    pub(crate) fn value(
53        &self,
54        beat_progression: f32,
55        collection: &Collections,
56        sound_data: &dyn SoundLevels,
57    ) -> f32 {
58        match self {
59            Self::F32(value) => *value,
60            Self::Percentage(value) => value.value(beat_progression, collection, sound_data),
61            Self::Degrees(value) => value.value(beat_progression, collection, sound_data),
62        }
63    }
64
65    /// The value as a share of its range: degrees over a full turn, the
66    /// others as they are.
67    pub fn normalized_value(
68        &self,
69        beat_progression: f32,
70        collection: &Collections,
71        sound_data: &dyn SoundLevels,
72    ) -> f32 {
73        match self {
74            Self::Degrees(_) => self.value(beat_progression, collection, sound_data) / 360.0,
75            Self::F32(_) | Self::Percentage(_) => {
76                self.value(beat_progression, collection, sound_data)
77            }
78        }
79    }
80
81    /// The setting's own value: the number of a plain value, the multiplier
82    /// of a curve. A controller's fader sets and shows this.
83    pub fn multiplier(&self) -> f32 {
84        match self {
85            Self::F32(value) => *value,
86            Self::Percentage(curve) => curve.multiplier,
87            Self::Degrees(curve) => curve.multiplier,
88        }
89    }
90
91    /// Sets what `multiplier` returns, keeping a curve and its sound trigger.
92    pub fn set_multiplier(&mut self, multiplier: f32) {
93        match self {
94            Self::F32(value) => *value = multiplier,
95            Self::Percentage(curve) => curve.set_multiplier(multiplier),
96            Self::Degrees(curve) => curve.set_multiplier(multiplier),
97        }
98    }
99}
100
101impl CollectSoundTriggers for FloatValue {
102    fn collect_sound_triggers(&self, triggers: &mut SoundTriggerSet) {
103        match self {
104            Self::F32(_) => {}
105            Self::Percentage(value) => value.collect_sound_triggers(triggers),
106            Self::Degrees(value) => value.collect_sound_triggers(triggers),
107        }
108    }
109}
110
111#[cfg(test)]
112mod tests {
113    use super::*;
114    use crate::asset_id::AssetId;
115
116    /// A controller's fader sets the multiplier; the curve the setting
117    /// follows must stay.
118    #[test]
119    fn setting_the_multiplier_keeps_the_curve() {
120        let curve = Some(AssetId::default());
121        let mut inner = MultipliedCurve::new_multiplier(1.0);
122        inner.set_curve(curve);
123        let mut value = FloatValue::Percentage(inner);
124        value.set_multiplier(0.25);
125        assert_eq!(value.multiplier(), 0.25);
126        assert!(matches!(value, FloatValue::Percentage(ref inner) if inner.curve == curve));
127    }
128
129    #[test]
130    fn a_plain_value_is_its_own_multiplier() {
131        let mut value = FloatValue::F32(0.5);
132        value.set_multiplier(0.75);
133        assert_eq!(value, FloatValue::F32(0.75));
134    }
135}