Skip to main content

ferroui_base/rendering/composition/server/
server_compositor_animations.rs

1use super::{IServerClockItem, ServerObjectAnimations};
2use std::cell::RefCell;
3use std::collections::VecDeque;
4use std::rc::Rc;
5
6/// The clock items and the dirty animated objects of a server compositor.
7#[derive(Default)]
8pub struct ServerCompositorAnimations {
9    clock_items: RefCell<Vec<Rc<dyn IServerClockItem>>>,
10    clock_items_to_update: RefCell<Vec<Rc<dyn IServerClockItem>>>,
11    dirty_animated_object_queue: RefCell<VecDeque<Rc<ServerObjectAnimations>>>,
12}
13
14fn same_item(a: &Rc<dyn IServerClockItem>, b: &Rc<dyn IServerClockItem>) -> bool {
15    std::ptr::addr_eq(Rc::as_ptr(a), Rc::as_ptr(b))
16}
17
18impl ServerCompositorAnimations {
19    pub fn new() -> Self {
20        Self::default()
21    }
22
23    pub fn add_to_clock(&self, item: Rc<dyn IServerClockItem>) {
24        let mut items = self.clock_items.borrow_mut();
25        if !items.iter().any(|i| same_item(i, &item)) {
26            items.push(item);
27        }
28    }
29
30    pub fn remove_from_clock(&self, item: &Rc<dyn IServerClockItem>) {
31        self.clock_items.borrow_mut().retain(|i| !same_item(i, item));
32    }
33
34    pub fn process(&self) {
35        let mut to_update = std::mem::take(&mut *self.clock_items_to_update.borrow_mut());
36        to_update.extend(self.clock_items.borrow().iter().cloned());
37        for animation in &to_update {
38            animation.on_tick();
39        }
40        to_update.clear();
41        *self.clock_items_to_update.borrow_mut() = to_update;
42
43        loop {
44            let Some(animation) = self.dirty_animated_object_queue.borrow_mut().pop_front() else { break };
45            animation.evaluate_animations();
46        }
47    }
48
49    pub fn need_next_tick(&self) -> bool {
50        !self.clock_items.borrow().is_empty()
51    }
52
53    pub fn add_dirty_animated_object(&self, obj: Rc<ServerObjectAnimations>) {
54        let mut queue = self.dirty_animated_object_queue.borrow_mut();
55        if !queue.iter().any(|o| Rc::ptr_eq(o, &obj)) {
56            queue.push_back(obj);
57        }
58    }
59}