freya_animation/
anim_sequential.rs

1use std::ops::Deref;
2
3use crate::hook::{
4    AnimDirection,
5    AnimatedValue,
6};
7
8/// Chain a sequence of animated values.
9#[derive(Clone)]
10pub struct AnimSequential<Animated: AnimatedValue, const N: usize> {
11    values: [Animated; N],
12    curr_value: usize,
13    acc_index: u128,
14}
15
16impl<Animated: AnimatedValue + Default, const N: usize> Default for AnimSequential<Animated, N> {
17    fn default() -> Self {
18        Self {
19            values: std::array::from_fn(|_| Animated::default()),
20            curr_value: 0,
21            acc_index: 0,
22        }
23    }
24}
25
26impl<Animated: AnimatedValue, const N: usize> AnimSequential<Animated, N> {
27    pub fn new(values: [Animated; N]) -> Self {
28        Self {
29            values,
30            curr_value: 0,
31            acc_index: 0,
32        }
33    }
34}
35
36impl<Animated: AnimatedValue, const N: usize> Deref for AnimSequential<Animated, N> {
37    type Target = [Animated; N];
38
39    fn deref(&self) -> &Self::Target {
40        &self.values
41    }
42}
43
44impl<Animated: AnimatedValue, const N: usize> AnimatedValue for AnimSequential<Animated, N> {
45    fn advance(&mut self, index: u128, direction: AnimDirection) {
46        let value = if direction == AnimDirection::Forward {
47            self.values.get_mut(self.curr_value)
48        } else {
49            self.values.iter_mut().rev().nth(self.curr_value)
50        };
51        if let Some(value) = value {
52            let index = index - self.acc_index;
53            value.advance(index, direction);
54
55            if value.is_finished(index, direction) {
56                self.curr_value += 1;
57                self.acc_index += index;
58            }
59        }
60    }
61
62    fn is_finished(&self, index: u128, direction: AnimDirection) -> bool {
63        let value = if direction == AnimDirection::Forward {
64            self.values.get(self.curr_value)
65        } else {
66            self.values.iter().rev().nth(self.curr_value)
67        };
68        if let Some(value) = value {
69            value.is_finished(index, direction)
70        } else {
71            true
72        }
73    }
74
75    fn prepare(&mut self, direction: AnimDirection) {
76        self.acc_index = 0;
77        self.curr_value = 0;
78        match direction {
79            AnimDirection::Forward => {
80                for val in self.values.iter_mut() {
81                    val.prepare(direction);
82                }
83            }
84            AnimDirection::Reverse => {
85                for val in self.values.iter_mut().rev() {
86                    val.prepare(direction);
87                }
88            }
89        }
90    }
91
92    fn finish(&mut self, direction: AnimDirection) {
93        match direction {
94            AnimDirection::Forward => {
95                for value in &mut self.values {
96                    value.finish(direction);
97                }
98            }
99            AnimDirection::Reverse => {
100                for value in &mut self.values {
101                    value.finish(direction);
102                }
103            }
104        }
105    }
106
107    fn into_reversed(self) -> Self {
108        let mut values: [Animated; N] = self.values.map(|v| v.into_reversed());
109
110        values.reverse();
111
112        Self {
113            values,
114            curr_value: 0,
115            acc_index: 0,
116        }
117    }
118}