gled_model/asset/animation/config/
float_value.rs1use 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 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 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 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 #[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}