1#![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
17pub mod vitem;
19
20#[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}