ferroui_base/rendering/composition/animations/
implicit_animation_collection.rs1use super::ICompositionAnimationBase;
2use crate::rendering::composition::{AsCompositionObject, CompositionObject, Compositor};
3use std::cell::RefCell;
4use std::collections::HashMap;
5use std::rc::Rc;
6
7fn same(a: &Rc<dyn ICompositionAnimationBase>, b: &Rc<dyn ICompositionAnimationBase>) -> bool {
8 std::ptr::addr_eq(Rc::as_ptr(a), Rc::as_ptr(b))
9}
10
11pub struct ImplicitAnimationCollection {
25 object: CompositionObject,
26 inner: RefCell<Vec<(String, Rc<dyn ICompositionAnimationBase>)>>,
27}
28
29impl ImplicitAnimationCollection {
30 pub(crate) fn new(compositor: &Rc<Compositor>) -> Rc<ImplicitAnimationCollection> {
31 Rc::new(ImplicitAnimationCollection {
32 object: CompositionObject::new(compositor, None),
33 inner: RefCell::new(Vec::new()),
34 })
35 }
36
37 fn index_of(&self, key: &str) -> Option<usize> {
38 self.inner.borrow().iter().position(|(k, _)| k == key)
39 }
40
41 pub fn items(&self) -> Vec<(String, Rc<dyn ICompositionAnimationBase>)> {
43 self.inner.borrow().clone()
44 }
45
46 pub fn add_pair(&self, item: (String, Rc<dyn ICompositionAnimationBase>)) {
48 self.add(&item.0, item.1)
49 }
50
51 pub fn clear(&self) {
52 self.inner.borrow_mut().clear()
53 }
54
55 pub fn contains_pair(&self, key: &str, value: &Rc<dyn ICompositionAnimationBase>) -> bool {
58 self.inner.borrow().iter().any(|(k, v)| k == key && same(v, value))
59 }
60
61 pub fn copy_to(&self, array: &mut [Option<(String, Rc<dyn ICompositionAnimationBase>)>], array_index: usize) {
64 let inner = self.inner.borrow();
65 if array_index > array.len() || array.len() - array_index < inner.len() {
66 panic!("Destination array is not long enough to copy all the items in the collection. Check array index and length.");
67 }
68 for (offset, item) in inner.iter().enumerate() {
69 array[array_index + offset] = Some(item.clone());
70 }
71 }
72
73 pub fn remove_pair(&self, key: &str, value: &Rc<dyn ICompositionAnimationBase>) -> bool {
76 if !self.contains_pair(key, value) {
77 return false;
78 }
79 self.remove(key)
80 }
81
82 pub fn count(&self) -> usize {
83 self.inner.borrow().len()
84 }
85
86 pub fn is_read_only(&self) -> bool {
88 false
89 }
90
91 pub fn add(&self, key: &str, value: Rc<dyn ICompositionAnimationBase>) {
93 if self.index_of(key).is_some() {
94 panic!("An item with the same key has already been added. Key: {key}");
95 }
96 self.inner.borrow_mut().push((key.to_owned(), value));
97 }
98
99 pub fn contains_key(&self, key: &str) -> bool {
100 self.index_of(key).is_some()
101 }
102
103 pub fn remove(&self, key: &str) -> bool {
104 match self.index_of(key) {
105 Some(index) => {
106 self.inner.borrow_mut().remove(index);
107 true
108 }
109 None => false,
110 }
111 }
112
113 pub fn try_get_value(&self, key: &str) -> Option<Rc<dyn ICompositionAnimationBase>> {
114 self.inner.borrow().iter().find(|(k, _)| k == key).map(|(_, v)| v.clone())
115 }
116
117 pub fn get(&self, key: &str) -> Rc<dyn ICompositionAnimationBase> {
119 match self.try_get_value(key) {
120 Some(value) => value,
121 None => panic!("The given key '{key}' was not present in the dictionary."),
122 }
123 }
124
125 pub fn set(&self, key: &str, value: Rc<dyn ICompositionAnimationBase>) {
127 match self.index_of(key) {
128 Some(index) => self.inner.borrow_mut()[index].1 = value,
129 None => self.inner.borrow_mut().push((key.to_owned(), value)),
130 }
131 }
132
133 pub fn keys(&self) -> Vec<String> {
134 self.inner.borrow().iter().map(|(k, _)| k.clone()).collect()
135 }
136
137 pub fn values(&self) -> Vec<Rc<dyn ICompositionAnimationBase>> {
138 self.inner.borrow().iter().map(|(_, v)| v.clone()).collect()
139 }
140
141 pub fn size(&self) -> u32 {
143 self.count() as u32
144 }
145
146 pub fn get_view(&self) -> HashMap<String, Rc<dyn ICompositionAnimationBase>> {
147 self.inner.borrow().iter().cloned().collect()
148 }
149
150 pub fn has_key(&self, key: &str) -> bool {
151 self.contains_key(key)
152 }
153
154 pub fn insert(&self, key: &str, animation: Rc<dyn ICompositionAnimationBase>) {
155 self.add(key, animation)
156 }
157
158 pub fn lookup(&self, key: &str) -> Option<Rc<dyn ICompositionAnimationBase>> {
159 self.try_get_value(key)
160 }
161}
162
163impl AsCompositionObject for ImplicitAnimationCollection {
164 fn as_composition_object(&self) -> &CompositionObject {
165 &self.object
166 }
167
168 fn composition_type_name(&self) -> &'static str {
169 "ImplicitAnimationCollection"
170 }
171}