1use crate::{
11 core_item::{AnyExtractCoreItem, CoreItem, DynItem},
12 utils::rate_functions::linear,
13};
14
15use std::fmt::Debug;
16
17pub trait Eval<T> {
25 fn eval_alpha(&self, alpha: f64) -> T;
27 fn into_animation_cell(self) -> AnimationCell<T>
30 where
31 Self: Sized + 'static,
32 {
33 AnimationCell {
34 inner: Box::new(self),
35 info: AnimationInfo::default(),
36 anim_name: std::any::type_name::<Self>().to_string(),
37 }
38 }
39}
40#[derive(Debug, Clone)]
48pub struct AnimationInfo {
49 pub rate_func: fn(f64) -> f64,
51 pub start_sec: f64,
53 pub duration_secs: f64,
55 pub enabled: bool,
57}
58
59impl Default for AnimationInfo {
60 fn default() -> Self {
61 Self {
62 rate_func: linear,
63 start_sec: 0.0,
64 duration_secs: 1.0,
65 enabled: true,
66 }
67 }
68}
69impl AnimationInfo {
72 pub fn range(&self) -> std::ops::Range<f64> {
74 self.start_sec..self.start_sec + self.duration_secs
75 }
76 pub fn range_inclusive(&self) -> std::ops::RangeInclusive<f64> {
78 self.start_sec..=self.start_sec + self.duration_secs
79 }
80 pub fn map_alpha(&self, alpha: f64) -> f64 {
83 (self.rate_func)(alpha)
84 }
85 pub fn map_sec_to_alpha(&self, sec: f64) -> Option<f64> {
91 if self.range_inclusive().contains(&sec) {
92 let alpha = (sec - self.start_sec) / self.duration_secs;
93 let alpha = if alpha.is_nan() { 1.0 } else { alpha };
94 Some(alpha)
95 } else {
96 None
97 }
98 }
99 }
101
102impl AnimationInfo {
103 pub fn at(mut self, at_sec: f64) -> Self {
105 self.start_sec = at_sec;
106 self
107 }
108 pub fn with_rate_func(mut self, rate_func: fn(f64) -> f64) -> Self {
110 self.rate_func = rate_func;
111 self
112 }
113 pub fn with_duration(mut self, secs: f64) -> Self {
115 self.duration_secs = secs;
116 self
117 }
118 pub fn with_enabled(mut self, enabled: bool) -> Self {
120 self.enabled = enabled;
121 self
122 }
123}
124
125pub struct AnimationCell<T> {
129 inner: Box<dyn Eval<T>>,
130 pub info: AnimationInfo,
132 anim_name: String,
134}
135
136impl<T> AnimationCell<T> {
137 pub fn at(mut self, at_sec: f64) -> Self {
139 self.info = self.info.at(at_sec);
140 self
141 }
142 pub fn with_rate_func(mut self, rate_func: fn(f64) -> f64) -> Self {
144 self.info = self.info.with_rate_func(rate_func);
145 self
146 }
147 pub fn with_duration(mut self, duration_secs: f64) -> Self {
149 self.info = self.info.with_duration(duration_secs);
150 self
151 }
152 pub fn with_enabled(mut self, enabled: bool) -> Self {
154 self.info = self.info.with_enabled(enabled);
155 self
156 }
157 pub fn apply_to(self, item: &mut T) -> Self {
159 self.apply_alpha_to(item, 1.0)
160 }
161 pub fn apply_alpha_to(self, item: &mut T, alpha: f64) -> Self {
163 *item = self.eval_alpha(alpha);
164 self
165 }
166}
167
168impl<T> Eval<T> for AnimationCell<T> {
170 fn eval_alpha(&self, alpha: f64) -> T {
171 self.inner.eval_alpha(self.info.map_alpha(alpha))
172 }
173}
174pub trait CoreItemAnimation {
179 fn anim_info(&self) -> &AnimationInfo;
181 fn anim_name(&self) -> &str;
183 fn eval_alpha_dyn(&self, alpha: f64) -> DynItem;
185 fn eval_global_sec_dyn(&self, sec: f64) -> Option<DynItem> {
187 self.anim_info()
188 .map_sec_to_alpha(sec)
189 .map(|alpha| self.eval_alpha_dyn(alpha))
190 }
191 fn eval_alpha_core_item(&self, alpha: f64) -> Vec<CoreItem>;
193 fn eval_global_sec_core_item(&self, sec: f64) -> Option<Vec<CoreItem>> {
195 self.anim_info()
196 .map_sec_to_alpha(sec)
197 .map(|alpha| self.eval_alpha_core_item(alpha))
198 }
199}
200
201impl<T: AnyExtractCoreItem> CoreItemAnimation for AnimationCell<T> {
204 fn eval_alpha_dyn(&self, alpha: f64) -> DynItem {
205 DynItem(Box::new(self.eval_alpha(alpha)))
206 }
207 fn eval_alpha_core_item(&self, alpha: f64) -> Vec<CoreItem> {
208 self.eval_alpha(alpha).extract()
209 }
210 fn anim_info(&self) -> &AnimationInfo {
212 &self.info
213 }
214 fn anim_name(&self) -> &str {
215 &self.anim_name
216 }
217}
218pub trait StaticAnimRequirement: Clone {}
223
224impl<T: Clone> StaticAnimRequirement for T {}
225
226pub trait StaticAnim: StaticAnimRequirement {
228 fn show(&self) -> AnimationCell<Self>;
230 fn hide(&self) -> AnimationCell<Self>;
232}
233
234impl<T: StaticAnimRequirement + 'static> StaticAnim for T {
235 fn show(&self) -> AnimationCell<Self> {
236 Static(self.clone())
237 .into_animation_cell()
238 .with_duration(0.0)
239 }
240 fn hide(&self) -> AnimationCell<Self> {
241 Static(self.clone())
242 .into_animation_cell()
243 .with_enabled(false)
244 .with_duration(0.0)
245 }
246}
247
248pub struct Static<T>(pub T);
251
252impl<T: Clone> Eval<T> for Static<T> {
253 fn eval_alpha(&self, _alpha: f64) -> T {
254 self.0.clone()
255 }
256}
257