ferroui_base/rendering/composition/generated/
sprite_visual.rs1use bitflags::bitflags;
8use crate::rendering::composition::ICompositionObject;
9use crate::rendering::composition::animations::ICompositionAnimation;
10use crate::rendering::composition::expressions::ExpressionVariant;
11use crate::rendering::composition::server::AsServerRenderResource;
12use crate::rendering::composition::server::CompositionProperty;
13use crate::rendering::composition::server::CompositionPropertyOf;
14use crate::rendering::composition::server::IServerAnimatedPropertyHost;
15use crate::rendering::composition::server::IServerObject;
16use crate::rendering::composition::server::ServerPropertyValue;
17use crate::rendering::composition::server::ServerValueChange;
18use crate::rendering::composition::server::props_of;
19use crate::rendering::composition::server::read_server_object;
20use crate::rendering::composition::transport::BatchStreamReader;
21use crate::rendering::composition::transport::BatchStreamWriter;
22use crate::rendering::composition::transport::BatchValue;
23use crate::rendering::composition::transport::BatchValueReader;
24use std::any::Any;
25use std::any::TypeId;
26use std::cell::Cell;
27use std::cell::RefCell;
28use std::rc::Rc;
29use std::sync::OnceLock;
30use std::time::Duration;
31use super::CompositionContainerVisualHooks;
32use super::CompositionContainerVisualProps;
33
34bitflags! {
35 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
37 pub struct SpriteVisualChangedFields: u8 {
38 const BRUSH = 1;
39 const SHADOW = 2;
40 }
41}
42
43impl BatchValue for SpriteVisualChangedFields {
44 #[inline]
45 fn write_to(&self, out: &mut Vec<u8>) {
46 self.bits().write_to(out);
47 }
48
49 #[inline]
50 fn read_from(input: &mut BatchValueReader<'_>) -> Self {
51 SpriteVisualChangedFields::from_bits_retain(u8::read_from(input))
52 }
53}
54
55pub trait SpriteVisualHooks: CompositionContainerVisualHooks {
58 fn initialize_defaults_extra(&self) {}
59
60 fn validate_brush_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
61 fn on_brush_changed(&self) {}
62 fn on_brush_changing(&self) {}
63
64 fn validate_shadow_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
65 fn on_shadow_changed(&self) {}
66 fn on_shadow_changing(&self) {}
67}
68
69pub struct SpriteVisualProps {
71 base: CompositionContainerVisualProps,
72 changed_fields_of_sprite_visual: Cell<SpriteVisualChangedFields>,
73 brush: RefCell<Option<Rc<dyn ICompositionObject>>>,
74 shadow: RefCell<Option<Rc<dyn ICompositionObject>>>,
75}
76
77impl Default for SpriteVisualProps {
78 fn default() -> Self {
79 Self::new()
80 }
81}
82
83impl SpriteVisualProps {
84 pub fn new() -> Self {
88 Self {
89 base: CompositionContainerVisualProps::new(),
90 changed_fields_of_sprite_visual: Cell::new(SpriteVisualChangedFields::empty()),
91 brush: RefCell::new(None),
92 shadow: RefCell::new(None),
93 }
94 }
95
96 pub fn base(&self) -> &CompositionContainerVisualProps {
98 &self.base
99 }
100
101 pub fn initialize_defaults(&self, host: &dyn SpriteVisualHooks) {
104 self.base.initialize_defaults(host);
105 self.initialize_own_defaults(host);
106 }
107
108 pub fn initialize_own_defaults(&self, host: &dyn SpriteVisualHooks) {
110 SpriteVisualHooks::initialize_defaults_extra(host);
111 }
112
113 pub fn brush(&self) -> Option<Rc<dyn ICompositionObject>> {
115 self.brush.borrow().clone()
116 }
117
118 pub fn set_brush(&self, host: &dyn SpriteVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
120 let mut changed = false;
121 let old_value = self.brush.borrow().clone();
122 if old_value.differs(&value) {
123 SpriteVisualHooks::validate_brush_change(host, &old_value, &value);
124 SpriteVisualHooks::on_brush_changing(host);
125 changed = true;
126 *self.brush.borrow_mut() = value.clone();
128 self.changed_fields_of_sprite_visual.set(self.changed_fields_of_sprite_visual.get() | SpriteVisualChangedFields::BRUSH);
130 host.register_for_serialization();
131 }
132 *self.brush.borrow_mut() = value;
133 if changed {
134 SpriteVisualHooks::on_brush_changed(host);
135 }
136 }
137
138 pub fn shadow(&self) -> Option<Rc<dyn ICompositionObject>> {
140 self.shadow.borrow().clone()
141 }
142
143 pub fn set_shadow(&self, host: &dyn SpriteVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
145 let mut changed = false;
146 let old_value = self.shadow.borrow().clone();
147 if old_value.differs(&value) {
148 SpriteVisualHooks::validate_shadow_change(host, &old_value, &value);
149 SpriteVisualHooks::on_shadow_changing(host);
150 changed = true;
151 *self.shadow.borrow_mut() = value.clone();
153 self.changed_fields_of_sprite_visual.set(self.changed_fields_of_sprite_visual.get() | SpriteVisualChangedFields::SHADOW);
155 host.register_for_serialization();
156 }
157 *self.shadow.borrow_mut() = value;
158 if changed {
159 SpriteVisualHooks::on_shadow_changed(host);
160 }
161 }
162
163 pub fn start_animation(
167 &self,
168 host: &dyn SpriteVisualHooks,
169 property_name: &str,
170 animation: &dyn ICompositionAnimation,
171 final_value: Option<ExpressionVariant>,
172 ) -> bool {
173 self.base.start_animation(host, property_name, animation, final_value)
174 }
175
176 pub fn serialize_changes_core(&self, host: &dyn SpriteVisualHooks, writer: &mut BatchStreamWriter<'_>) {
179 self.base.serialize_changes_core(host, writer);
180 let changed = self.changed_fields_of_sprite_visual.get();
181 writer.write(changed);
182 if changed.contains(SpriteVisualChangedFields::BRUSH) {
183 writer.write_server_object(self.brush.borrow().clone().map(|o| o.server()));
184 }
185 if changed.contains(SpriteVisualChangedFields::SHADOW) {
186 writer.write_server_object(self.shadow.borrow().clone().map(|o| o.server()));
187 }
188 self.changed_fields_of_sprite_visual.set(SpriteVisualChangedFields::empty());
189 }
190}
191
192pub trait ServerSpriteVisualHooks: IServerAnimatedPropertyHost {
195 fn base_deserialize_changes_core(&self, reader: &mut BatchStreamReader<'_>, committed_at: Duration);
198
199 fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
200 fn on_fields_deserialized(&self, _changed: SpriteVisualChangedFields) {}
201
202 fn on_brush_changed(&self) {}
203 fn on_brush_changing(&self) {}
204
205 fn on_shadow_changed(&self) {}
206 fn on_shadow_changing(&self) {}
207}
208
209pub struct ServerSpriteVisualProps {
211 brush: RefCell<Option<Rc<dyn IServerObject>>>,
212 shadow: RefCell<Option<Rc<dyn IServerObject>>>,
213}
214
215impl Default for ServerSpriteVisualProps {
216 fn default() -> Self {
217 Self::new()
218 }
219}
220
221impl ServerSpriteVisualProps {
222 pub fn new() -> Self {
225 Self {
226 brush: RefCell::new(None),
227 shadow: RefCell::new(None),
228 }
229 }
230
231 pub fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
234 if type_id == TypeId::of::<Self>() {
235 return Some(self);
236 }
237 None
238 }
239
240 pub fn id_of_brush_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
242 static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
243 PROPERTY.get_or_init(|| {
244 CompositionProperty::register::<ServerSpriteVisualProps, Option<Rc<dyn IServerObject>>>(
245 "Brush",
246 "ServerSpriteVisual",
247 |obj| props_of::<ServerSpriteVisualProps>(obj).brush.borrow().clone(),
248 |obj, v| *props_of::<ServerSpriteVisualProps>(obj).brush.borrow_mut() = v,
249 None,
250 None,
251 )
252 })
253 }
254
255 pub fn brush(&self) -> Option<Rc<dyn IServerObject>> {
257 self.brush.borrow().clone()
258 }
259
260 pub fn set_brush(&self, host: &dyn ServerSpriteVisualHooks, value: Option<Rc<dyn IServerObject>>) {
261 let old_value = self.brush.borrow().clone();
262 let mut changed = false;
263 if old_value.differs(&value) {
264 ServerSpriteVisualHooks::on_brush_changing(host);
265 changed = true;
266 }
267 host.set_value(
268 Self::id_of_brush_property().base(),
269 ServerValueChange {
270 equal: old_value.default_equals(&value),
271 old_resource: old_value.as_server_render_resource(),
272 new_resource: value.as_server_render_resource(),
273 assign: &mut || *self.brush.borrow_mut() = value.clone(),
274 },
275 );
276 if changed {
277 ServerSpriteVisualHooks::on_brush_changed(host);
278 }
279 }
280
281 pub fn id_of_shadow_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
283 static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
284 PROPERTY.get_or_init(|| {
285 CompositionProperty::register::<ServerSpriteVisualProps, Option<Rc<dyn IServerObject>>>(
286 "Shadow",
287 "ServerSpriteVisual",
288 |obj| props_of::<ServerSpriteVisualProps>(obj).shadow.borrow().clone(),
289 |obj, v| *props_of::<ServerSpriteVisualProps>(obj).shadow.borrow_mut() = v,
290 None,
291 None,
292 )
293 })
294 }
295
296 pub fn shadow(&self) -> Option<Rc<dyn IServerObject>> {
298 self.shadow.borrow().clone()
299 }
300
301 pub fn set_shadow(&self, host: &dyn ServerSpriteVisualHooks, value: Option<Rc<dyn IServerObject>>) {
302 let old_value = self.shadow.borrow().clone();
303 let mut changed = false;
304 if old_value.differs(&value) {
305 ServerSpriteVisualHooks::on_shadow_changing(host);
306 changed = true;
307 }
308 host.set_value(
309 Self::id_of_shadow_property().base(),
310 ServerValueChange {
311 equal: old_value.default_equals(&value),
312 old_resource: old_value.as_server_render_resource(),
313 new_resource: value.as_server_render_resource(),
314 assign: &mut || *self.shadow.borrow_mut() = value.clone(),
315 },
316 );
317 if changed {
318 ServerSpriteVisualHooks::on_shadow_changed(host);
319 }
320 }
321
322 pub fn deserialize_changes_core(
325 &self,
326 host: &dyn ServerSpriteVisualHooks,
327 reader: &mut BatchStreamReader<'_>,
328 committed_at: Duration,
329 ) {
330 let compositor = host.server_compositor();
331 ServerSpriteVisualHooks::base_deserialize_changes_core(host, reader, committed_at);
332 ServerSpriteVisualHooks::deserialize_changes_extra(host, reader);
333 let changed = reader.read::<SpriteVisualChangedFields>();
334 if changed.contains(SpriteVisualChangedFields::BRUSH) {
335 let value = read_server_object(reader, compositor.as_ref());
336 self.set_brush(host, value);
337 }
338 if changed.contains(SpriteVisualChangedFields::SHADOW) {
339 let value = read_server_object(reader, compositor.as_ref());
340 self.set_shadow(host, value);
341 }
342 ServerSpriteVisualHooks::on_fields_deserialized(host, changed);
343 }
344}