Skip to main content

ass_renderer/animation/
state.rs

1//! Resolved animation state queried by the render pipeline
2
3#[cfg(feature = "nostd")]
4use alloc::string::{String, ToString};
5#[cfg(not(feature = "nostd"))]
6use std::string::String;
7
8use smallvec::SmallVec;
9
10use super::value::AnimatedResult;
11
12/// Current animation state
13#[derive(Debug, Clone)]
14pub struct AnimationState {
15    properties: SmallVec<[(String, AnimatedResult); 16]>,
16}
17
18impl AnimationState {
19    /// Create new animation state
20    pub fn new() -> Self {
21        Self {
22            properties: SmallVec::new(),
23        }
24    }
25
26    /// Set a property value
27    pub fn set_property(&mut self, name: &str, value: AnimatedResult) {
28        if let Some(entry) = self.properties.iter_mut().find(|(n, _)| n == name) {
29            entry.1 = value;
30        } else {
31            self.properties.push((name.to_string(), value));
32        }
33    }
34
35    /// Get a property value
36    pub fn get_property(&self, name: &str) -> Option<&AnimatedResult> {
37        self.properties
38            .iter()
39            .find(|(n, _)| n == name)
40            .map(|(_, v)| v)
41    }
42
43    /// Get font size if animated
44    pub fn font_size(&self) -> Option<f32> {
45        self.get_property("fs").and_then(|v| {
46            if let AnimatedResult::Float(size) = v {
47                Some(*size)
48            } else {
49                None
50            }
51        })
52    }
53
54    /// Get scale if animated
55    pub fn scale(&self) -> Option<(f32, f32)> {
56        let scale_x = self.get_property("fscx").and_then(|v| {
57            if let AnimatedResult::Float(scale) = v {
58                Some(*scale)
59            } else {
60                None
61            }
62        });
63
64        let scale_y = self.get_property("fscy").and_then(|v| {
65            if let AnimatedResult::Float(scale) = v {
66                Some(*scale)
67            } else {
68                None
69            }
70        });
71
72        match (scale_x, scale_y) {
73            (Some(x), Some(y)) => Some((x, y)),
74            (Some(x), None) => Some((x, 100.0)),
75            (None, Some(y)) => Some((100.0, y)),
76            _ => None,
77        }
78    }
79
80    /// Get rotation if animated
81    pub fn rotation(&self) -> Option<f32> {
82        self.get_property("frz").and_then(|v| {
83            if let AnimatedResult::Float(rotation) = v {
84                Some(*rotation)
85            } else {
86                None
87            }
88        })
89    }
90
91    /// Get color if animated
92    pub fn color(&self) -> Option<[u8; 4]> {
93        self.get_property("c").and_then(|v| {
94            if let AnimatedResult::Color(color) = v {
95                Some(*color)
96            } else {
97                None
98            }
99        })
100    }
101}
102
103impl Default for AnimationState {
104    fn default() -> Self {
105        Self::new()
106    }
107}