ranim_core/animation/compose/
stack.rs1use std::any::type_name;
4
5use crate::animation::build::{IntoAnimNode, Unplaced};
6use crate::animation::node::{AnimNode, NodeContent};
7
8#[derive(Default)]
13pub struct AnimStack {
14 animations: Vec<AnimNode>,
15 duration_secs: f64,
16}
17
18impl AnimStack {
19 pub fn new() -> Self {
21 Self::default()
22 }
23
24 pub fn push<A: IntoAnimNode + 'static>(&mut self, animation: A) -> &mut Self {
26 let animation = animation.into_anim_node();
27 self.duration_secs = self.duration_secs.max(animation.time_range.end);
28 self.animations.push(animation);
29 self
30 }
31
32 pub fn extend(&mut self, stack: AnimStack) -> &mut Self {
34 self.duration_secs = self.duration_secs.max(stack.duration_secs);
35 self.animations.extend(stack.animations);
36 self
37 }
38
39 pub fn duration_secs(&self) -> f64 {
41 self.duration_secs
42 }
43
44 pub fn built_animations(&self) -> &[AnimNode] {
46 &self.animations
47 }
48
49 pub fn into_built_animations(self) -> Vec<AnimNode> {
51 self.animations
52 }
53}
54
55impl Unplaced for AnimStack {}
56impl IntoAnimNode for AnimStack {
57 fn into_anim_node(self) -> AnimNode {
58 let duration_secs = self.duration_secs;
59 AnimNode {
60 content: NodeContent::Children(self.animations),
61 internal_time_secs: duration_secs,
62 rate_func: None,
63 time_range: 0.0..duration_secs,
64 end_inclusive: true,
65 enabled: true,
66 anim_name: type_name::<Self>(),
67 }
68 }
69}
70
71#[macro_export]
73macro_rules! stack {
74 ($($animation:expr),* $(,)?) => {
75 {
76 #[allow(unused_mut)]
77 let mut stack = $crate::animation::compose::stack::AnimStack::new();
78 $(stack.push($animation);)*
79 stack
80 }
81 };
82}
83
84impl<A: IntoAnimNode + 'static> FromIterator<A> for AnimStack {
85 fn from_iter<I: IntoIterator<Item = A>>(iter: I) -> Self {
86 let mut stack = AnimStack::new();
87 for animation in iter {
88 stack.push(animation);
89 }
90 stack
91 }
92}