ranim_items/
lib.rs

1//! Ranim's built-in items
2#![warn(missing_docs)]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4#![allow(rustdoc::private_intra_doc_links)]
5#![doc(
6    html_logo_url = "https://raw.githubusercontent.com/AzurIce/ranim/refs/heads/main/assets/ranim.svg",
7    html_favicon_url = "https://raw.githubusercontent.com/AzurIce/ranim/refs/heads/main/assets/ranim.svg"
8)]
9
10use derive_more::{Deref, DerefMut};
11use ranim_core::{
12    Extract,
13    traits::{Alignable, Interpolatable, Opacity},
14    utils::resize_preserving_order_with_repeated_indices,
15};
16
17/// The vectorized item.
18pub mod vitem;
19
20/// A Group of type `T`.
21///
22/// Just like a [`Vec`]
23#[derive(Debug, Default, Clone, PartialEq, Deref, DerefMut)]
24pub struct Group<T>(pub Vec<T>);
25
26impl<T> IntoIterator for Group<T> {
27    type IntoIter = std::vec::IntoIter<T>;
28    type Item = T;
29    fn into_iter(self) -> Self::IntoIter {
30        self.0.into_iter()
31    }
32}
33
34impl<'a, T> IntoIterator for &'a Group<T> {
35    type IntoIter = std::slice::Iter<'a, T>;
36    type Item = &'a T;
37    fn into_iter(self) -> Self::IntoIter {
38        self.0.iter()
39    }
40}
41
42impl<'a, T> IntoIterator for &'a mut Group<T> {
43    type IntoIter = std::slice::IterMut<'a, T>;
44    type Item = &'a mut T;
45    fn into_iter(self) -> Self::IntoIter {
46        self.0.iter_mut()
47    }
48}
49
50impl<T> FromIterator<T> for Group<T> {
51    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
52        Self(Vec::from_iter(iter))
53    }
54}
55
56impl<T: Interpolatable> Interpolatable for Group<T> {
57    fn lerp(&self, target: &Self, t: f64) -> Self {
58        self.into_iter()
59            .zip(target)
60            .map(|(a, b)| a.lerp(b, t))
61            .collect()
62    }
63}
64
65impl<T: Opacity + Alignable + Clone> Alignable for Group<T> {
66    fn is_aligned(&self, other: &Self) -> bool {
67        self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a.is_aligned(b))
68    }
69    fn align_with(&mut self, other: &mut Self) {
70        let len = self.len().max(other.len());
71
72        let transparent_repeated = |items: &mut Vec<T>, repeat_idxs: Vec<usize>| {
73            for idx in repeat_idxs {
74                items[idx].set_opacity(0.0);
75            }
76        };
77        if self.len() != len {
78            let (mut items, idxs) = resize_preserving_order_with_repeated_indices(&self.0, len);
79            transparent_repeated(&mut items, idxs);
80            self.0 = items;
81        }
82        if other.len() != len {
83            let (mut items, idxs) = resize_preserving_order_with_repeated_indices(&other.0, len);
84            transparent_repeated(&mut items, idxs);
85            other.0 = items;
86        }
87        self.iter_mut()
88            .zip(other)
89            .for_each(|(a, b)| a.align_with(b));
90    }
91}
92
93impl<E: Extract> Extract for Group<E> {
94    type Target = E::Target;
95    fn extract(&self) -> Vec<Self::Target> {
96        self.iter().flat_map(|x| x.extract()).collect()
97    }
98}