ferroui_base/rendering/composition/brushes/
server_simple_content_brush.rs1use crate::rendering::composition::server::{
5 impl_simple_server_render_resource, server_simple_brush, IServerObject, IServerRenderResource,
6 IServerRenderResourceObserver, ServerCompositor, SimpleServerRenderResource,
7};
8use crate::media::{
9 AlignmentX, AlignmentY, IBrush, ISceneBrush, ISceneBrushContent, ITileBrush, ITransform, Stretch, TileMode,
10};
11use crate::rendering::composition::drawing::{
12 CompositionRenderDataSceneBrushContent, CompositionRenderDataSceneBrushContentProperties,
13};
14use crate::rendering::composition::generated::{
15 ServerCompositionSimpleBrushHooks, ServerCompositionSimpleBrushProps, ServerCompositionSimpleTileBrushHooks,
16 ServerCompositionSimpleTileBrushProps,
17};
18use crate::rendering::composition::transport::BatchStreamReader;
19use crate::{RelativePoint, RelativeRect};
20use std::any::{Any, TypeId};
21use std::cell::RefCell;
22use std::rc::{Rc, Weak};
23use std::time::Duration;
24
25server_simple_brush! {
26 ServerCompositionSimpleContentBrush {
29 props: ServerCompositionSimpleTileBrushProps = ServerCompositionSimpleTileBrushProps::new(),
30 content: RefCell<Option<CompositionRenderDataSceneBrushContentProperties>> = RefCell::new(None),
31 }
32 brush: |b| b.props.base();
33 deserialize: |d, reader, committed_at| {
34 d.props.deserialize_changes_core(d, reader, committed_at);
35 let content =
36 CompositionRenderDataSceneBrushContentProperties::deserialize(reader, d.base.compositor().as_ref());
37 d.set_content(content);
38 };
39 find: |f, type_id| f.props.find_props(type_id);
40 dispose: |x| x.remove_content_observer();
41 as: { as_tile_brush -> ITileBrush, as_scene_brush -> ISceneBrush }
42}
43
44impl ServerCompositionSimpleTileBrushHooks for ServerCompositionSimpleContentBrush {}
45
46impl ServerCompositionSimpleContentBrush {
47 pub fn props(&self) -> &ServerCompositionSimpleTileBrushProps {
49 &self.props
50 }
51
52 fn as_observer(&self) -> Option<Rc<dyn IServerRenderResourceObserver>> {
53 self.to_rc().map(|this| this as Rc<dyn IServerRenderResourceObserver>)
54 }
55
56 fn set_content(&self, content: Option<CompositionRenderDataSceneBrushContentProperties>) {
60 let old = self.content.borrow().as_ref().map(|content| content.render_data.clone());
61 let new = content.as_ref().map(|content| content.render_data.clone());
62 let same = match (&old, &new) {
63 (Some(old), Some(new)) => Rc::ptr_eq(old, new),
64 (None, None) => true,
65 _ => false,
66 };
67 if !same {
68 if let Some(observer) = self.as_observer() {
69 if let Some(old) = &old {
70 old.remove_observer(&observer);
71 }
72 if let Some(new) = &new {
73 new.add_observer(&observer);
74 }
75 }
76 }
77
78 *self.content.borrow_mut() = content;
79 }
80
81 fn remove_content_observer(&self) {
82 let render_data = self.content.borrow().as_ref().map(|content| content.render_data.clone());
83 if let (Some(render_data), Some(observer)) = (render_data, self.as_observer()) {
84 render_data.remove_observer(&observer);
85 }
86 }
87}
88
89impl ITileBrush for ServerCompositionSimpleContentBrush {
90 fn alignment_x(&self) -> AlignmentX {
91 self.props.alignment_x()
92 }
93
94 fn alignment_y(&self) -> AlignmentY {
95 self.props.alignment_y()
96 }
97
98 fn destination_rect(&self) -> RelativeRect {
99 self.props.destination_rect()
100 }
101
102 fn source_rect(&self) -> RelativeRect {
103 self.props.source_rect()
104 }
105
106 fn stretch(&self) -> Stretch {
107 self.props.stretch()
108 }
109
110 fn tile_mode(&self) -> TileMode {
111 self.props.tile_mode()
112 }
113}
114
115impl ISceneBrush for ServerCompositionSimpleContentBrush {
116 fn create_content(&self) -> Option<Rc<dyn ISceneBrushContent>> {
117 let content = self.content.borrow();
118 let content = content.as_ref()?;
119 if content.render_data.is_disposed() {
120 return None;
121 }
122 let this: Rc<dyn ITileBrush> = self.to_rc()?;
123 Some(Rc::new(CompositionRenderDataSceneBrushContent::new(this, content)))
124 }
125}