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::Stack(self.animations),
61 internal_time_secs: duration_secs,
62 rate_func: None,
63 time_range: 0.0..duration_secs,
64 enabled: true,
65 anim_name: type_name::<Self>(),
66 }
67 }
68}
69
70#[macro_export]
72macro_rules! stack {
73 ($($animation:expr),* $(,)?) => {
74 {
75 #[allow(unused_mut)]
76 let mut stack = $crate::animation::compose::stack::AnimStack::new();
77 $(stack.push($animation);)*
78 stack
79 }
80 };
81}
82
83impl<A: IntoAnimNode + 'static> FromIterator<A> for AnimStack {
84 fn from_iter<I: IntoIterator<Item = A>>(iter: I) -> Self {
85 let mut stack = AnimStack::new();
86 for animation in iter {
87 stack.push(animation);
88 }
89 stack
90 }
91}