Skip to main content

ferroui_base/rendering/composition/generated/
composition_visual.rs

1// @generated by scripts/generate_composition.py — do not edit
2
3//! `CompositionVisual`.
4//!
5//! Schema attributes: abstract.
6
7use bitflags::bitflags;
8use crate::Matrix;
9use crate::Vector;
10use crate::Vector3D;
11use crate::media::IBrush;
12use crate::media::IImmutableEffect;
13use crate::media::RenderOptions;
14use crate::media::TextOptions;
15use crate::numerics::Quaternion;
16use crate::platform::IGeometryImpl;
17use crate::rendering::composition::ICompositionObject;
18use crate::rendering::composition::ICompositionObjectHost;
19use crate::rendering::composition::animations::AnimationInstanceFactory;
20use crate::rendering::composition::animations::ICompositionAnimation;
21use crate::rendering::composition::expressions::ExpressionVariant;
22use crate::rendering::composition::server::AsServerRenderResource;
23use crate::rendering::composition::server::CompositionProperty;
24use crate::rendering::composition::server::CompositionPropertyOf;
25use crate::rendering::composition::server::IServerAnimatedPropertyHost;
26use crate::rendering::composition::server::IServerObject;
27use crate::rendering::composition::server::ServerPropertyValue;
28use crate::rendering::composition::server::ServerResourceRef;
29use crate::rendering::composition::server::ServerValueChange;
30use crate::rendering::composition::server::props_of;
31use crate::rendering::composition::server::read_resource;
32use crate::rendering::composition::server::read_server_object;
33use crate::rendering::composition::transport::BatchResource;
34use crate::rendering::composition::transport::BatchStreamReader;
35use crate::rendering::composition::transport::BatchStreamWriter;
36use crate::rendering::composition::transport::BatchValue;
37use crate::rendering::composition::transport::BatchValueReader;
38use std::any::Any;
39use std::any::TypeId;
40use std::cell::Cell;
41use std::cell::RefCell;
42use std::rc::Rc;
43use std::sync::Arc;
44use std::sync::OnceLock;
45use std::time::Duration;
46
47bitflags! {
48    /// The fields of `CompositionVisual` that changed since its last serialization.
49    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
50    pub struct CompositionVisualChangedFields: u64 {
51        const ROOT = 1;
52        const PARENT = 2;
53        const VISIBLE = 4;
54        const VISIBLE_ANIMATED = 8;
55        const OPACITY = 16;
56        const OPACITY_ANIMATED = 32;
57        const CLIP = 64;
58        const CLIP_TO_BOUNDS = 128;
59        const CLIP_TO_BOUNDS_ANIMATED = 256;
60        const OFFSET = 512;
61        const OFFSET_ANIMATED = 1024;
62        const TRANSLATION = 2048;
63        const TRANSLATION_ANIMATED = 4096;
64        const SIZE = 8192;
65        const SIZE_ANIMATED = 16384;
66        const ANCHOR_POINT = 32768;
67        const ANCHOR_POINT_ANIMATED = 65536;
68        const CENTER_POINT = 131072;
69        const CENTER_POINT_ANIMATED = 262144;
70        const ROTATION_ANGLE = 524288;
71        const ROTATION_ANGLE_ANIMATED = 1048576;
72        const ORIENTATION = 2097152;
73        const ORIENTATION_ANIMATED = 4194304;
74        const SCALE = 8388608;
75        const SCALE_ANIMATED = 16777216;
76        const TRANSFORM_MATRIX = 33554432;
77        const TRANSFORM_MATRIX_ANIMATED = 67108864;
78        const ADORNED_VISUAL = 134217728;
79        const ADORNER_IS_CLIPPED = 268435456;
80        const OPACITY_MASK_BRUSH = 536870912;
81        const EFFECT = 1073741824;
82        const RENDER_OPTIONS = 2147483648;
83        const TEXT_OPTIONS = 4294967296;
84        const CACHE_MODE = 8589934592;
85    }
86}
87
88impl BatchValue for CompositionVisualChangedFields {
89    #[inline]
90    fn write_to(&self, out: &mut Vec<u8>) {
91        self.bits().write_to(out);
92    }
93
94    #[inline]
95    fn read_from(input: &mut BatchValueReader<'_>) -> Self {
96        CompositionVisualChangedFields::from_bits_retain(u64::read_from(input))
97    }
98}
99
100/// The partial methods of `CompositionVisual`: implemented by the class that embeds
101/// [`CompositionVisualProps`]. Every hook defaults to doing nothing.
102pub trait CompositionVisualHooks: ICompositionObjectHost {
103    fn initialize_defaults_extra(&self) {}
104
105    fn validate_root_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
106    fn on_root_changed(&self) {}
107    fn on_root_changing(&self) {}
108
109    fn validate_parent_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
110    fn on_parent_changed(&self) {}
111    fn on_parent_changing(&self) {}
112
113    fn validate_visible_change(&self, _old_value: bool, _new_value: bool) {}
114    fn on_visible_changed(&self) {}
115    fn on_visible_changing(&self) {}
116
117    fn validate_opacity_change(&self, _old_value: f32, _new_value: f32) {}
118    fn on_opacity_changed(&self) {}
119    fn on_opacity_changing(&self) {}
120
121    fn validate_clip_change(&self, _old_value: &Option<Arc<dyn IGeometryImpl>>, _new_value: &Option<Arc<dyn IGeometryImpl>>) {}
122    fn on_clip_changed(&self) {}
123    fn on_clip_changing(&self) {}
124
125    fn validate_clip_to_bounds_change(&self, _old_value: bool, _new_value: bool) {}
126    fn on_clip_to_bounds_changed(&self) {}
127    fn on_clip_to_bounds_changing(&self) {}
128
129    fn validate_offset_change(&self, _old_value: Vector3D, _new_value: Vector3D) {}
130    fn on_offset_changed(&self) {}
131    fn on_offset_changing(&self) {}
132
133    fn validate_translation_change(&self, _old_value: Vector3D, _new_value: Vector3D) {}
134    fn on_translation_changed(&self) {}
135    fn on_translation_changing(&self) {}
136
137    fn validate_size_change(&self, _old_value: Vector, _new_value: Vector) {}
138    fn on_size_changed(&self) {}
139    fn on_size_changing(&self) {}
140
141    fn validate_anchor_point_change(&self, _old_value: Vector, _new_value: Vector) {}
142    fn on_anchor_point_changed(&self) {}
143    fn on_anchor_point_changing(&self) {}
144
145    fn validate_center_point_change(&self, _old_value: Vector3D, _new_value: Vector3D) {}
146    fn on_center_point_changed(&self) {}
147    fn on_center_point_changing(&self) {}
148
149    fn validate_rotation_angle_change(&self, _old_value: f32, _new_value: f32) {}
150    fn on_rotation_angle_changed(&self) {}
151    fn on_rotation_angle_changing(&self) {}
152
153    fn validate_orientation_change(&self, _old_value: Quaternion, _new_value: Quaternion) {}
154    fn on_orientation_changed(&self) {}
155    fn on_orientation_changing(&self) {}
156
157    fn validate_scale_change(&self, _old_value: Vector3D, _new_value: Vector3D) {}
158    fn on_scale_changed(&self) {}
159    fn on_scale_changing(&self) {}
160
161    fn validate_transform_matrix_change(&self, _old_value: Matrix, _new_value: Matrix) {}
162    fn on_transform_matrix_changed(&self) {}
163    fn on_transform_matrix_changing(&self) {}
164
165    fn validate_adorned_visual_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
166    fn on_adorned_visual_changed(&self) {}
167    fn on_adorned_visual_changing(&self) {}
168
169    fn validate_adorner_is_clipped_change(&self, _old_value: bool, _new_value: bool) {}
170    fn on_adorner_is_clipped_changed(&self) {}
171    fn on_adorner_is_clipped_changing(&self) {}
172
173    fn validate_opacity_mask_brush_change(&self, _old_value: &Option<BatchResource<dyn IBrush>>, _new_value: &Option<BatchResource<dyn IBrush>>) {}
174    fn on_opacity_mask_brush_changed(&self) {}
175    fn on_opacity_mask_brush_changing(&self) {}
176
177    fn validate_effect_change(&self, _old_value: &Option<Arc<dyn IImmutableEffect>>, _new_value: &Option<Arc<dyn IImmutableEffect>>) {}
178    fn on_effect_changed(&self) {}
179    fn on_effect_changing(&self) {}
180
181    fn validate_render_options_change(&self, _old_value: RenderOptions, _new_value: RenderOptions) {}
182    fn on_render_options_changed(&self) {}
183    fn on_render_options_changing(&self) {}
184
185    fn validate_text_options_change(&self, _old_value: TextOptions, _new_value: TextOptions) {}
186    fn on_text_options_changed(&self) {}
187    fn on_text_options_changing(&self) {}
188
189    fn validate_cache_mode_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
190    fn on_cache_mode_changed(&self) {}
191    fn on_cache_mode_changing(&self) {}
192}
193
194/// The UI-thread properties of `CompositionVisual`.
195pub struct CompositionVisualProps {
196    changed_fields_of_composition_visual: Cell<CompositionVisualChangedFields>,
197    root: RefCell<Option<Rc<dyn ICompositionObject>>>,
198    parent: RefCell<Option<Rc<dyn ICompositionObject>>>,
199    visible: Cell<bool>,
200    opacity: Cell<f32>,
201    clip: RefCell<Option<Arc<dyn IGeometryImpl>>>,
202    clip_to_bounds: Cell<bool>,
203    offset: Cell<Vector3D>,
204    translation: Cell<Vector3D>,
205    size: Cell<Vector>,
206    anchor_point: Cell<Vector>,
207    center_point: Cell<Vector3D>,
208    rotation_angle: Cell<f32>,
209    orientation: Cell<Quaternion>,
210    scale: Cell<Vector3D>,
211    transform_matrix: Cell<Matrix>,
212    adorned_visual: RefCell<Option<Rc<dyn ICompositionObject>>>,
213    adorner_is_clipped: Cell<bool>,
214    opacity_mask_brush: RefCell<Option<BatchResource<dyn IBrush>>>,
215    effect: RefCell<Option<Arc<dyn IImmutableEffect>>>,
216    render_options: Cell<RenderOptions>,
217    text_options: Cell<TextOptions>,
218    cache_mode: RefCell<Option<Rc<dyn ICompositionObject>>>,
219}
220
221impl Default for CompositionVisualProps {
222    fn default() -> Self {
223        Self::new()
224    }
225}
226
227impl CompositionVisualProps {
228    /// Creates the properties with every field at the default of its type.
229    /// The defaults of the schema are applied by
230    /// [`initialize_defaults`](Self::initialize_defaults).
231    pub fn new() -> Self {
232        Self {
233            changed_fields_of_composition_visual: Cell::new(CompositionVisualChangedFields::empty()),
234            root: RefCell::new(None),
235            parent: RefCell::new(None),
236            visible: Cell::new(Default::default()),
237            opacity: Cell::new(Default::default()),
238            clip: RefCell::new(None),
239            clip_to_bounds: Cell::new(Default::default()),
240            offset: Cell::new(Default::default()),
241            translation: Cell::new(Default::default()),
242            size: Cell::new(Default::default()),
243            anchor_point: Cell::new(Default::default()),
244            center_point: Cell::new(Default::default()),
245            rotation_angle: Cell::new(Default::default()),
246            orientation: Cell::new(Default::default()),
247            scale: Cell::new(Default::default()),
248            transform_matrix: Cell::new(Default::default()),
249            adorned_visual: RefCell::new(None),
250            adorner_is_clipped: Cell::new(Default::default()),
251            opacity_mask_brush: RefCell::new(None),
252            effect: RefCell::new(None),
253            render_options: Cell::new(Default::default()),
254            text_options: Cell::new(Default::default()),
255            cache_mode: RefCell::new(None),
256        }
257    }
258
259    /// The `InitializeDefaults` calls of the constructor chain: the base
260    /// classes first, then this class.
261    pub fn initialize_defaults(&self, host: &dyn CompositionVisualHooks) {
262        self.initialize_own_defaults(host);
263    }
264
265    /// `InitializeDefaults` of this class alone.
266    pub fn initialize_own_defaults(&self, host: &dyn CompositionVisualHooks) {
267        CompositionVisualHooks::initialize_defaults_extra(host);
268        self.set_visible(host, true);
269        self.set_opacity(host, 1.0);
270        self.set_clip_to_bounds(host, true);
271        self.set_orientation(host, Quaternion::IDENTITY);
272        self.set_scale(host, Vector3D::new(1.0, 1.0, 1.0));
273        self.set_transform_matrix(host, Matrix::IDENTITY);
274    }
275
276    /// `Root` (internal).
277    pub fn root(&self) -> Option<Rc<dyn ICompositionObject>> {
278        self.root.borrow().clone()
279    }
280
281    /// Sets `Root` (internal).
282    pub fn set_root(&self, host: &dyn CompositionVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
283        let mut changed = false;
284        let old_value = self.root.borrow().clone();
285        if old_value.differs(&value) {
286            CompositionVisualHooks::validate_root_change(host, &old_value, &value);
287            CompositionVisualHooks::on_root_changing(host);
288            changed = true;
289            // Update the backing value
290            *self.root.borrow_mut() = value.clone();
291            // Register object for serialization in the next batch
292            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ROOT);
293            host.register_for_serialization();
294        }
295        *self.root.borrow_mut() = value;
296        if changed {
297            CompositionVisualHooks::on_root_changed(host);
298        }
299    }
300
301    /// `Parent` (internal).
302    pub fn parent(&self) -> Option<Rc<dyn ICompositionObject>> {
303        self.parent.borrow().clone()
304    }
305
306    /// Sets `Parent` (internal).
307    pub fn set_parent(&self, host: &dyn CompositionVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
308        let mut changed = false;
309        let old_value = self.parent.borrow().clone();
310        if old_value.differs(&value) {
311            CompositionVisualHooks::validate_parent_change(host, &old_value, &value);
312            CompositionVisualHooks::on_parent_changing(host);
313            changed = true;
314            // Update the backing value
315            *self.parent.borrow_mut() = value.clone();
316            // Register object for serialization in the next batch
317            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::PARENT);
318            host.register_for_serialization();
319        }
320        *self.parent.borrow_mut() = value;
321        if changed {
322            CompositionVisualHooks::on_parent_changed(host);
323        }
324    }
325
326    /// `Visible` (animated, default `true`).
327    pub fn visible(&self) -> bool {
328        self.visible.get()
329    }
330
331    /// Sets `Visible` (animated, default `true`).
332    pub fn set_visible(&self, host: &dyn CompositionVisualHooks, value: bool) {
333        let mut changed = false;
334        let old_value = self.visible.get();
335        if old_value.differs(&value) {
336            CompositionVisualHooks::validate_visible_change(host, old_value, value);
337            CompositionVisualHooks::on_visible_changing(host);
338            changed = true;
339            // Update the backing value
340            self.visible.set(value);
341            // Register object for serialization in the next batch
342            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::VISIBLE);
343            host.register_for_serialization();
344            // Reset previous animation if any
345            host.pending_animations().remove(ServerCompositionVisualProps::id_of_visible_property().base());
346            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::VISIBLE_ANIMATED);
347            // Check for implicit animations
348            if let Some(animation) = host.implicit_animation("Visible") {
349                // Animation affects only current property
350                if let Some(a) = animation.as_composition_animation() {
351                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::VISIBLE_ANIMATED);
352                    host.pending_animations().set(
353                        ServerCompositionVisualProps::id_of_visible_property().base(),
354                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
355                    );
356                }
357                // Animation is triggered by the current field, but does not necessary affects it
358                host.start_animation_group(&animation, "Visible", ExpressionVariant::create(value));
359            }
360        }
361        self.visible.set(value);
362        if changed {
363            CompositionVisualHooks::on_visible_changed(host);
364        }
365    }
366
367    /// `Opacity` (animated, default `1.0`).
368    pub fn opacity(&self) -> f32 {
369        self.opacity.get()
370    }
371
372    /// Sets `Opacity` (animated, default `1.0`).
373    pub fn set_opacity(&self, host: &dyn CompositionVisualHooks, value: f32) {
374        let mut changed = false;
375        let old_value = self.opacity.get();
376        if old_value.differs(&value) {
377            CompositionVisualHooks::validate_opacity_change(host, old_value, value);
378            CompositionVisualHooks::on_opacity_changing(host);
379            changed = true;
380            // Update the backing value
381            self.opacity.set(value);
382            // Register object for serialization in the next batch
383            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OPACITY);
384            host.register_for_serialization();
385            // Reset previous animation if any
386            host.pending_animations().remove(ServerCompositionVisualProps::id_of_opacity_property().base());
387            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::OPACITY_ANIMATED);
388            // Check for implicit animations
389            if let Some(animation) = host.implicit_animation("Opacity") {
390                // Animation affects only current property
391                if let Some(a) = animation.as_composition_animation() {
392                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OPACITY_ANIMATED);
393                    host.pending_animations().set(
394                        ServerCompositionVisualProps::id_of_opacity_property().base(),
395                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
396                    );
397                }
398                // Animation is triggered by the current field, but does not necessary affects it
399                host.start_animation_group(&animation, "Opacity", ExpressionVariant::create(value));
400            }
401        }
402        self.opacity.set(value);
403        if changed {
404            CompositionVisualHooks::on_opacity_changed(host);
405        }
406    }
407
408    /// `Clip` (internal).
409    pub fn clip(&self) -> Option<Arc<dyn IGeometryImpl>> {
410        self.clip.borrow().clone()
411    }
412
413    /// Sets `Clip` (internal).
414    pub fn set_clip(&self, host: &dyn CompositionVisualHooks, value: Option<Arc<dyn IGeometryImpl>>) {
415        let mut changed = false;
416        let old_value = self.clip.borrow().clone();
417        if old_value.differs(&value) {
418            CompositionVisualHooks::validate_clip_change(host, &old_value, &value);
419            CompositionVisualHooks::on_clip_changing(host);
420            changed = true;
421            // Update the backing value
422            *self.clip.borrow_mut() = value.clone();
423            // Register object for serialization in the next batch
424            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CLIP);
425            host.register_for_serialization();
426        }
427        *self.clip.borrow_mut() = value;
428        if changed {
429            CompositionVisualHooks::on_clip_changed(host);
430        }
431    }
432
433    /// `ClipToBounds` (animated, default `true`).
434    pub fn clip_to_bounds(&self) -> bool {
435        self.clip_to_bounds.get()
436    }
437
438    /// Sets `ClipToBounds` (animated, default `true`).
439    pub fn set_clip_to_bounds(&self, host: &dyn CompositionVisualHooks, value: bool) {
440        let mut changed = false;
441        let old_value = self.clip_to_bounds.get();
442        if old_value.differs(&value) {
443            CompositionVisualHooks::validate_clip_to_bounds_change(host, old_value, value);
444            CompositionVisualHooks::on_clip_to_bounds_changing(host);
445            changed = true;
446            // Update the backing value
447            self.clip_to_bounds.set(value);
448            // Register object for serialization in the next batch
449            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CLIP_TO_BOUNDS);
450            host.register_for_serialization();
451            // Reset previous animation if any
452            host.pending_animations().remove(ServerCompositionVisualProps::id_of_clip_to_bounds_property().base());
453            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::CLIP_TO_BOUNDS_ANIMATED);
454            // Check for implicit animations
455            if let Some(animation) = host.implicit_animation("ClipToBounds") {
456                // Animation affects only current property
457                if let Some(a) = animation.as_composition_animation() {
458                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CLIP_TO_BOUNDS_ANIMATED);
459                    host.pending_animations().set(
460                        ServerCompositionVisualProps::id_of_clip_to_bounds_property().base(),
461                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
462                    );
463                }
464                // Animation is triggered by the current field, but does not necessary affects it
465                host.start_animation_group(&animation, "ClipToBounds", ExpressionVariant::create(value));
466            }
467        }
468        self.clip_to_bounds.set(value);
469        if changed {
470            CompositionVisualHooks::on_clip_to_bounds_changed(host);
471        }
472    }
473
474    /// `Offset` (animated).
475    pub fn offset(&self) -> Vector3D {
476        self.offset.get()
477    }
478
479    /// Sets `Offset` (animated).
480    pub fn set_offset(&self, host: &dyn CompositionVisualHooks, value: Vector3D) {
481        let mut changed = false;
482        let old_value = self.offset.get();
483        if old_value.differs(&value) {
484            CompositionVisualHooks::validate_offset_change(host, old_value, value);
485            CompositionVisualHooks::on_offset_changing(host);
486            changed = true;
487            // Update the backing value
488            self.offset.set(value);
489            // Register object for serialization in the next batch
490            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OFFSET);
491            host.register_for_serialization();
492            // Reset previous animation if any
493            host.pending_animations().remove(ServerCompositionVisualProps::id_of_offset_property().base());
494            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::OFFSET_ANIMATED);
495            // Check for implicit animations
496            if let Some(animation) = host.implicit_animation("Offset") {
497                // Animation affects only current property
498                if let Some(a) = animation.as_composition_animation() {
499                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OFFSET_ANIMATED);
500                    host.pending_animations().set(
501                        ServerCompositionVisualProps::id_of_offset_property().base(),
502                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
503                    );
504                }
505                // Animation is triggered by the current field, but does not necessary affects it
506                host.start_animation_group(&animation, "Offset", ExpressionVariant::create(value));
507            }
508        }
509        self.offset.set(value);
510        if changed {
511            CompositionVisualHooks::on_offset_changed(host);
512        }
513    }
514
515    /// `Translation` (animated).
516    pub fn translation(&self) -> Vector3D {
517        self.translation.get()
518    }
519
520    /// Sets `Translation` (animated).
521    pub fn set_translation(&self, host: &dyn CompositionVisualHooks, value: Vector3D) {
522        let mut changed = false;
523        let old_value = self.translation.get();
524        if old_value.differs(&value) {
525            CompositionVisualHooks::validate_translation_change(host, old_value, value);
526            CompositionVisualHooks::on_translation_changing(host);
527            changed = true;
528            // Update the backing value
529            self.translation.set(value);
530            // Register object for serialization in the next batch
531            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSLATION);
532            host.register_for_serialization();
533            // Reset previous animation if any
534            host.pending_animations().remove(ServerCompositionVisualProps::id_of_translation_property().base());
535            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::TRANSLATION_ANIMATED);
536            // Check for implicit animations
537            if let Some(animation) = host.implicit_animation("Translation") {
538                // Animation affects only current property
539                if let Some(a) = animation.as_composition_animation() {
540                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSLATION_ANIMATED);
541                    host.pending_animations().set(
542                        ServerCompositionVisualProps::id_of_translation_property().base(),
543                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
544                    );
545                }
546                // Animation is triggered by the current field, but does not necessary affects it
547                host.start_animation_group(&animation, "Translation", ExpressionVariant::create(value));
548            }
549        }
550        self.translation.set(value);
551        if changed {
552            CompositionVisualHooks::on_translation_changed(host);
553        }
554    }
555
556    /// `Size` (animated).
557    pub fn size(&self) -> Vector {
558        self.size.get()
559    }
560
561    /// Sets `Size` (animated).
562    pub fn set_size(&self, host: &dyn CompositionVisualHooks, value: Vector) {
563        let mut changed = false;
564        let old_value = self.size.get();
565        if old_value.differs(&value) {
566            CompositionVisualHooks::validate_size_change(host, old_value, value);
567            CompositionVisualHooks::on_size_changing(host);
568            changed = true;
569            // Update the backing value
570            self.size.set(value);
571            // Register object for serialization in the next batch
572            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SIZE);
573            host.register_for_serialization();
574            // Reset previous animation if any
575            host.pending_animations().remove(ServerCompositionVisualProps::id_of_size_property().base());
576            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::SIZE_ANIMATED);
577            // Check for implicit animations
578            if let Some(animation) = host.implicit_animation("Size") {
579                // Animation affects only current property
580                if let Some(a) = animation.as_composition_animation() {
581                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SIZE_ANIMATED);
582                    host.pending_animations().set(
583                        ServerCompositionVisualProps::id_of_size_property().base(),
584                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
585                    );
586                }
587                // Animation is triggered by the current field, but does not necessary affects it
588                host.start_animation_group(&animation, "Size", ExpressionVariant::create(value));
589            }
590        }
591        self.size.set(value);
592        if changed {
593            CompositionVisualHooks::on_size_changed(host);
594        }
595    }
596
597    /// `AnchorPoint` (animated).
598    pub fn anchor_point(&self) -> Vector {
599        self.anchor_point.get()
600    }
601
602    /// Sets `AnchorPoint` (animated).
603    pub fn set_anchor_point(&self, host: &dyn CompositionVisualHooks, value: Vector) {
604        let mut changed = false;
605        let old_value = self.anchor_point.get();
606        if old_value.differs(&value) {
607            CompositionVisualHooks::validate_anchor_point_change(host, old_value, value);
608            CompositionVisualHooks::on_anchor_point_changing(host);
609            changed = true;
610            // Update the backing value
611            self.anchor_point.set(value);
612            // Register object for serialization in the next batch
613            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ANCHOR_POINT);
614            host.register_for_serialization();
615            // Reset previous animation if any
616            host.pending_animations().remove(ServerCompositionVisualProps::id_of_anchor_point_property().base());
617            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::ANCHOR_POINT_ANIMATED);
618            // Check for implicit animations
619            if let Some(animation) = host.implicit_animation("AnchorPoint") {
620                // Animation affects only current property
621                if let Some(a) = animation.as_composition_animation() {
622                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ANCHOR_POINT_ANIMATED);
623                    host.pending_animations().set(
624                        ServerCompositionVisualProps::id_of_anchor_point_property().base(),
625                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
626                    );
627                }
628                // Animation is triggered by the current field, but does not necessary affects it
629                host.start_animation_group(&animation, "AnchorPoint", ExpressionVariant::create(value));
630            }
631        }
632        self.anchor_point.set(value);
633        if changed {
634            CompositionVisualHooks::on_anchor_point_changed(host);
635        }
636    }
637
638    /// `CenterPoint` (animated).
639    pub fn center_point(&self) -> Vector3D {
640        self.center_point.get()
641    }
642
643    /// Sets `CenterPoint` (animated).
644    pub fn set_center_point(&self, host: &dyn CompositionVisualHooks, value: Vector3D) {
645        let mut changed = false;
646        let old_value = self.center_point.get();
647        if old_value.differs(&value) {
648            CompositionVisualHooks::validate_center_point_change(host, old_value, value);
649            CompositionVisualHooks::on_center_point_changing(host);
650            changed = true;
651            // Update the backing value
652            self.center_point.set(value);
653            // Register object for serialization in the next batch
654            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CENTER_POINT);
655            host.register_for_serialization();
656            // Reset previous animation if any
657            host.pending_animations().remove(ServerCompositionVisualProps::id_of_center_point_property().base());
658            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::CENTER_POINT_ANIMATED);
659            // Check for implicit animations
660            if let Some(animation) = host.implicit_animation("CenterPoint") {
661                // Animation affects only current property
662                if let Some(a) = animation.as_composition_animation() {
663                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CENTER_POINT_ANIMATED);
664                    host.pending_animations().set(
665                        ServerCompositionVisualProps::id_of_center_point_property().base(),
666                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
667                    );
668                }
669                // Animation is triggered by the current field, but does not necessary affects it
670                host.start_animation_group(&animation, "CenterPoint", ExpressionVariant::create(value));
671            }
672        }
673        self.center_point.set(value);
674        if changed {
675            CompositionVisualHooks::on_center_point_changed(host);
676        }
677    }
678
679    /// `RotationAngle` (animated).
680    pub fn rotation_angle(&self) -> f32 {
681        self.rotation_angle.get()
682    }
683
684    /// Sets `RotationAngle` (animated).
685    pub fn set_rotation_angle(&self, host: &dyn CompositionVisualHooks, value: f32) {
686        let mut changed = false;
687        let old_value = self.rotation_angle.get();
688        if old_value.differs(&value) {
689            CompositionVisualHooks::validate_rotation_angle_change(host, old_value, value);
690            CompositionVisualHooks::on_rotation_angle_changing(host);
691            changed = true;
692            // Update the backing value
693            self.rotation_angle.set(value);
694            // Register object for serialization in the next batch
695            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ROTATION_ANGLE);
696            host.register_for_serialization();
697            // Reset previous animation if any
698            host.pending_animations().remove(ServerCompositionVisualProps::id_of_rotation_angle_property().base());
699            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::ROTATION_ANGLE_ANIMATED);
700            // Check for implicit animations
701            if let Some(animation) = host.implicit_animation("RotationAngle") {
702                // Animation affects only current property
703                if let Some(a) = animation.as_composition_animation() {
704                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ROTATION_ANGLE_ANIMATED);
705                    host.pending_animations().set(
706                        ServerCompositionVisualProps::id_of_rotation_angle_property().base(),
707                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
708                    );
709                }
710                // Animation is triggered by the current field, but does not necessary affects it
711                host.start_animation_group(&animation, "RotationAngle", ExpressionVariant::create(value));
712            }
713        }
714        self.rotation_angle.set(value);
715        if changed {
716            CompositionVisualHooks::on_rotation_angle_changed(host);
717        }
718    }
719
720    /// `Orientation` (animated, default `Quaternion::IDENTITY`).
721    pub fn orientation(&self) -> Quaternion {
722        self.orientation.get()
723    }
724
725    /// Sets `Orientation` (animated, default `Quaternion::IDENTITY`).
726    pub fn set_orientation(&self, host: &dyn CompositionVisualHooks, value: Quaternion) {
727        let mut changed = false;
728        let old_value = self.orientation.get();
729        if old_value.differs(&value) {
730            CompositionVisualHooks::validate_orientation_change(host, old_value, value);
731            CompositionVisualHooks::on_orientation_changing(host);
732            changed = true;
733            // Update the backing value
734            self.orientation.set(value);
735            // Register object for serialization in the next batch
736            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ORIENTATION);
737            host.register_for_serialization();
738            // Reset previous animation if any
739            host.pending_animations().remove(ServerCompositionVisualProps::id_of_orientation_property().base());
740            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::ORIENTATION_ANIMATED);
741            // Check for implicit animations
742            if let Some(animation) = host.implicit_animation("Orientation") {
743                // Animation affects only current property
744                if let Some(a) = animation.as_composition_animation() {
745                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ORIENTATION_ANIMATED);
746                    host.pending_animations().set(
747                        ServerCompositionVisualProps::id_of_orientation_property().base(),
748                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
749                    );
750                }
751                // Animation is triggered by the current field, but does not necessary affects it
752                host.start_animation_group(&animation, "Orientation", ExpressionVariant::create(value));
753            }
754        }
755        self.orientation.set(value);
756        if changed {
757            CompositionVisualHooks::on_orientation_changed(host);
758        }
759    }
760
761    /// `Scale` (animated, default `Vector3D::new(1.0, 1.0, 1.0)`).
762    pub fn scale(&self) -> Vector3D {
763        self.scale.get()
764    }
765
766    /// Sets `Scale` (animated, default `Vector3D::new(1.0, 1.0, 1.0)`).
767    pub fn set_scale(&self, host: &dyn CompositionVisualHooks, value: Vector3D) {
768        let mut changed = false;
769        let old_value = self.scale.get();
770        if old_value.differs(&value) {
771            CompositionVisualHooks::validate_scale_change(host, old_value, value);
772            CompositionVisualHooks::on_scale_changing(host);
773            changed = true;
774            // Update the backing value
775            self.scale.set(value);
776            // Register object for serialization in the next batch
777            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SCALE);
778            host.register_for_serialization();
779            // Reset previous animation if any
780            host.pending_animations().remove(ServerCompositionVisualProps::id_of_scale_property().base());
781            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::SCALE_ANIMATED);
782            // Check for implicit animations
783            if let Some(animation) = host.implicit_animation("Scale") {
784                // Animation affects only current property
785                if let Some(a) = animation.as_composition_animation() {
786                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SCALE_ANIMATED);
787                    host.pending_animations().set(
788                        ServerCompositionVisualProps::id_of_scale_property().base(),
789                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
790                    );
791                }
792                // Animation is triggered by the current field, but does not necessary affects it
793                host.start_animation_group(&animation, "Scale", ExpressionVariant::create(value));
794            }
795        }
796        self.scale.set(value);
797        if changed {
798            CompositionVisualHooks::on_scale_changed(host);
799        }
800    }
801
802    /// `TransformMatrix` (internal, animated, default `Matrix::IDENTITY`).
803    pub fn transform_matrix(&self) -> Matrix {
804        self.transform_matrix.get()
805    }
806
807    /// Sets `TransformMatrix` (internal, animated, default `Matrix::IDENTITY`).
808    pub fn set_transform_matrix(&self, host: &dyn CompositionVisualHooks, value: Matrix) {
809        let mut changed = false;
810        let old_value = self.transform_matrix.get();
811        if old_value.differs(&value) {
812            CompositionVisualHooks::validate_transform_matrix_change(host, old_value, value);
813            CompositionVisualHooks::on_transform_matrix_changing(host);
814            changed = true;
815            // Update the backing value
816            self.transform_matrix.set(value);
817            // Register object for serialization in the next batch
818            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSFORM_MATRIX);
819            host.register_for_serialization();
820            // Reset previous animation if any
821            host.pending_animations().remove(ServerCompositionVisualProps::id_of_transform_matrix_property().base());
822            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::TRANSFORM_MATRIX_ANIMATED);
823            // Check for implicit animations
824            if let Some(animation) = host.implicit_animation("TransformMatrix") {
825                // Animation affects only current property
826                if let Some(a) = animation.as_composition_animation() {
827                    self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSFORM_MATRIX_ANIMATED);
828                    host.pending_animations().set(
829                        ServerCompositionVisualProps::id_of_transform_matrix_property().base(),
830                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
831                    );
832                }
833                // Animation is triggered by the current field, but does not necessary affects it
834                host.start_animation_group(&animation, "TransformMatrix", ExpressionVariant::create(value));
835            }
836        }
837        self.transform_matrix.set(value);
838        if changed {
839            CompositionVisualHooks::on_transform_matrix_changed(host);
840        }
841    }
842
843    /// `AdornedVisual` (internal).
844    pub fn adorned_visual(&self) -> Option<Rc<dyn ICompositionObject>> {
845        self.adorned_visual.borrow().clone()
846    }
847
848    /// Sets `AdornedVisual` (internal).
849    pub fn set_adorned_visual(&self, host: &dyn CompositionVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
850        let mut changed = false;
851        let old_value = self.adorned_visual.borrow().clone();
852        if old_value.differs(&value) {
853            CompositionVisualHooks::validate_adorned_visual_change(host, &old_value, &value);
854            CompositionVisualHooks::on_adorned_visual_changing(host);
855            changed = true;
856            // Update the backing value
857            *self.adorned_visual.borrow_mut() = value.clone();
858            // Register object for serialization in the next batch
859            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ADORNED_VISUAL);
860            host.register_for_serialization();
861        }
862        *self.adorned_visual.borrow_mut() = value;
863        if changed {
864            CompositionVisualHooks::on_adorned_visual_changed(host);
865        }
866    }
867
868    /// `AdornerIsClipped` (internal).
869    pub fn adorner_is_clipped(&self) -> bool {
870        self.adorner_is_clipped.get()
871    }
872
873    /// Sets `AdornerIsClipped` (internal).
874    pub fn set_adorner_is_clipped(&self, host: &dyn CompositionVisualHooks, value: bool) {
875        let mut changed = false;
876        let old_value = self.adorner_is_clipped.get();
877        if old_value.differs(&value) {
878            CompositionVisualHooks::validate_adorner_is_clipped_change(host, old_value, value);
879            CompositionVisualHooks::on_adorner_is_clipped_changing(host);
880            changed = true;
881            // Update the backing value
882            self.adorner_is_clipped.set(value);
883            // Register object for serialization in the next batch
884            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ADORNER_IS_CLIPPED);
885            host.register_for_serialization();
886        }
887        self.adorner_is_clipped.set(value);
888        if changed {
889            CompositionVisualHooks::on_adorner_is_clipped_changed(host);
890        }
891    }
892
893    /// `OpacityMaskBrush` (private to the class).
894    pub fn opacity_mask_brush_transport_field(&self) -> Option<BatchResource<dyn IBrush>> {
895        self.opacity_mask_brush.borrow().clone()
896    }
897
898    /// Sets `OpacityMaskBrush` (private to the class).
899    pub fn set_opacity_mask_brush_transport_field(&self, host: &dyn CompositionVisualHooks, value: Option<BatchResource<dyn IBrush>>) {
900        let mut changed = false;
901        let old_value = self.opacity_mask_brush.borrow().clone();
902        if old_value.differs(&value) {
903            CompositionVisualHooks::validate_opacity_mask_brush_change(host, &old_value, &value);
904            CompositionVisualHooks::on_opacity_mask_brush_changing(host);
905            changed = true;
906            // Update the backing value
907            *self.opacity_mask_brush.borrow_mut() = value.clone();
908            // Register object for serialization in the next batch
909            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OPACITY_MASK_BRUSH);
910            host.register_for_serialization();
911        }
912        *self.opacity_mask_brush.borrow_mut() = value;
913        if changed {
914            CompositionVisualHooks::on_opacity_mask_brush_changed(host);
915        }
916    }
917
918    /// `Effect` (internal).
919    pub fn effect(&self) -> Option<Arc<dyn IImmutableEffect>> {
920        self.effect.borrow().clone()
921    }
922
923    /// Sets `Effect` (internal).
924    pub fn set_effect(&self, host: &dyn CompositionVisualHooks, value: Option<Arc<dyn IImmutableEffect>>) {
925        let mut changed = false;
926        let old_value = self.effect.borrow().clone();
927        if old_value.differs(&value) {
928            CompositionVisualHooks::validate_effect_change(host, &old_value, &value);
929            CompositionVisualHooks::on_effect_changing(host);
930            changed = true;
931            // Update the backing value
932            *self.effect.borrow_mut() = value.clone();
933            // Register object for serialization in the next batch
934            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::EFFECT);
935            host.register_for_serialization();
936        }
937        *self.effect.borrow_mut() = value;
938        if changed {
939            CompositionVisualHooks::on_effect_changed(host);
940        }
941    }
942
943    /// `RenderOptions`.
944    pub fn render_options(&self) -> RenderOptions {
945        self.render_options.get()
946    }
947
948    /// Sets `RenderOptions`.
949    pub fn set_render_options(&self, host: &dyn CompositionVisualHooks, value: RenderOptions) {
950        let mut changed = false;
951        let old_value = self.render_options.get();
952        if old_value.differs(&value) {
953            CompositionVisualHooks::validate_render_options_change(host, old_value, value);
954            CompositionVisualHooks::on_render_options_changing(host);
955            changed = true;
956            // Update the backing value
957            self.render_options.set(value);
958            // Register object for serialization in the next batch
959            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::RENDER_OPTIONS);
960            host.register_for_serialization();
961        }
962        self.render_options.set(value);
963        if changed {
964            CompositionVisualHooks::on_render_options_changed(host);
965        }
966    }
967
968    /// `TextOptions`.
969    pub fn text_options(&self) -> TextOptions {
970        self.text_options.get()
971    }
972
973    /// Sets `TextOptions`.
974    pub fn set_text_options(&self, host: &dyn CompositionVisualHooks, value: TextOptions) {
975        let mut changed = false;
976        let old_value = self.text_options.get();
977        if old_value.differs(&value) {
978            CompositionVisualHooks::validate_text_options_change(host, old_value, value);
979            CompositionVisualHooks::on_text_options_changing(host);
980            changed = true;
981            // Update the backing value
982            self.text_options.set(value);
983            // Register object for serialization in the next batch
984            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TEXT_OPTIONS);
985            host.register_for_serialization();
986        }
987        self.text_options.set(value);
988        if changed {
989            CompositionVisualHooks::on_text_options_changed(host);
990        }
991    }
992
993    /// `CacheMode` (internal).
994    pub fn cache_mode(&self) -> Option<Rc<dyn ICompositionObject>> {
995        self.cache_mode.borrow().clone()
996    }
997
998    /// Sets `CacheMode` (internal).
999    pub fn set_cache_mode(&self, host: &dyn CompositionVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
1000        let mut changed = false;
1001        let old_value = self.cache_mode.borrow().clone();
1002        if old_value.differs(&value) {
1003            CompositionVisualHooks::validate_cache_mode_change(host, &old_value, &value);
1004            CompositionVisualHooks::on_cache_mode_changing(host);
1005            changed = true;
1006            // Update the backing value
1007            *self.cache_mode.borrow_mut() = value.clone();
1008            // Register object for serialization in the next batch
1009            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CACHE_MODE);
1010            host.register_for_serialization();
1011        }
1012        *self.cache_mode.borrow_mut() = value;
1013        if changed {
1014            CompositionVisualHooks::on_cache_mode_changed(host);
1015        }
1016    }
1017
1018    /// Connects an animation with the named property. Returns `false` when
1019    /// neither this class nor its generated bases have an animated property
1020    /// of that name: the caller continues with its hand-written base.
1021    pub fn start_animation(
1022        &self,
1023        host: &dyn CompositionVisualHooks,
1024        property_name: &str,
1025        animation: &dyn ICompositionAnimation,
1026        final_value: Option<ExpressionVariant>,
1027    ) -> bool {
1028        if property_name == "Visible" {
1029            let server = animation.create_instance(host.server(), final_value);
1030            host.pending_animations().set(ServerCompositionVisualProps::id_of_visible_property().base(), server);
1031            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::VISIBLE_ANIMATED);
1032            host.register_for_serialization();
1033            return true;
1034        }
1035        if property_name == "Opacity" {
1036            let server = animation.create_instance(host.server(), final_value);
1037            host.pending_animations().set(ServerCompositionVisualProps::id_of_opacity_property().base(), server);
1038            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OPACITY_ANIMATED);
1039            host.register_for_serialization();
1040            return true;
1041        }
1042        if property_name == "ClipToBounds" {
1043            let server = animation.create_instance(host.server(), final_value);
1044            host.pending_animations().set(ServerCompositionVisualProps::id_of_clip_to_bounds_property().base(), server);
1045            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CLIP_TO_BOUNDS_ANIMATED);
1046            host.register_for_serialization();
1047            return true;
1048        }
1049        if property_name == "Offset" {
1050            let server = animation.create_instance(host.server(), final_value);
1051            host.pending_animations().set(ServerCompositionVisualProps::id_of_offset_property().base(), server);
1052            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OFFSET_ANIMATED);
1053            host.register_for_serialization();
1054            return true;
1055        }
1056        if property_name == "Translation" {
1057            let server = animation.create_instance(host.server(), final_value);
1058            host.pending_animations().set(ServerCompositionVisualProps::id_of_translation_property().base(), server);
1059            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSLATION_ANIMATED);
1060            host.register_for_serialization();
1061            return true;
1062        }
1063        if property_name == "Size" {
1064            let server = animation.create_instance(host.server(), final_value);
1065            host.pending_animations().set(ServerCompositionVisualProps::id_of_size_property().base(), server);
1066            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SIZE_ANIMATED);
1067            host.register_for_serialization();
1068            return true;
1069        }
1070        if property_name == "AnchorPoint" {
1071            let server = animation.create_instance(host.server(), final_value);
1072            host.pending_animations().set(ServerCompositionVisualProps::id_of_anchor_point_property().base(), server);
1073            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ANCHOR_POINT_ANIMATED);
1074            host.register_for_serialization();
1075            return true;
1076        }
1077        if property_name == "CenterPoint" {
1078            let server = animation.create_instance(host.server(), final_value);
1079            host.pending_animations().set(ServerCompositionVisualProps::id_of_center_point_property().base(), server);
1080            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CENTER_POINT_ANIMATED);
1081            host.register_for_serialization();
1082            return true;
1083        }
1084        if property_name == "RotationAngle" {
1085            let server = animation.create_instance(host.server(), final_value);
1086            host.pending_animations().set(ServerCompositionVisualProps::id_of_rotation_angle_property().base(), server);
1087            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ROTATION_ANGLE_ANIMATED);
1088            host.register_for_serialization();
1089            return true;
1090        }
1091        if property_name == "Orientation" {
1092            let server = animation.create_instance(host.server(), final_value);
1093            host.pending_animations().set(ServerCompositionVisualProps::id_of_orientation_property().base(), server);
1094            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ORIENTATION_ANIMATED);
1095            host.register_for_serialization();
1096            return true;
1097        }
1098        if property_name == "Scale" {
1099            let server = animation.create_instance(host.server(), final_value);
1100            host.pending_animations().set(ServerCompositionVisualProps::id_of_scale_property().base(), server);
1101            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SCALE_ANIMATED);
1102            host.register_for_serialization();
1103            return true;
1104        }
1105        if property_name == "TransformMatrix" {
1106            let server = animation.create_instance(host.server(), final_value);
1107            host.pending_animations().set(ServerCompositionVisualProps::id_of_transform_matrix_property().base(), server);
1108            self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSFORM_MATRIX_ANIMATED);
1109            host.register_for_serialization();
1110            return true;
1111        }
1112        false
1113    }
1114
1115    /// Writes the changes of the object: the base class first, then the
1116    /// changed-fields mask and the changed members of this class.
1117    pub fn serialize_changes_core(&self, host: &dyn CompositionVisualHooks, writer: &mut BatchStreamWriter<'_>) {
1118        let changed = self.changed_fields_of_composition_visual.get();
1119        writer.write(changed);
1120        if changed.contains(CompositionVisualChangedFields::ROOT) {
1121            writer.write_server_object(self.root.borrow().clone().map(|o| o.server()));
1122        }
1123        if changed.contains(CompositionVisualChangedFields::PARENT) {
1124            writer.write_server_object(self.parent.borrow().clone().map(|o| o.server()));
1125        }
1126        if changed.contains(CompositionVisualChangedFields::VISIBLE_ANIMATED) {
1127            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_visible_property().base()));
1128        } else if changed.contains(CompositionVisualChangedFields::VISIBLE) {
1129            writer.write(self.visible.get());
1130        }
1131        if changed.contains(CompositionVisualChangedFields::OPACITY_ANIMATED) {
1132            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_opacity_property().base()));
1133        } else if changed.contains(CompositionVisualChangedFields::OPACITY) {
1134            writer.write(self.opacity.get());
1135        }
1136        if changed.contains(CompositionVisualChangedFields::CLIP) {
1137            writer.write_value(self.clip.borrow().clone());
1138        }
1139        if changed.contains(CompositionVisualChangedFields::CLIP_TO_BOUNDS_ANIMATED) {
1140            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_clip_to_bounds_property().base()));
1141        } else if changed.contains(CompositionVisualChangedFields::CLIP_TO_BOUNDS) {
1142            writer.write(self.clip_to_bounds.get());
1143        }
1144        if changed.contains(CompositionVisualChangedFields::OFFSET_ANIMATED) {
1145            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_offset_property().base()));
1146        } else if changed.contains(CompositionVisualChangedFields::OFFSET) {
1147            writer.write(self.offset.get());
1148        }
1149        if changed.contains(CompositionVisualChangedFields::TRANSLATION_ANIMATED) {
1150            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_translation_property().base()));
1151        } else if changed.contains(CompositionVisualChangedFields::TRANSLATION) {
1152            writer.write(self.translation.get());
1153        }
1154        if changed.contains(CompositionVisualChangedFields::SIZE_ANIMATED) {
1155            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_size_property().base()));
1156        } else if changed.contains(CompositionVisualChangedFields::SIZE) {
1157            writer.write(self.size.get());
1158        }
1159        if changed.contains(CompositionVisualChangedFields::ANCHOR_POINT_ANIMATED) {
1160            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_anchor_point_property().base()));
1161        } else if changed.contains(CompositionVisualChangedFields::ANCHOR_POINT) {
1162            writer.write(self.anchor_point.get());
1163        }
1164        if changed.contains(CompositionVisualChangedFields::CENTER_POINT_ANIMATED) {
1165            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_center_point_property().base()));
1166        } else if changed.contains(CompositionVisualChangedFields::CENTER_POINT) {
1167            writer.write(self.center_point.get());
1168        }
1169        if changed.contains(CompositionVisualChangedFields::ROTATION_ANGLE_ANIMATED) {
1170            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_rotation_angle_property().base()));
1171        } else if changed.contains(CompositionVisualChangedFields::ROTATION_ANGLE) {
1172            writer.write(self.rotation_angle.get());
1173        }
1174        if changed.contains(CompositionVisualChangedFields::ORIENTATION_ANIMATED) {
1175            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_orientation_property().base()));
1176        } else if changed.contains(CompositionVisualChangedFields::ORIENTATION) {
1177            writer.write(self.orientation.get());
1178        }
1179        if changed.contains(CompositionVisualChangedFields::SCALE_ANIMATED) {
1180            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_scale_property().base()));
1181        } else if changed.contains(CompositionVisualChangedFields::SCALE) {
1182            writer.write(self.scale.get());
1183        }
1184        if changed.contains(CompositionVisualChangedFields::TRANSFORM_MATRIX_ANIMATED) {
1185            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_transform_matrix_property().base()));
1186        } else if changed.contains(CompositionVisualChangedFields::TRANSFORM_MATRIX) {
1187            writer.write(self.transform_matrix.get());
1188        }
1189        if changed.contains(CompositionVisualChangedFields::ADORNED_VISUAL) {
1190            writer.write_server_object(self.adorned_visual.borrow().clone().map(|o| o.server()));
1191        }
1192        if changed.contains(CompositionVisualChangedFields::ADORNER_IS_CLIPPED) {
1193            writer.write(self.adorner_is_clipped.get());
1194        }
1195        if changed.contains(CompositionVisualChangedFields::OPACITY_MASK_BRUSH) {
1196            writer.write_resource(self.opacity_mask_brush.borrow().clone());
1197        }
1198        if changed.contains(CompositionVisualChangedFields::EFFECT) {
1199            writer.write_value(self.effect.borrow().clone());
1200        }
1201        if changed.contains(CompositionVisualChangedFields::RENDER_OPTIONS) {
1202            writer.write(self.render_options.get());
1203        }
1204        if changed.contains(CompositionVisualChangedFields::TEXT_OPTIONS) {
1205            writer.write(self.text_options.get());
1206        }
1207        if changed.contains(CompositionVisualChangedFields::CACHE_MODE) {
1208            writer.write_server_object(self.cache_mode.borrow().clone().map(|o| o.server()));
1209        }
1210        self.changed_fields_of_composition_visual.set(CompositionVisualChangedFields::empty());
1211    }
1212}
1213
1214/// The partial methods of `ServerCompositionVisual`: implemented by the class that embeds
1215/// [`ServerCompositionVisualProps`]. Every hook defaults to doing nothing.
1216pub trait ServerCompositionVisualHooks: IServerAnimatedPropertyHost {
1217    fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
1218    fn on_fields_deserialized(&self, _changed: CompositionVisualChangedFields) {}
1219
1220    fn on_root_changed(&self) {}
1221    fn on_root_changing(&self) {}
1222
1223    fn on_parent_changed(&self) {}
1224    fn on_parent_changing(&self) {}
1225
1226    fn on_clip_changed(&self) {}
1227    fn on_clip_changing(&self) {}
1228
1229    fn on_adorned_visual_changed(&self) {}
1230    fn on_adorned_visual_changing(&self) {}
1231
1232    fn on_adorner_is_clipped_changed(&self) {}
1233    fn on_adorner_is_clipped_changing(&self) {}
1234
1235    fn on_opacity_mask_brush_changed(&self) {}
1236    fn on_opacity_mask_brush_changing(&self) {}
1237
1238    fn on_effect_changed(&self) {}
1239    fn on_effect_changing(&self) {}
1240
1241    fn on_render_options_changed(&self) {}
1242    fn on_render_options_changing(&self) {}
1243
1244    fn on_text_options_changed(&self) {}
1245    fn on_text_options_changing(&self) {}
1246
1247    fn on_cache_mode_changed(&self) {}
1248    fn on_cache_mode_changing(&self) {}
1249}
1250
1251/// The server-side properties of `ServerCompositionVisual`.
1252pub struct ServerCompositionVisualProps {
1253    root: RefCell<Option<Rc<dyn IServerObject>>>,
1254    parent: RefCell<Option<Rc<dyn IServerObject>>>,
1255    visible: Cell<bool>,
1256    opacity: Cell<f32>,
1257    clip: RefCell<Option<Arc<dyn IGeometryImpl>>>,
1258    clip_to_bounds: Cell<bool>,
1259    offset: Cell<Vector3D>,
1260    translation: Cell<Vector3D>,
1261    size: Cell<Vector>,
1262    anchor_point: Cell<Vector>,
1263    center_point: Cell<Vector3D>,
1264    rotation_angle: Cell<f32>,
1265    orientation: Cell<Quaternion>,
1266    scale: Cell<Vector3D>,
1267    transform_matrix: Cell<Matrix>,
1268    adorned_visual: RefCell<Option<Rc<dyn IServerObject>>>,
1269    adorner_is_clipped: Cell<bool>,
1270    opacity_mask_brush: RefCell<Option<ServerResourceRef<dyn IBrush>>>,
1271    effect: RefCell<Option<Arc<dyn IImmutableEffect>>>,
1272    render_options: Cell<RenderOptions>,
1273    text_options: Cell<TextOptions>,
1274    cache_mode: RefCell<Option<Rc<dyn IServerObject>>>,
1275}
1276
1277impl Default for ServerCompositionVisualProps {
1278    fn default() -> Self {
1279        Self::new()
1280    }
1281}
1282
1283impl ServerCompositionVisualProps {
1284    /// Creates the properties with every field at the default of its type; the
1285    /// values of the UI thread arrive with the first batch.
1286    pub fn new() -> Self {
1287        Self {
1288            root: RefCell::new(None),
1289            parent: RefCell::new(None),
1290            visible: Cell::new(Default::default()),
1291            opacity: Cell::new(Default::default()),
1292            clip: RefCell::new(None),
1293            clip_to_bounds: Cell::new(Default::default()),
1294            offset: Cell::new(Default::default()),
1295            translation: Cell::new(Default::default()),
1296            size: Cell::new(Default::default()),
1297            anchor_point: Cell::new(Default::default()),
1298            center_point: Cell::new(Default::default()),
1299            rotation_angle: Cell::new(Default::default()),
1300            orientation: Cell::new(Default::default()),
1301            scale: Cell::new(Default::default()),
1302            transform_matrix: Cell::new(Default::default()),
1303            adorned_visual: RefCell::new(None),
1304            adorner_is_clipped: Cell::new(Default::default()),
1305            opacity_mask_brush: RefCell::new(None),
1306            effect: RefCell::new(None),
1307            render_options: Cell::new(Default::default()),
1308            text_options: Cell::new(Default::default()),
1309            cache_mode: RefCell::new(None),
1310        }
1311    }
1312
1313    /// This block or the block of a base class, by type: what
1314    /// `IServerObject::get_props` of the embedding class returns.
1315    pub fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
1316        if type_id == TypeId::of::<Self>() {
1317            return Some(self);
1318        }
1319        None
1320    }
1321
1322    /// The composition property of `Root`.
1323    pub fn id_of_root_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
1324        static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
1325        PROPERTY.get_or_init(|| {
1326            CompositionProperty::register::<ServerCompositionVisualProps, Option<Rc<dyn IServerObject>>>(
1327                "Root",
1328                "ServerCompositionVisual",
1329                |obj| props_of::<ServerCompositionVisualProps>(obj).root.borrow().clone(),
1330                |obj, v| *props_of::<ServerCompositionVisualProps>(obj).root.borrow_mut() = v,
1331                None,
1332                None,
1333            )
1334        })
1335    }
1336
1337    /// `Root`.
1338    pub fn root(&self) -> Option<Rc<dyn IServerObject>> {
1339        self.root.borrow().clone()
1340    }
1341
1342    pub fn set_root(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Rc<dyn IServerObject>>) {
1343        let old_value = self.root.borrow().clone();
1344        let mut changed = false;
1345        if old_value.differs(&value) {
1346            ServerCompositionVisualHooks::on_root_changing(host);
1347            changed = true;
1348        }
1349        host.set_value(
1350            Self::id_of_root_property().base(),
1351            ServerValueChange {
1352                equal: old_value.default_equals(&value),
1353                old_resource: old_value.as_server_render_resource(),
1354                new_resource: value.as_server_render_resource(),
1355                assign: &mut || *self.root.borrow_mut() = value.clone(),
1356            },
1357        );
1358        if changed {
1359            ServerCompositionVisualHooks::on_root_changed(host);
1360        }
1361    }
1362
1363    /// The composition property of `Parent`.
1364    pub fn id_of_parent_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
1365        static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
1366        PROPERTY.get_or_init(|| {
1367            CompositionProperty::register::<ServerCompositionVisualProps, Option<Rc<dyn IServerObject>>>(
1368                "Parent",
1369                "ServerCompositionVisual",
1370                |obj| props_of::<ServerCompositionVisualProps>(obj).parent.borrow().clone(),
1371                |obj, v| *props_of::<ServerCompositionVisualProps>(obj).parent.borrow_mut() = v,
1372                None,
1373                None,
1374            )
1375        })
1376    }
1377
1378    /// `Parent`.
1379    pub fn parent(&self) -> Option<Rc<dyn IServerObject>> {
1380        self.parent.borrow().clone()
1381    }
1382
1383    pub fn set_parent(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Rc<dyn IServerObject>>) {
1384        let old_value = self.parent.borrow().clone();
1385        let mut changed = false;
1386        if old_value.differs(&value) {
1387            ServerCompositionVisualHooks::on_parent_changing(host);
1388            changed = true;
1389        }
1390        host.set_value(
1391            Self::id_of_parent_property().base(),
1392            ServerValueChange {
1393                equal: old_value.default_equals(&value),
1394                old_resource: old_value.as_server_render_resource(),
1395                new_resource: value.as_server_render_resource(),
1396                assign: &mut || *self.parent.borrow_mut() = value.clone(),
1397            },
1398        );
1399        if changed {
1400            ServerCompositionVisualHooks::on_parent_changed(host);
1401        }
1402    }
1403
1404    /// The composition property of `Visible`.
1405    pub fn id_of_visible_property() -> &'static CompositionPropertyOf<bool> {
1406        static PROPERTY: OnceLock<CompositionPropertyOf<bool>> = OnceLock::new();
1407        PROPERTY.get_or_init(|| {
1408            CompositionProperty::register::<ServerCompositionVisualProps, bool>(
1409                "Visible",
1410                "ServerCompositionVisual",
1411                |obj| props_of::<ServerCompositionVisualProps>(obj).visible.get(),
1412                |obj, v| props_of::<ServerCompositionVisualProps>(obj).visible.set(v),
1413                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).visible.get())),
1414                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).visible.set(v.cast_or_default::<bool>())),
1415            )
1416        })
1417    }
1418
1419    /// `Visible` (animated).
1420    pub fn visible(&self) -> bool {
1421        self.visible.get()
1422    }
1423
1424    pub fn set_visible(&self, host: &dyn ServerCompositionVisualHooks, value: bool) {
1425        self.visible.set(value);
1426        host.remove_animation_for_property(Self::id_of_visible_property().base());
1427    }
1428
1429    /// The composition property of `Opacity`.
1430    pub fn id_of_opacity_property() -> &'static CompositionPropertyOf<f32> {
1431        static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
1432        PROPERTY.get_or_init(|| {
1433            CompositionProperty::register::<ServerCompositionVisualProps, f32>(
1434                "Opacity",
1435                "ServerCompositionVisual",
1436                |obj| props_of::<ServerCompositionVisualProps>(obj).opacity.get(),
1437                |obj, v| props_of::<ServerCompositionVisualProps>(obj).opacity.set(v),
1438                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).opacity.get())),
1439                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).opacity.set(v.cast_or_default::<f32>())),
1440            )
1441        })
1442    }
1443
1444    /// `Opacity` (animated).
1445    pub fn opacity(&self) -> f32 {
1446        self.opacity.get()
1447    }
1448
1449    pub fn set_opacity(&self, host: &dyn ServerCompositionVisualHooks, value: f32) {
1450        self.opacity.set(value);
1451        host.remove_animation_for_property(Self::id_of_opacity_property().base());
1452    }
1453
1454    /// The composition property of `Clip`.
1455    pub fn id_of_clip_property() -> &'static CompositionPropertyOf<Option<Arc<dyn IGeometryImpl>>> {
1456        static PROPERTY: OnceLock<CompositionPropertyOf<Option<Arc<dyn IGeometryImpl>>>> = OnceLock::new();
1457        PROPERTY.get_or_init(|| {
1458            CompositionProperty::register::<ServerCompositionVisualProps, Option<Arc<dyn IGeometryImpl>>>(
1459                "Clip",
1460                "ServerCompositionVisual",
1461                |obj| props_of::<ServerCompositionVisualProps>(obj).clip.borrow().clone(),
1462                |obj, v| *props_of::<ServerCompositionVisualProps>(obj).clip.borrow_mut() = v,
1463                None,
1464                None,
1465            )
1466        })
1467    }
1468
1469    /// `Clip`.
1470    pub fn clip(&self) -> Option<Arc<dyn IGeometryImpl>> {
1471        self.clip.borrow().clone()
1472    }
1473
1474    pub fn set_clip(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Arc<dyn IGeometryImpl>>) {
1475        let old_value = self.clip.borrow().clone();
1476        let mut changed = false;
1477        if old_value.differs(&value) {
1478            ServerCompositionVisualHooks::on_clip_changing(host);
1479            changed = true;
1480        }
1481        host.set_value(
1482            Self::id_of_clip_property().base(),
1483            ServerValueChange {
1484                equal: old_value.default_equals(&value),
1485                old_resource: None,
1486                new_resource: None,
1487                assign: &mut || *self.clip.borrow_mut() = value.clone(),
1488            },
1489        );
1490        if changed {
1491            ServerCompositionVisualHooks::on_clip_changed(host);
1492        }
1493    }
1494
1495    /// The composition property of `ClipToBounds`.
1496    pub fn id_of_clip_to_bounds_property() -> &'static CompositionPropertyOf<bool> {
1497        static PROPERTY: OnceLock<CompositionPropertyOf<bool>> = OnceLock::new();
1498        PROPERTY.get_or_init(|| {
1499            CompositionProperty::register::<ServerCompositionVisualProps, bool>(
1500                "ClipToBounds",
1501                "ServerCompositionVisual",
1502                |obj| props_of::<ServerCompositionVisualProps>(obj).clip_to_bounds.get(),
1503                |obj, v| props_of::<ServerCompositionVisualProps>(obj).clip_to_bounds.set(v),
1504                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).clip_to_bounds.get())),
1505                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).clip_to_bounds.set(v.cast_or_default::<bool>())),
1506            )
1507        })
1508    }
1509
1510    /// `ClipToBounds` (animated).
1511    pub fn clip_to_bounds(&self) -> bool {
1512        self.clip_to_bounds.get()
1513    }
1514
1515    pub fn set_clip_to_bounds(&self, host: &dyn ServerCompositionVisualHooks, value: bool) {
1516        self.clip_to_bounds.set(value);
1517        host.remove_animation_for_property(Self::id_of_clip_to_bounds_property().base());
1518    }
1519
1520    /// The composition property of `Offset`.
1521    pub fn id_of_offset_property() -> &'static CompositionPropertyOf<Vector3D> {
1522        static PROPERTY: OnceLock<CompositionPropertyOf<Vector3D>> = OnceLock::new();
1523        PROPERTY.get_or_init(|| {
1524            CompositionProperty::register::<ServerCompositionVisualProps, Vector3D>(
1525                "Offset",
1526                "ServerCompositionVisual",
1527                |obj| props_of::<ServerCompositionVisualProps>(obj).offset.get(),
1528                |obj, v| props_of::<ServerCompositionVisualProps>(obj).offset.set(v),
1529                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).offset.get())),
1530                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).offset.set(v.cast_or_default::<Vector3D>())),
1531            )
1532        })
1533    }
1534
1535    /// `Offset` (animated).
1536    pub fn offset(&self) -> Vector3D {
1537        self.offset.get()
1538    }
1539
1540    pub fn set_offset(&self, host: &dyn ServerCompositionVisualHooks, value: Vector3D) {
1541        self.offset.set(value);
1542        host.remove_animation_for_property(Self::id_of_offset_property().base());
1543    }
1544
1545    /// The composition property of `Translation`.
1546    pub fn id_of_translation_property() -> &'static CompositionPropertyOf<Vector3D> {
1547        static PROPERTY: OnceLock<CompositionPropertyOf<Vector3D>> = OnceLock::new();
1548        PROPERTY.get_or_init(|| {
1549            CompositionProperty::register::<ServerCompositionVisualProps, Vector3D>(
1550                "Translation",
1551                "ServerCompositionVisual",
1552                |obj| props_of::<ServerCompositionVisualProps>(obj).translation.get(),
1553                |obj, v| props_of::<ServerCompositionVisualProps>(obj).translation.set(v),
1554                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).translation.get())),
1555                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).translation.set(v.cast_or_default::<Vector3D>())),
1556            )
1557        })
1558    }
1559
1560    /// `Translation` (animated).
1561    pub fn translation(&self) -> Vector3D {
1562        self.translation.get()
1563    }
1564
1565    pub fn set_translation(&self, host: &dyn ServerCompositionVisualHooks, value: Vector3D) {
1566        self.translation.set(value);
1567        host.remove_animation_for_property(Self::id_of_translation_property().base());
1568    }
1569
1570    /// The composition property of `Size`.
1571    pub fn id_of_size_property() -> &'static CompositionPropertyOf<Vector> {
1572        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
1573        PROPERTY.get_or_init(|| {
1574            CompositionProperty::register::<ServerCompositionVisualProps, Vector>(
1575                "Size",
1576                "ServerCompositionVisual",
1577                |obj| props_of::<ServerCompositionVisualProps>(obj).size.get(),
1578                |obj, v| props_of::<ServerCompositionVisualProps>(obj).size.set(v),
1579                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).size.get())),
1580                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).size.set(v.cast_or_default::<Vector>())),
1581            )
1582        })
1583    }
1584
1585    /// `Size` (animated).
1586    pub fn size(&self) -> Vector {
1587        self.size.get()
1588    }
1589
1590    pub fn set_size(&self, host: &dyn ServerCompositionVisualHooks, value: Vector) {
1591        self.size.set(value);
1592        host.remove_animation_for_property(Self::id_of_size_property().base());
1593    }
1594
1595    /// The composition property of `AnchorPoint`.
1596    pub fn id_of_anchor_point_property() -> &'static CompositionPropertyOf<Vector> {
1597        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
1598        PROPERTY.get_or_init(|| {
1599            CompositionProperty::register::<ServerCompositionVisualProps, Vector>(
1600                "AnchorPoint",
1601                "ServerCompositionVisual",
1602                |obj| props_of::<ServerCompositionVisualProps>(obj).anchor_point.get(),
1603                |obj, v| props_of::<ServerCompositionVisualProps>(obj).anchor_point.set(v),
1604                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).anchor_point.get())),
1605                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).anchor_point.set(v.cast_or_default::<Vector>())),
1606            )
1607        })
1608    }
1609
1610    /// `AnchorPoint` (animated).
1611    pub fn anchor_point(&self) -> Vector {
1612        self.anchor_point.get()
1613    }
1614
1615    pub fn set_anchor_point(&self, host: &dyn ServerCompositionVisualHooks, value: Vector) {
1616        self.anchor_point.set(value);
1617        host.remove_animation_for_property(Self::id_of_anchor_point_property().base());
1618    }
1619
1620    /// The composition property of `CenterPoint`.
1621    pub fn id_of_center_point_property() -> &'static CompositionPropertyOf<Vector3D> {
1622        static PROPERTY: OnceLock<CompositionPropertyOf<Vector3D>> = OnceLock::new();
1623        PROPERTY.get_or_init(|| {
1624            CompositionProperty::register::<ServerCompositionVisualProps, Vector3D>(
1625                "CenterPoint",
1626                "ServerCompositionVisual",
1627                |obj| props_of::<ServerCompositionVisualProps>(obj).center_point.get(),
1628                |obj, v| props_of::<ServerCompositionVisualProps>(obj).center_point.set(v),
1629                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).center_point.get())),
1630                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).center_point.set(v.cast_or_default::<Vector3D>())),
1631            )
1632        })
1633    }
1634
1635    /// `CenterPoint` (animated).
1636    pub fn center_point(&self) -> Vector3D {
1637        self.center_point.get()
1638    }
1639
1640    pub fn set_center_point(&self, host: &dyn ServerCompositionVisualHooks, value: Vector3D) {
1641        self.center_point.set(value);
1642        host.remove_animation_for_property(Self::id_of_center_point_property().base());
1643    }
1644
1645    /// The composition property of `RotationAngle`.
1646    pub fn id_of_rotation_angle_property() -> &'static CompositionPropertyOf<f32> {
1647        static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
1648        PROPERTY.get_or_init(|| {
1649            CompositionProperty::register::<ServerCompositionVisualProps, f32>(
1650                "RotationAngle",
1651                "ServerCompositionVisual",
1652                |obj| props_of::<ServerCompositionVisualProps>(obj).rotation_angle.get(),
1653                |obj, v| props_of::<ServerCompositionVisualProps>(obj).rotation_angle.set(v),
1654                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).rotation_angle.get())),
1655                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).rotation_angle.set(v.cast_or_default::<f32>())),
1656            )
1657        })
1658    }
1659
1660    /// `RotationAngle` (animated).
1661    pub fn rotation_angle(&self) -> f32 {
1662        self.rotation_angle.get()
1663    }
1664
1665    pub fn set_rotation_angle(&self, host: &dyn ServerCompositionVisualHooks, value: f32) {
1666        self.rotation_angle.set(value);
1667        host.remove_animation_for_property(Self::id_of_rotation_angle_property().base());
1668    }
1669
1670    /// The composition property of `Orientation`.
1671    pub fn id_of_orientation_property() -> &'static CompositionPropertyOf<Quaternion> {
1672        static PROPERTY: OnceLock<CompositionPropertyOf<Quaternion>> = OnceLock::new();
1673        PROPERTY.get_or_init(|| {
1674            CompositionProperty::register::<ServerCompositionVisualProps, Quaternion>(
1675                "Orientation",
1676                "ServerCompositionVisual",
1677                |obj| props_of::<ServerCompositionVisualProps>(obj).orientation.get(),
1678                |obj, v| props_of::<ServerCompositionVisualProps>(obj).orientation.set(v),
1679                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).orientation.get())),
1680                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).orientation.set(v.cast_or_default::<Quaternion>())),
1681            )
1682        })
1683    }
1684
1685    /// `Orientation` (animated).
1686    pub fn orientation(&self) -> Quaternion {
1687        self.orientation.get()
1688    }
1689
1690    pub fn set_orientation(&self, host: &dyn ServerCompositionVisualHooks, value: Quaternion) {
1691        self.orientation.set(value);
1692        host.remove_animation_for_property(Self::id_of_orientation_property().base());
1693    }
1694
1695    /// The composition property of `Scale`.
1696    pub fn id_of_scale_property() -> &'static CompositionPropertyOf<Vector3D> {
1697        static PROPERTY: OnceLock<CompositionPropertyOf<Vector3D>> = OnceLock::new();
1698        PROPERTY.get_or_init(|| {
1699            CompositionProperty::register::<ServerCompositionVisualProps, Vector3D>(
1700                "Scale",
1701                "ServerCompositionVisual",
1702                |obj| props_of::<ServerCompositionVisualProps>(obj).scale.get(),
1703                |obj, v| props_of::<ServerCompositionVisualProps>(obj).scale.set(v),
1704                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).scale.get())),
1705                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).scale.set(v.cast_or_default::<Vector3D>())),
1706            )
1707        })
1708    }
1709
1710    /// `Scale` (animated).
1711    pub fn scale(&self) -> Vector3D {
1712        self.scale.get()
1713    }
1714
1715    pub fn set_scale(&self, host: &dyn ServerCompositionVisualHooks, value: Vector3D) {
1716        self.scale.set(value);
1717        host.remove_animation_for_property(Self::id_of_scale_property().base());
1718    }
1719
1720    /// The composition property of `TransformMatrix`.
1721    pub fn id_of_transform_matrix_property() -> &'static CompositionPropertyOf<Matrix> {
1722        static PROPERTY: OnceLock<CompositionPropertyOf<Matrix>> = OnceLock::new();
1723        PROPERTY.get_or_init(|| {
1724            CompositionProperty::register::<ServerCompositionVisualProps, Matrix>(
1725                "TransformMatrix",
1726                "ServerCompositionVisual",
1727                |obj| props_of::<ServerCompositionVisualProps>(obj).transform_matrix.get(),
1728                |obj, v| props_of::<ServerCompositionVisualProps>(obj).transform_matrix.set(v),
1729                None,
1730                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).transform_matrix.set(v.cast_or_default::<Matrix>())),
1731            )
1732        })
1733    }
1734
1735    /// `TransformMatrix` (animated).
1736    pub fn transform_matrix(&self) -> Matrix {
1737        self.transform_matrix.get()
1738    }
1739
1740    pub fn set_transform_matrix(&self, host: &dyn ServerCompositionVisualHooks, value: Matrix) {
1741        self.transform_matrix.set(value);
1742        host.remove_animation_for_property(Self::id_of_transform_matrix_property().base());
1743    }
1744
1745    /// The composition property of `AdornedVisual`.
1746    pub fn id_of_adorned_visual_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
1747        static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
1748        PROPERTY.get_or_init(|| {
1749            CompositionProperty::register::<ServerCompositionVisualProps, Option<Rc<dyn IServerObject>>>(
1750                "AdornedVisual",
1751                "ServerCompositionVisual",
1752                |obj| props_of::<ServerCompositionVisualProps>(obj).adorned_visual.borrow().clone(),
1753                |obj, v| *props_of::<ServerCompositionVisualProps>(obj).adorned_visual.borrow_mut() = v,
1754                None,
1755                None,
1756            )
1757        })
1758    }
1759
1760    /// `AdornedVisual`.
1761    pub fn adorned_visual(&self) -> Option<Rc<dyn IServerObject>> {
1762        self.adorned_visual.borrow().clone()
1763    }
1764
1765    pub fn set_adorned_visual(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Rc<dyn IServerObject>>) {
1766        let old_value = self.adorned_visual.borrow().clone();
1767        let mut changed = false;
1768        if old_value.differs(&value) {
1769            ServerCompositionVisualHooks::on_adorned_visual_changing(host);
1770            changed = true;
1771        }
1772        host.set_value(
1773            Self::id_of_adorned_visual_property().base(),
1774            ServerValueChange {
1775                equal: old_value.default_equals(&value),
1776                old_resource: old_value.as_server_render_resource(),
1777                new_resource: value.as_server_render_resource(),
1778                assign: &mut || *self.adorned_visual.borrow_mut() = value.clone(),
1779            },
1780        );
1781        if changed {
1782            ServerCompositionVisualHooks::on_adorned_visual_changed(host);
1783        }
1784    }
1785
1786    /// The composition property of `AdornerIsClipped`.
1787    pub fn id_of_adorner_is_clipped_property() -> &'static CompositionPropertyOf<bool> {
1788        static PROPERTY: OnceLock<CompositionPropertyOf<bool>> = OnceLock::new();
1789        PROPERTY.get_or_init(|| {
1790            CompositionProperty::register::<ServerCompositionVisualProps, bool>(
1791                "AdornerIsClipped",
1792                "ServerCompositionVisual",
1793                |obj| props_of::<ServerCompositionVisualProps>(obj).adorner_is_clipped.get(),
1794                |obj, v| props_of::<ServerCompositionVisualProps>(obj).adorner_is_clipped.set(v),
1795                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).adorner_is_clipped.get())),
1796                None,
1797            )
1798        })
1799    }
1800
1801    /// `AdornerIsClipped`.
1802    pub fn adorner_is_clipped(&self) -> bool {
1803        self.adorner_is_clipped.get()
1804    }
1805
1806    pub fn set_adorner_is_clipped(&self, host: &dyn ServerCompositionVisualHooks, value: bool) {
1807        let old_value = self.adorner_is_clipped.get();
1808        let mut changed = false;
1809        if old_value.differs(&value) {
1810            ServerCompositionVisualHooks::on_adorner_is_clipped_changing(host);
1811            changed = true;
1812        }
1813        host.set_value(
1814            Self::id_of_adorner_is_clipped_property().base(),
1815            ServerValueChange {
1816                equal: old_value.default_equals(&value),
1817                old_resource: None,
1818                new_resource: None,
1819                assign: &mut || self.adorner_is_clipped.set(value),
1820            },
1821        );
1822        if changed {
1823            ServerCompositionVisualHooks::on_adorner_is_clipped_changed(host);
1824        }
1825    }
1826
1827    /// The composition property of `OpacityMaskBrush`.
1828    pub fn id_of_opacity_mask_brush_property() -> &'static CompositionPropertyOf<Option<ServerResourceRef<dyn IBrush>>> {
1829        static PROPERTY: OnceLock<CompositionPropertyOf<Option<ServerResourceRef<dyn IBrush>>>> = OnceLock::new();
1830        PROPERTY.get_or_init(|| {
1831            CompositionProperty::register::<ServerCompositionVisualProps, Option<ServerResourceRef<dyn IBrush>>>(
1832                "OpacityMaskBrush",
1833                "ServerCompositionVisual",
1834                |obj| props_of::<ServerCompositionVisualProps>(obj).opacity_mask_brush.borrow().clone(),
1835                |obj, v| *props_of::<ServerCompositionVisualProps>(obj).opacity_mask_brush.borrow_mut() = v,
1836                None,
1837                None,
1838            )
1839        })
1840    }
1841
1842    /// `OpacityMaskBrush`.
1843    pub fn opacity_mask_brush(&self) -> Option<ServerResourceRef<dyn IBrush>> {
1844        self.opacity_mask_brush.borrow().clone()
1845    }
1846
1847    pub fn set_opacity_mask_brush(&self, host: &dyn ServerCompositionVisualHooks, value: Option<ServerResourceRef<dyn IBrush>>) {
1848        let old_value = self.opacity_mask_brush.borrow().clone();
1849        let mut changed = false;
1850        if old_value.differs(&value) {
1851            ServerCompositionVisualHooks::on_opacity_mask_brush_changing(host);
1852            changed = true;
1853        }
1854        host.set_value(
1855            Self::id_of_opacity_mask_brush_property().base(),
1856            ServerValueChange {
1857                equal: old_value.default_equals(&value),
1858                old_resource: old_value.as_server_render_resource(),
1859                new_resource: value.as_server_render_resource(),
1860                assign: &mut || *self.opacity_mask_brush.borrow_mut() = value.clone(),
1861            },
1862        );
1863        if changed {
1864            ServerCompositionVisualHooks::on_opacity_mask_brush_changed(host);
1865        }
1866    }
1867
1868    /// The composition property of `Effect`.
1869    pub fn id_of_effect_property() -> &'static CompositionPropertyOf<Option<Arc<dyn IImmutableEffect>>> {
1870        static PROPERTY: OnceLock<CompositionPropertyOf<Option<Arc<dyn IImmutableEffect>>>> = OnceLock::new();
1871        PROPERTY.get_or_init(|| {
1872            CompositionProperty::register::<ServerCompositionVisualProps, Option<Arc<dyn IImmutableEffect>>>(
1873                "Effect",
1874                "ServerCompositionVisual",
1875                |obj| props_of::<ServerCompositionVisualProps>(obj).effect.borrow().clone(),
1876                |obj, v| *props_of::<ServerCompositionVisualProps>(obj).effect.borrow_mut() = v,
1877                None,
1878                None,
1879            )
1880        })
1881    }
1882
1883    /// `Effect`.
1884    pub fn effect(&self) -> Option<Arc<dyn IImmutableEffect>> {
1885        self.effect.borrow().clone()
1886    }
1887
1888    pub fn set_effect(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Arc<dyn IImmutableEffect>>) {
1889        let old_value = self.effect.borrow().clone();
1890        let mut changed = false;
1891        if old_value.differs(&value) {
1892            ServerCompositionVisualHooks::on_effect_changing(host);
1893            changed = true;
1894        }
1895        host.set_value(
1896            Self::id_of_effect_property().base(),
1897            ServerValueChange {
1898                equal: old_value.default_equals(&value),
1899                old_resource: None,
1900                new_resource: None,
1901                assign: &mut || *self.effect.borrow_mut() = value.clone(),
1902            },
1903        );
1904        if changed {
1905            ServerCompositionVisualHooks::on_effect_changed(host);
1906        }
1907    }
1908
1909    /// The composition property of `RenderOptions`.
1910    pub fn id_of_render_options_property() -> &'static CompositionPropertyOf<RenderOptions> {
1911        static PROPERTY: OnceLock<CompositionPropertyOf<RenderOptions>> = OnceLock::new();
1912        PROPERTY.get_or_init(|| {
1913            CompositionProperty::register::<ServerCompositionVisualProps, RenderOptions>(
1914                "RenderOptions",
1915                "ServerCompositionVisual",
1916                |obj| props_of::<ServerCompositionVisualProps>(obj).render_options.get(),
1917                |obj, v| props_of::<ServerCompositionVisualProps>(obj).render_options.set(v),
1918                None,
1919                None,
1920            )
1921        })
1922    }
1923
1924    /// `RenderOptions`.
1925    pub fn render_options(&self) -> RenderOptions {
1926        self.render_options.get()
1927    }
1928
1929    pub fn set_render_options(&self, host: &dyn ServerCompositionVisualHooks, value: RenderOptions) {
1930        let old_value = self.render_options.get();
1931        let mut changed = false;
1932        if old_value.differs(&value) {
1933            ServerCompositionVisualHooks::on_render_options_changing(host);
1934            changed = true;
1935        }
1936        host.set_value(
1937            Self::id_of_render_options_property().base(),
1938            ServerValueChange {
1939                equal: old_value.default_equals(&value),
1940                old_resource: None,
1941                new_resource: None,
1942                assign: &mut || self.render_options.set(value),
1943            },
1944        );
1945        if changed {
1946            ServerCompositionVisualHooks::on_render_options_changed(host);
1947        }
1948    }
1949
1950    /// The composition property of `TextOptions`.
1951    pub fn id_of_text_options_property() -> &'static CompositionPropertyOf<TextOptions> {
1952        static PROPERTY: OnceLock<CompositionPropertyOf<TextOptions>> = OnceLock::new();
1953        PROPERTY.get_or_init(|| {
1954            CompositionProperty::register::<ServerCompositionVisualProps, TextOptions>(
1955                "TextOptions",
1956                "ServerCompositionVisual",
1957                |obj| props_of::<ServerCompositionVisualProps>(obj).text_options.get(),
1958                |obj, v| props_of::<ServerCompositionVisualProps>(obj).text_options.set(v),
1959                None,
1960                None,
1961            )
1962        })
1963    }
1964
1965    /// `TextOptions`.
1966    pub fn text_options(&self) -> TextOptions {
1967        self.text_options.get()
1968    }
1969
1970    pub fn set_text_options(&self, host: &dyn ServerCompositionVisualHooks, value: TextOptions) {
1971        let old_value = self.text_options.get();
1972        let mut changed = false;
1973        if old_value.differs(&value) {
1974            ServerCompositionVisualHooks::on_text_options_changing(host);
1975            changed = true;
1976        }
1977        host.set_value(
1978            Self::id_of_text_options_property().base(),
1979            ServerValueChange {
1980                equal: old_value.default_equals(&value),
1981                old_resource: None,
1982                new_resource: None,
1983                assign: &mut || self.text_options.set(value),
1984            },
1985        );
1986        if changed {
1987            ServerCompositionVisualHooks::on_text_options_changed(host);
1988        }
1989    }
1990
1991    /// The composition property of `CacheMode`.
1992    pub fn id_of_cache_mode_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
1993        static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
1994        PROPERTY.get_or_init(|| {
1995            CompositionProperty::register::<ServerCompositionVisualProps, Option<Rc<dyn IServerObject>>>(
1996                "CacheMode",
1997                "ServerCompositionVisual",
1998                |obj| props_of::<ServerCompositionVisualProps>(obj).cache_mode.borrow().clone(),
1999                |obj, v| *props_of::<ServerCompositionVisualProps>(obj).cache_mode.borrow_mut() = v,
2000                None,
2001                None,
2002            )
2003        })
2004    }
2005
2006    /// `CacheMode`.
2007    pub fn cache_mode(&self) -> Option<Rc<dyn IServerObject>> {
2008        self.cache_mode.borrow().clone()
2009    }
2010
2011    pub fn set_cache_mode(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Rc<dyn IServerObject>>) {
2012        let old_value = self.cache_mode.borrow().clone();
2013        let mut changed = false;
2014        if old_value.differs(&value) {
2015            ServerCompositionVisualHooks::on_cache_mode_changing(host);
2016            changed = true;
2017        }
2018        host.set_value(
2019            Self::id_of_cache_mode_property().base(),
2020            ServerValueChange {
2021                equal: old_value.default_equals(&value),
2022                old_resource: old_value.as_server_render_resource(),
2023                new_resource: value.as_server_render_resource(),
2024                assign: &mut || *self.cache_mode.borrow_mut() = value.clone(),
2025            },
2026        );
2027        if changed {
2028            ServerCompositionVisualHooks::on_cache_mode_changed(host);
2029        }
2030    }
2031
2032    /// Reads the changes of the object: the base class first, then the
2033    /// changed-fields mask and the changed members of this class.
2034    pub fn deserialize_changes_core(
2035        &self,
2036        host: &dyn ServerCompositionVisualHooks,
2037        reader: &mut BatchStreamReader<'_>,
2038        committed_at: Duration,
2039    ) {
2040        let compositor = host.server_compositor();
2041        ServerCompositionVisualHooks::deserialize_changes_extra(host, reader);
2042        let changed = reader.read::<CompositionVisualChangedFields>();
2043        if changed.contains(CompositionVisualChangedFields::ROOT) {
2044            let value = read_server_object(reader, compositor.as_ref());
2045            self.set_root(host, value);
2046        }
2047        if changed.contains(CompositionVisualChangedFields::PARENT) {
2048            let value = read_server_object(reader, compositor.as_ref());
2049            self.set_parent(host, value);
2050        }
2051        if changed.contains(CompositionVisualChangedFields::VISIBLE_ANIMATED) {
2052            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2053                panic!("a batch starts an animation of `Visible` without an animation instance");
2054            };
2055            host.set_animated_value(
2056                Self::id_of_visible_property().base(),
2057                ExpressionVariant::create(self.visible.get()),
2058                committed_at,
2059                animation,
2060            );
2061        } else if changed.contains(CompositionVisualChangedFields::VISIBLE) {
2062            let value = reader.read::<bool>();
2063            self.set_visible(host, value);
2064        }
2065        if changed.contains(CompositionVisualChangedFields::OPACITY_ANIMATED) {
2066            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2067                panic!("a batch starts an animation of `Opacity` without an animation instance");
2068            };
2069            host.set_animated_value(
2070                Self::id_of_opacity_property().base(),
2071                ExpressionVariant::create(self.opacity.get()),
2072                committed_at,
2073                animation,
2074            );
2075        } else if changed.contains(CompositionVisualChangedFields::OPACITY) {
2076            let value = reader.read::<f32>();
2077            self.set_opacity(host, value);
2078        }
2079        if changed.contains(CompositionVisualChangedFields::CLIP) {
2080            let value = reader.read_value::<Arc<dyn IGeometryImpl>>();
2081            self.set_clip(host, value);
2082        }
2083        if changed.contains(CompositionVisualChangedFields::CLIP_TO_BOUNDS_ANIMATED) {
2084            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2085                panic!("a batch starts an animation of `ClipToBounds` without an animation instance");
2086            };
2087            host.set_animated_value(
2088                Self::id_of_clip_to_bounds_property().base(),
2089                ExpressionVariant::create(self.clip_to_bounds.get()),
2090                committed_at,
2091                animation,
2092            );
2093        } else if changed.contains(CompositionVisualChangedFields::CLIP_TO_BOUNDS) {
2094            let value = reader.read::<bool>();
2095            self.set_clip_to_bounds(host, value);
2096        }
2097        if changed.contains(CompositionVisualChangedFields::OFFSET_ANIMATED) {
2098            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2099                panic!("a batch starts an animation of `Offset` without an animation instance");
2100            };
2101            host.set_animated_value(
2102                Self::id_of_offset_property().base(),
2103                ExpressionVariant::create(self.offset.get()),
2104                committed_at,
2105                animation,
2106            );
2107        } else if changed.contains(CompositionVisualChangedFields::OFFSET) {
2108            let value = reader.read::<Vector3D>();
2109            self.set_offset(host, value);
2110        }
2111        if changed.contains(CompositionVisualChangedFields::TRANSLATION_ANIMATED) {
2112            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2113                panic!("a batch starts an animation of `Translation` without an animation instance");
2114            };
2115            host.set_animated_value(
2116                Self::id_of_translation_property().base(),
2117                ExpressionVariant::create(self.translation.get()),
2118                committed_at,
2119                animation,
2120            );
2121        } else if changed.contains(CompositionVisualChangedFields::TRANSLATION) {
2122            let value = reader.read::<Vector3D>();
2123            self.set_translation(host, value);
2124        }
2125        if changed.contains(CompositionVisualChangedFields::SIZE_ANIMATED) {
2126            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2127                panic!("a batch starts an animation of `Size` without an animation instance");
2128            };
2129            host.set_animated_value(
2130                Self::id_of_size_property().base(),
2131                ExpressionVariant::create(self.size.get()),
2132                committed_at,
2133                animation,
2134            );
2135        } else if changed.contains(CompositionVisualChangedFields::SIZE) {
2136            let value = reader.read::<Vector>();
2137            self.set_size(host, value);
2138        }
2139        if changed.contains(CompositionVisualChangedFields::ANCHOR_POINT_ANIMATED) {
2140            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2141                panic!("a batch starts an animation of `AnchorPoint` without an animation instance");
2142            };
2143            host.set_animated_value(
2144                Self::id_of_anchor_point_property().base(),
2145                ExpressionVariant::create(self.anchor_point.get()),
2146                committed_at,
2147                animation,
2148            );
2149        } else if changed.contains(CompositionVisualChangedFields::ANCHOR_POINT) {
2150            let value = reader.read::<Vector>();
2151            self.set_anchor_point(host, value);
2152        }
2153        if changed.contains(CompositionVisualChangedFields::CENTER_POINT_ANIMATED) {
2154            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2155                panic!("a batch starts an animation of `CenterPoint` without an animation instance");
2156            };
2157            host.set_animated_value(
2158                Self::id_of_center_point_property().base(),
2159                ExpressionVariant::create(self.center_point.get()),
2160                committed_at,
2161                animation,
2162            );
2163        } else if changed.contains(CompositionVisualChangedFields::CENTER_POINT) {
2164            let value = reader.read::<Vector3D>();
2165            self.set_center_point(host, value);
2166        }
2167        if changed.contains(CompositionVisualChangedFields::ROTATION_ANGLE_ANIMATED) {
2168            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2169                panic!("a batch starts an animation of `RotationAngle` without an animation instance");
2170            };
2171            host.set_animated_value(
2172                Self::id_of_rotation_angle_property().base(),
2173                ExpressionVariant::create(self.rotation_angle.get()),
2174                committed_at,
2175                animation,
2176            );
2177        } else if changed.contains(CompositionVisualChangedFields::ROTATION_ANGLE) {
2178            let value = reader.read::<f32>();
2179            self.set_rotation_angle(host, value);
2180        }
2181        if changed.contains(CompositionVisualChangedFields::ORIENTATION_ANIMATED) {
2182            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2183                panic!("a batch starts an animation of `Orientation` without an animation instance");
2184            };
2185            host.set_animated_value(
2186                Self::id_of_orientation_property().base(),
2187                ExpressionVariant::create(self.orientation.get()),
2188                committed_at,
2189                animation,
2190            );
2191        } else if changed.contains(CompositionVisualChangedFields::ORIENTATION) {
2192            let value = reader.read::<Quaternion>();
2193            self.set_orientation(host, value);
2194        }
2195        if changed.contains(CompositionVisualChangedFields::SCALE_ANIMATED) {
2196            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2197                panic!("a batch starts an animation of `Scale` without an animation instance");
2198            };
2199            host.set_animated_value(
2200                Self::id_of_scale_property().base(),
2201                ExpressionVariant::create(self.scale.get()),
2202                committed_at,
2203                animation,
2204            );
2205        } else if changed.contains(CompositionVisualChangedFields::SCALE) {
2206            let value = reader.read::<Vector3D>();
2207            self.set_scale(host, value);
2208        }
2209        if changed.contains(CompositionVisualChangedFields::TRANSFORM_MATRIX_ANIMATED) {
2210            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2211                panic!("a batch starts an animation of `TransformMatrix` without an animation instance");
2212            };
2213            host.set_animated_value(
2214                Self::id_of_transform_matrix_property().base(),
2215                ExpressionVariant::create(self.transform_matrix.get()),
2216                committed_at,
2217                animation,
2218            );
2219        } else if changed.contains(CompositionVisualChangedFields::TRANSFORM_MATRIX) {
2220            let value = reader.read::<Matrix>();
2221            self.set_transform_matrix(host, value);
2222        }
2223        if changed.contains(CompositionVisualChangedFields::ADORNED_VISUAL) {
2224            let value = read_server_object(reader, compositor.as_ref());
2225            self.set_adorned_visual(host, value);
2226        }
2227        if changed.contains(CompositionVisualChangedFields::ADORNER_IS_CLIPPED) {
2228            let value = reader.read::<bool>();
2229            self.set_adorner_is_clipped(host, value);
2230        }
2231        if changed.contains(CompositionVisualChangedFields::OPACITY_MASK_BRUSH) {
2232            let value = read_resource(reader, compositor.as_ref(), |o| o.as_brush());
2233            self.set_opacity_mask_brush(host, value);
2234        }
2235        if changed.contains(CompositionVisualChangedFields::EFFECT) {
2236            let value = reader.read_value::<Arc<dyn IImmutableEffect>>();
2237            self.set_effect(host, value);
2238        }
2239        if changed.contains(CompositionVisualChangedFields::RENDER_OPTIONS) {
2240            let value = reader.read::<RenderOptions>();
2241            self.set_render_options(host, value);
2242        }
2243        if changed.contains(CompositionVisualChangedFields::TEXT_OPTIONS) {
2244            let value = reader.read::<TextOptions>();
2245            self.set_text_options(host, value);
2246        }
2247        if changed.contains(CompositionVisualChangedFields::CACHE_MODE) {
2248            let value = read_server_object(reader, compositor.as_ref());
2249            self.set_cache_mode(host, value);
2250        }
2251        ServerCompositionVisualHooks::on_fields_deserialized(host, changed);
2252    }
2253
2254    /// The composition property with the given name, among the properties
2255    /// of this class and of its generated bases that have a variant form.
2256    pub fn get_composition_property(name: &str) -> Option<&'static CompositionProperty> {
2257        if name == "Visible" {
2258            return Some(Self::id_of_visible_property().base());
2259        }
2260        if name == "Opacity" {
2261            return Some(Self::id_of_opacity_property().base());
2262        }
2263        if name == "ClipToBounds" {
2264            return Some(Self::id_of_clip_to_bounds_property().base());
2265        }
2266        if name == "Offset" {
2267            return Some(Self::id_of_offset_property().base());
2268        }
2269        if name == "Translation" {
2270            return Some(Self::id_of_translation_property().base());
2271        }
2272        if name == "Size" {
2273            return Some(Self::id_of_size_property().base());
2274        }
2275        if name == "AnchorPoint" {
2276            return Some(Self::id_of_anchor_point_property().base());
2277        }
2278        if name == "CenterPoint" {
2279            return Some(Self::id_of_center_point_property().base());
2280        }
2281        if name == "RotationAngle" {
2282            return Some(Self::id_of_rotation_angle_property().base());
2283        }
2284        if name == "Orientation" {
2285            return Some(Self::id_of_orientation_property().base());
2286        }
2287        if name == "Scale" {
2288            return Some(Self::id_of_scale_property().base());
2289        }
2290        if name == "AdornerIsClipped" {
2291            return Some(Self::id_of_adorner_is_clipped_property().base());
2292        }
2293        None
2294    }
2295}