Skip to main content

ferroui_base/rendering/composition/server/
server_composition_bitmap_cache.rs

1use super::{impl_animated_server_object, IAnimatedServerObject, IServerObject, ServerCompositionVisual, ServerCompositor, ServerObject};
2use crate::rendering::composition::generated::{
3    ServerCompositionBitmapCacheHooks, ServerCompositionBitmapCacheProps, ServerCompositionCacheModeHooks,
4};
5use crate::rendering::composition::transport::BatchStreamReader;
6use std::any::{Any, TypeId};
7use std::cell::RefCell;
8use std::rc::{Rc, Weak};
9use std::time::Duration;
10
11/// Server-side counterpart of `CompositionBitmapCache`.
12pub struct ServerCompositionBitmapCache {
13    object: ServerObject,
14    props: ServerCompositionBitmapCacheProps,
15    attached_visuals: RefCell<Vec<Weak<ServerCompositionVisual>>>,
16}
17
18impl ServerCompositionBitmapCache {
19    pub fn new(compositor: &Rc<ServerCompositor>) -> Rc<ServerCompositionBitmapCache> {
20        Rc::new_cyclic(|this: &Weak<ServerCompositionBitmapCache>| {
21            let owner: Weak<dyn IAnimatedServerObject> = this.clone();
22            ServerCompositionBitmapCache {
23                object: ServerObject::new(compositor, owner),
24                props: ServerCompositionBitmapCacheProps::new(),
25                attached_visuals: RefCell::new(Vec::new()),
26            }
27        })
28    }
29
30    pub fn render_at_scale(&self) -> f64 {
31        self.props.render_at_scale()
32    }
33
34    pub fn snaps_to_device_pixels(&self) -> bool {
35        self.props.snaps_to_device_pixels()
36    }
37
38    pub fn enable_clear_type(&self) -> bool {
39        self.props.enable_clear_type()
40    }
41
42    // --- ServerCompositionCacheMode -----------------------------------------
43
44    pub fn subscribe(&self, visual: &Rc<ServerCompositionVisual>) {
45        let mut visuals = self.attached_visuals.borrow_mut();
46        visuals.retain(|v| v.strong_count() > 0);
47        if !visuals.iter().any(|v| std::ptr::eq(v.as_ptr(), Rc::as_ptr(visual))) {
48            visuals.push(Rc::downgrade(visual));
49        }
50    }
51
52    pub fn unsubscribe(&self, visual: &Rc<ServerCompositionVisual>) {
53        self.attached_visuals.borrow_mut().retain(|v| !std::ptr::eq(v.as_ptr(), Rc::as_ptr(visual)));
54    }
55}
56
57impl ServerCompositionCacheModeHooks for ServerCompositionBitmapCache {}
58impl ServerCompositionBitmapCacheHooks for ServerCompositionBitmapCache {}
59
60impl_animated_server_object!(
61    ServerCompositionBitmapCache,
62    object,
63    composition_property: ServerCompositionBitmapCacheProps::get_composition_property
64);
65
66impl IServerObject for ServerCompositionBitmapCache {
67    fn deserialize_changes_core(&self, reader: &mut BatchStreamReader<'_>, committed_at: Duration) {
68        self.props.deserialize_changes_core(self, reader, committed_at);
69    }
70
71    fn values_invalidated(&self) {
72        let alive: Vec<_> = self.attached_visuals.borrow().iter().filter_map(Weak::upgrade).collect();
73        for visual in alive {
74            visual.on_cache_mode_state_changed();
75        }
76    }
77
78    fn get_props(&self, type_id: TypeId) -> Option<&dyn Any> {
79        self.props.find_props(type_id)
80    }
81
82    fn as_animated(self: Rc<Self>) -> Option<Rc<dyn IAnimatedServerObject>> {
83        Some(self)
84    }
85
86    fn as_any(&self) -> &dyn Any {
87        self
88    }
89
90    fn into_any_rc(self: Rc<Self>) -> Rc<dyn Any> {
91        self
92    }
93}