Skip to main content

ferroui_base/rendering/composition/generated/
composition_conic_gradient_brush.rs

1// @generated by scripts/generate_composition.py — do not edit
2
3//! `CompositionConicGradientBrush`.
4//!
5//! Properties added by the FerroUI overlay (scripts/composition-schema-winui.xml): `AnchorPoint`, `CenterPoint`, `Offset`, `RotationAngle`, `Scale`, `TransformMatrix`.
6
7use bitflags::bitflags;
8use crate::Matrix;
9use crate::RelativePoint;
10use crate::Vector;
11use crate::rendering::composition::ICompositionObjectHost;
12use crate::rendering::composition::animations::AnimationInstanceFactory;
13use crate::rendering::composition::animations::ICompositionAnimation;
14use crate::rendering::composition::expressions::ExpressionVariant;
15use crate::rendering::composition::server::CompositionProperty;
16use crate::rendering::composition::server::CompositionPropertyOf;
17use crate::rendering::composition::server::IServerAnimatedPropertyHost;
18use crate::rendering::composition::server::ServerPropertyValue;
19use crate::rendering::composition::server::props_of;
20use crate::rendering::composition::transport::BatchStreamReader;
21use crate::rendering::composition::transport::BatchStreamWriter;
22use crate::rendering::composition::transport::BatchValue;
23use crate::rendering::composition::transport::BatchValueReader;
24use std::any::Any;
25use std::any::TypeId;
26use std::cell::Cell;
27use std::sync::OnceLock;
28use std::time::Duration;
29
30bitflags! {
31    /// The fields of `CompositionConicGradientBrush` that changed since its last serialization.
32    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
33    pub struct CompositionConicGradientBrushChangedFields: u16 {
34        const ANGLE = 1;
35        const ANGLE_ANIMATED = 2;
36        const CENTER = 4;
37        const CENTER_ANIMATED = 8;
38        const ANCHOR_POINT = 16;
39        const ANCHOR_POINT_ANIMATED = 32;
40        const CENTER_POINT = 64;
41        const CENTER_POINT_ANIMATED = 128;
42        const OFFSET = 256;
43        const OFFSET_ANIMATED = 512;
44        const ROTATION_ANGLE = 1024;
45        const ROTATION_ANGLE_ANIMATED = 2048;
46        const SCALE = 4096;
47        const SCALE_ANIMATED = 8192;
48        const TRANSFORM_MATRIX = 16384;
49        const TRANSFORM_MATRIX_ANIMATED = 32768;
50    }
51}
52
53impl BatchValue for CompositionConicGradientBrushChangedFields {
54    #[inline]
55    fn write_to(&self, out: &mut Vec<u8>) {
56        self.bits().write_to(out);
57    }
58
59    #[inline]
60    fn read_from(input: &mut BatchValueReader<'_>) -> Self {
61        CompositionConicGradientBrushChangedFields::from_bits_retain(u16::read_from(input))
62    }
63}
64
65/// The partial methods of `CompositionConicGradientBrush`: implemented by the class that embeds
66/// [`CompositionConicGradientBrushProps`]. Every hook defaults to doing nothing.
67pub trait CompositionConicGradientBrushHooks: ICompositionObjectHost {
68    /// `base.SerializeChangesCore(writer)`: serializes the changes of the
69    /// hand-written base class `CompositionGradientBrush`.
70    fn base_serialize_changes_core(&self, writer: &mut BatchStreamWriter<'_>);
71
72    fn initialize_defaults_extra(&self) {}
73
74    fn validate_angle_change(&self, _old_value: f64, _new_value: f64) {}
75    fn on_angle_changed(&self) {}
76    fn on_angle_changing(&self) {}
77
78    fn validate_center_change(&self, _old_value: RelativePoint, _new_value: RelativePoint) {}
79    fn on_center_changed(&self) {}
80    fn on_center_changing(&self) {}
81
82    fn validate_anchor_point_change(&self, _old_value: Vector, _new_value: Vector) {}
83    fn on_anchor_point_changed(&self) {}
84    fn on_anchor_point_changing(&self) {}
85
86    fn validate_center_point_change(&self, _old_value: Vector, _new_value: Vector) {}
87    fn on_center_point_changed(&self) {}
88    fn on_center_point_changing(&self) {}
89
90    fn validate_offset_change(&self, _old_value: Vector, _new_value: Vector) {}
91    fn on_offset_changed(&self) {}
92    fn on_offset_changing(&self) {}
93
94    fn validate_rotation_angle_change(&self, _old_value: f32, _new_value: f32) {}
95    fn on_rotation_angle_changed(&self) {}
96    fn on_rotation_angle_changing(&self) {}
97
98    fn validate_scale_change(&self, _old_value: Vector, _new_value: Vector) {}
99    fn on_scale_changed(&self) {}
100    fn on_scale_changing(&self) {}
101
102    fn validate_transform_matrix_change(&self, _old_value: Matrix, _new_value: Matrix) {}
103    fn on_transform_matrix_changed(&self) {}
104    fn on_transform_matrix_changing(&self) {}
105}
106
107/// The UI-thread properties of `CompositionConicGradientBrush`.
108pub struct CompositionConicGradientBrushProps {
109    changed_fields_of_composition_conic_gradient_brush: Cell<CompositionConicGradientBrushChangedFields>,
110    angle: Cell<f64>,
111    center: Cell<RelativePoint>,
112    anchor_point: Cell<Vector>,
113    center_point: Cell<Vector>,
114    offset: Cell<Vector>,
115    rotation_angle: Cell<f32>,
116    scale: Cell<Vector>,
117    transform_matrix: Cell<Matrix>,
118}
119
120impl Default for CompositionConicGradientBrushProps {
121    fn default() -> Self {
122        Self::new()
123    }
124}
125
126impl CompositionConicGradientBrushProps {
127    /// Creates the properties with every field at the default of its type.
128    /// The defaults of the schema are applied by
129    /// [`initialize_defaults`](Self::initialize_defaults).
130    pub fn new() -> Self {
131        Self {
132            changed_fields_of_composition_conic_gradient_brush: Cell::new(CompositionConicGradientBrushChangedFields::empty()),
133            angle: Cell::new(Default::default()),
134            center: Cell::new(Default::default()),
135            anchor_point: Cell::new(Default::default()),
136            center_point: Cell::new(Default::default()),
137            offset: Cell::new(Default::default()),
138            rotation_angle: Cell::new(Default::default()),
139            scale: Cell::new(Default::default()),
140            transform_matrix: Cell::new(Default::default()),
141        }
142    }
143
144    /// The `InitializeDefaults` calls of the constructor chain: the base
145    /// classes first, then this class.
146    pub fn initialize_defaults(&self, host: &dyn CompositionConicGradientBrushHooks) {
147        self.initialize_own_defaults(host);
148    }
149
150    /// `InitializeDefaults` of this class alone.
151    pub fn initialize_own_defaults(&self, host: &dyn CompositionConicGradientBrushHooks) {
152        CompositionConicGradientBrushHooks::initialize_defaults_extra(host);
153        self.set_scale(host, Vector::new(1.0, 1.0));
154        self.set_transform_matrix(host, Matrix::IDENTITY);
155    }
156
157    /// `Angle` (animated).
158    pub fn angle(&self) -> f64 {
159        self.angle.get()
160    }
161
162    /// Sets `Angle` (animated).
163    pub fn set_angle(&self, host: &dyn CompositionConicGradientBrushHooks, value: f64) {
164        let mut changed = false;
165        let old_value = self.angle.get();
166        if old_value.differs(&value) {
167            CompositionConicGradientBrushHooks::validate_angle_change(host, old_value, value);
168            CompositionConicGradientBrushHooks::on_angle_changing(host);
169            changed = true;
170            // Update the backing value
171            self.angle.set(value);
172            // Register object for serialization in the next batch
173            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::ANGLE);
174            host.register_for_serialization();
175            // Reset previous animation if any
176            host.pending_animations().remove(ServerCompositionConicGradientBrushProps::id_of_angle_property().base());
177            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() & !CompositionConicGradientBrushChangedFields::ANGLE_ANIMATED);
178            // Check for implicit animations
179            if let Some(animation) = host.implicit_animation("Angle") {
180                // Animation affects only current property
181                if let Some(a) = animation.as_composition_animation() {
182                    self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::ANGLE_ANIMATED);
183                    host.pending_animations().set(
184                        ServerCompositionConicGradientBrushProps::id_of_angle_property().base(),
185                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
186                    );
187                }
188                // Animation is triggered by the current field, but does not necessary affects it
189                host.start_animation_group(&animation, "Angle", ExpressionVariant::create(value));
190            }
191        }
192        self.angle.set(value);
193        if changed {
194            CompositionConicGradientBrushHooks::on_angle_changed(host);
195        }
196    }
197
198    /// `Center` (animated).
199    pub fn center(&self) -> RelativePoint {
200        self.center.get()
201    }
202
203    /// Sets `Center` (animated).
204    pub fn set_center(&self, host: &dyn CompositionConicGradientBrushHooks, value: RelativePoint) {
205        let mut changed = false;
206        let old_value = self.center.get();
207        if old_value.differs(&value) {
208            CompositionConicGradientBrushHooks::validate_center_change(host, old_value, value);
209            CompositionConicGradientBrushHooks::on_center_changing(host);
210            changed = true;
211            // Update the backing value
212            self.center.set(value);
213            // Register object for serialization in the next batch
214            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::CENTER);
215            host.register_for_serialization();
216            // Reset previous animation if any
217            host.pending_animations().remove(ServerCompositionConicGradientBrushProps::id_of_center_property().base());
218            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() & !CompositionConicGradientBrushChangedFields::CENTER_ANIMATED);
219            // Check for implicit animations
220            if let Some(animation) = host.implicit_animation("Center") {
221                // Animation affects only current property
222                if let Some(a) = animation.as_composition_animation() {
223                    self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::CENTER_ANIMATED);
224                    host.pending_animations().set(
225                        ServerCompositionConicGradientBrushProps::id_of_center_property().base(),
226                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
227                    );
228                }
229                // Animation is triggered by the current field, but does not necessary affects it
230                host.start_animation_group(&animation, "Center", ExpressionVariant::create(value));
231            }
232        }
233        self.center.set(value);
234        if changed {
235            CompositionConicGradientBrushHooks::on_center_changed(host);
236        }
237    }
238
239    /// `AnchorPoint` (animated, FerroUI overlay).
240    pub fn anchor_point(&self) -> Vector {
241        self.anchor_point.get()
242    }
243
244    /// Sets `AnchorPoint` (animated, FerroUI overlay).
245    pub fn set_anchor_point(&self, host: &dyn CompositionConicGradientBrushHooks, value: Vector) {
246        let mut changed = false;
247        let old_value = self.anchor_point.get();
248        if old_value.differs(&value) {
249            CompositionConicGradientBrushHooks::validate_anchor_point_change(host, old_value, value);
250            CompositionConicGradientBrushHooks::on_anchor_point_changing(host);
251            changed = true;
252            // Update the backing value
253            self.anchor_point.set(value);
254            // Register object for serialization in the next batch
255            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::ANCHOR_POINT);
256            host.register_for_serialization();
257            // Reset previous animation if any
258            host.pending_animations().remove(ServerCompositionConicGradientBrushProps::id_of_anchor_point_property().base());
259            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() & !CompositionConicGradientBrushChangedFields::ANCHOR_POINT_ANIMATED);
260            // Check for implicit animations
261            if let Some(animation) = host.implicit_animation("AnchorPoint") {
262                // Animation affects only current property
263                if let Some(a) = animation.as_composition_animation() {
264                    self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::ANCHOR_POINT_ANIMATED);
265                    host.pending_animations().set(
266                        ServerCompositionConicGradientBrushProps::id_of_anchor_point_property().base(),
267                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
268                    );
269                }
270                // Animation is triggered by the current field, but does not necessary affects it
271                host.start_animation_group(&animation, "AnchorPoint", ExpressionVariant::create(value));
272            }
273        }
274        self.anchor_point.set(value);
275        if changed {
276            CompositionConicGradientBrushHooks::on_anchor_point_changed(host);
277        }
278    }
279
280    /// `CenterPoint` (animated, FerroUI overlay).
281    pub fn center_point(&self) -> Vector {
282        self.center_point.get()
283    }
284
285    /// Sets `CenterPoint` (animated, FerroUI overlay).
286    pub fn set_center_point(&self, host: &dyn CompositionConicGradientBrushHooks, value: Vector) {
287        let mut changed = false;
288        let old_value = self.center_point.get();
289        if old_value.differs(&value) {
290            CompositionConicGradientBrushHooks::validate_center_point_change(host, old_value, value);
291            CompositionConicGradientBrushHooks::on_center_point_changing(host);
292            changed = true;
293            // Update the backing value
294            self.center_point.set(value);
295            // Register object for serialization in the next batch
296            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::CENTER_POINT);
297            host.register_for_serialization();
298            // Reset previous animation if any
299            host.pending_animations().remove(ServerCompositionConicGradientBrushProps::id_of_center_point_property().base());
300            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() & !CompositionConicGradientBrushChangedFields::CENTER_POINT_ANIMATED);
301            // Check for implicit animations
302            if let Some(animation) = host.implicit_animation("CenterPoint") {
303                // Animation affects only current property
304                if let Some(a) = animation.as_composition_animation() {
305                    self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::CENTER_POINT_ANIMATED);
306                    host.pending_animations().set(
307                        ServerCompositionConicGradientBrushProps::id_of_center_point_property().base(),
308                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
309                    );
310                }
311                // Animation is triggered by the current field, but does not necessary affects it
312                host.start_animation_group(&animation, "CenterPoint", ExpressionVariant::create(value));
313            }
314        }
315        self.center_point.set(value);
316        if changed {
317            CompositionConicGradientBrushHooks::on_center_point_changed(host);
318        }
319    }
320
321    /// `Offset` (animated, FerroUI overlay).
322    pub fn offset(&self) -> Vector {
323        self.offset.get()
324    }
325
326    /// Sets `Offset` (animated, FerroUI overlay).
327    pub fn set_offset(&self, host: &dyn CompositionConicGradientBrushHooks, value: Vector) {
328        let mut changed = false;
329        let old_value = self.offset.get();
330        if old_value.differs(&value) {
331            CompositionConicGradientBrushHooks::validate_offset_change(host, old_value, value);
332            CompositionConicGradientBrushHooks::on_offset_changing(host);
333            changed = true;
334            // Update the backing value
335            self.offset.set(value);
336            // Register object for serialization in the next batch
337            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::OFFSET);
338            host.register_for_serialization();
339            // Reset previous animation if any
340            host.pending_animations().remove(ServerCompositionConicGradientBrushProps::id_of_offset_property().base());
341            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() & !CompositionConicGradientBrushChangedFields::OFFSET_ANIMATED);
342            // Check for implicit animations
343            if let Some(animation) = host.implicit_animation("Offset") {
344                // Animation affects only current property
345                if let Some(a) = animation.as_composition_animation() {
346                    self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::OFFSET_ANIMATED);
347                    host.pending_animations().set(
348                        ServerCompositionConicGradientBrushProps::id_of_offset_property().base(),
349                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
350                    );
351                }
352                // Animation is triggered by the current field, but does not necessary affects it
353                host.start_animation_group(&animation, "Offset", ExpressionVariant::create(value));
354            }
355        }
356        self.offset.set(value);
357        if changed {
358            CompositionConicGradientBrushHooks::on_offset_changed(host);
359        }
360    }
361
362    /// `RotationAngle` (animated, FerroUI overlay).
363    pub fn rotation_angle(&self) -> f32 {
364        self.rotation_angle.get()
365    }
366
367    /// Sets `RotationAngle` (animated, FerroUI overlay).
368    pub fn set_rotation_angle(&self, host: &dyn CompositionConicGradientBrushHooks, value: f32) {
369        let mut changed = false;
370        let old_value = self.rotation_angle.get();
371        if old_value.differs(&value) {
372            CompositionConicGradientBrushHooks::validate_rotation_angle_change(host, old_value, value);
373            CompositionConicGradientBrushHooks::on_rotation_angle_changing(host);
374            changed = true;
375            // Update the backing value
376            self.rotation_angle.set(value);
377            // Register object for serialization in the next batch
378            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::ROTATION_ANGLE);
379            host.register_for_serialization();
380            // Reset previous animation if any
381            host.pending_animations().remove(ServerCompositionConicGradientBrushProps::id_of_rotation_angle_property().base());
382            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() & !CompositionConicGradientBrushChangedFields::ROTATION_ANGLE_ANIMATED);
383            // Check for implicit animations
384            if let Some(animation) = host.implicit_animation("RotationAngle") {
385                // Animation affects only current property
386                if let Some(a) = animation.as_composition_animation() {
387                    self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::ROTATION_ANGLE_ANIMATED);
388                    host.pending_animations().set(
389                        ServerCompositionConicGradientBrushProps::id_of_rotation_angle_property().base(),
390                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
391                    );
392                }
393                // Animation is triggered by the current field, but does not necessary affects it
394                host.start_animation_group(&animation, "RotationAngle", ExpressionVariant::create(value));
395            }
396        }
397        self.rotation_angle.set(value);
398        if changed {
399            CompositionConicGradientBrushHooks::on_rotation_angle_changed(host);
400        }
401    }
402
403    /// `Scale` (animated, default `Vector::new(1.0, 1.0)`, FerroUI overlay).
404    pub fn scale(&self) -> Vector {
405        self.scale.get()
406    }
407
408    /// Sets `Scale` (animated, default `Vector::new(1.0, 1.0)`, FerroUI overlay).
409    pub fn set_scale(&self, host: &dyn CompositionConicGradientBrushHooks, value: Vector) {
410        let mut changed = false;
411        let old_value = self.scale.get();
412        if old_value.differs(&value) {
413            CompositionConicGradientBrushHooks::validate_scale_change(host, old_value, value);
414            CompositionConicGradientBrushHooks::on_scale_changing(host);
415            changed = true;
416            // Update the backing value
417            self.scale.set(value);
418            // Register object for serialization in the next batch
419            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::SCALE);
420            host.register_for_serialization();
421            // Reset previous animation if any
422            host.pending_animations().remove(ServerCompositionConicGradientBrushProps::id_of_scale_property().base());
423            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() & !CompositionConicGradientBrushChangedFields::SCALE_ANIMATED);
424            // Check for implicit animations
425            if let Some(animation) = host.implicit_animation("Scale") {
426                // Animation affects only current property
427                if let Some(a) = animation.as_composition_animation() {
428                    self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::SCALE_ANIMATED);
429                    host.pending_animations().set(
430                        ServerCompositionConicGradientBrushProps::id_of_scale_property().base(),
431                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
432                    );
433                }
434                // Animation is triggered by the current field, but does not necessary affects it
435                host.start_animation_group(&animation, "Scale", ExpressionVariant::create(value));
436            }
437        }
438        self.scale.set(value);
439        if changed {
440            CompositionConicGradientBrushHooks::on_scale_changed(host);
441        }
442    }
443
444    /// `TransformMatrix` (animated, default `Matrix::IDENTITY`, FerroUI overlay).
445    pub fn transform_matrix(&self) -> Matrix {
446        self.transform_matrix.get()
447    }
448
449    /// Sets `TransformMatrix` (animated, default `Matrix::IDENTITY`, FerroUI overlay).
450    pub fn set_transform_matrix(&self, host: &dyn CompositionConicGradientBrushHooks, value: Matrix) {
451        let mut changed = false;
452        let old_value = self.transform_matrix.get();
453        if old_value.differs(&value) {
454            CompositionConicGradientBrushHooks::validate_transform_matrix_change(host, old_value, value);
455            CompositionConicGradientBrushHooks::on_transform_matrix_changing(host);
456            changed = true;
457            // Update the backing value
458            self.transform_matrix.set(value);
459            // Register object for serialization in the next batch
460            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::TRANSFORM_MATRIX);
461            host.register_for_serialization();
462            // Reset previous animation if any
463            host.pending_animations().remove(ServerCompositionConicGradientBrushProps::id_of_transform_matrix_property().base());
464            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() & !CompositionConicGradientBrushChangedFields::TRANSFORM_MATRIX_ANIMATED);
465            // Check for implicit animations
466            if let Some(animation) = host.implicit_animation("TransformMatrix") {
467                // Animation affects only current property
468                if let Some(a) = animation.as_composition_animation() {
469                    self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::TRANSFORM_MATRIX_ANIMATED);
470                    host.pending_animations().set(
471                        ServerCompositionConicGradientBrushProps::id_of_transform_matrix_property().base(),
472                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
473                    );
474                }
475                // Animation is triggered by the current field, but does not necessary affects it
476                host.start_animation_group(&animation, "TransformMatrix", ExpressionVariant::create(value));
477            }
478        }
479        self.transform_matrix.set(value);
480        if changed {
481            CompositionConicGradientBrushHooks::on_transform_matrix_changed(host);
482        }
483    }
484
485    /// Connects an animation with the named property. Returns `false` when
486    /// neither this class nor its generated bases have an animated property
487    /// of that name: the caller continues with its hand-written base.
488    pub fn start_animation(
489        &self,
490        host: &dyn CompositionConicGradientBrushHooks,
491        property_name: &str,
492        animation: &dyn ICompositionAnimation,
493        final_value: Option<ExpressionVariant>,
494    ) -> bool {
495        if property_name == "Angle" {
496            let server = animation.create_instance(host.server(), final_value);
497            host.pending_animations().set(ServerCompositionConicGradientBrushProps::id_of_angle_property().base(), server);
498            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::ANGLE_ANIMATED);
499            host.register_for_serialization();
500            return true;
501        }
502        if property_name == "Center" {
503            let server = animation.create_instance(host.server(), final_value);
504            host.pending_animations().set(ServerCompositionConicGradientBrushProps::id_of_center_property().base(), server);
505            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::CENTER_ANIMATED);
506            host.register_for_serialization();
507            return true;
508        }
509        if property_name == "AnchorPoint" {
510            let server = animation.create_instance(host.server(), final_value);
511            host.pending_animations().set(ServerCompositionConicGradientBrushProps::id_of_anchor_point_property().base(), server);
512            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::ANCHOR_POINT_ANIMATED);
513            host.register_for_serialization();
514            return true;
515        }
516        if property_name == "CenterPoint" {
517            let server = animation.create_instance(host.server(), final_value);
518            host.pending_animations().set(ServerCompositionConicGradientBrushProps::id_of_center_point_property().base(), server);
519            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::CENTER_POINT_ANIMATED);
520            host.register_for_serialization();
521            return true;
522        }
523        if property_name == "Offset" {
524            let server = animation.create_instance(host.server(), final_value);
525            host.pending_animations().set(ServerCompositionConicGradientBrushProps::id_of_offset_property().base(), server);
526            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::OFFSET_ANIMATED);
527            host.register_for_serialization();
528            return true;
529        }
530        if property_name == "RotationAngle" {
531            let server = animation.create_instance(host.server(), final_value);
532            host.pending_animations().set(ServerCompositionConicGradientBrushProps::id_of_rotation_angle_property().base(), server);
533            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::ROTATION_ANGLE_ANIMATED);
534            host.register_for_serialization();
535            return true;
536        }
537        if property_name == "Scale" {
538            let server = animation.create_instance(host.server(), final_value);
539            host.pending_animations().set(ServerCompositionConicGradientBrushProps::id_of_scale_property().base(), server);
540            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::SCALE_ANIMATED);
541            host.register_for_serialization();
542            return true;
543        }
544        if property_name == "TransformMatrix" {
545            let server = animation.create_instance(host.server(), final_value);
546            host.pending_animations().set(ServerCompositionConicGradientBrushProps::id_of_transform_matrix_property().base(), server);
547            self.changed_fields_of_composition_conic_gradient_brush.set(self.changed_fields_of_composition_conic_gradient_brush.get() | CompositionConicGradientBrushChangedFields::TRANSFORM_MATRIX_ANIMATED);
548            host.register_for_serialization();
549            return true;
550        }
551        false
552    }
553
554    /// Writes the changes of the object: the base class first, then the
555    /// changed-fields mask and the changed members of this class.
556    pub fn serialize_changes_core(&self, host: &dyn CompositionConicGradientBrushHooks, writer: &mut BatchStreamWriter<'_>) {
557        CompositionConicGradientBrushHooks::base_serialize_changes_core(host, writer);
558        let changed = self.changed_fields_of_composition_conic_gradient_brush.get();
559        writer.write(changed);
560        if changed.contains(CompositionConicGradientBrushChangedFields::ANGLE_ANIMATED) {
561            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionConicGradientBrushProps::id_of_angle_property().base()));
562        } else if changed.contains(CompositionConicGradientBrushChangedFields::ANGLE) {
563            writer.write(self.angle.get());
564        }
565        if changed.contains(CompositionConicGradientBrushChangedFields::CENTER_ANIMATED) {
566            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionConicGradientBrushProps::id_of_center_property().base()));
567        } else if changed.contains(CompositionConicGradientBrushChangedFields::CENTER) {
568            writer.write(self.center.get());
569        }
570        if changed.contains(CompositionConicGradientBrushChangedFields::ANCHOR_POINT_ANIMATED) {
571            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionConicGradientBrushProps::id_of_anchor_point_property().base()));
572        } else if changed.contains(CompositionConicGradientBrushChangedFields::ANCHOR_POINT) {
573            writer.write(self.anchor_point.get());
574        }
575        if changed.contains(CompositionConicGradientBrushChangedFields::CENTER_POINT_ANIMATED) {
576            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionConicGradientBrushProps::id_of_center_point_property().base()));
577        } else if changed.contains(CompositionConicGradientBrushChangedFields::CENTER_POINT) {
578            writer.write(self.center_point.get());
579        }
580        if changed.contains(CompositionConicGradientBrushChangedFields::OFFSET_ANIMATED) {
581            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionConicGradientBrushProps::id_of_offset_property().base()));
582        } else if changed.contains(CompositionConicGradientBrushChangedFields::OFFSET) {
583            writer.write(self.offset.get());
584        }
585        if changed.contains(CompositionConicGradientBrushChangedFields::ROTATION_ANGLE_ANIMATED) {
586            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionConicGradientBrushProps::id_of_rotation_angle_property().base()));
587        } else if changed.contains(CompositionConicGradientBrushChangedFields::ROTATION_ANGLE) {
588            writer.write(self.rotation_angle.get());
589        }
590        if changed.contains(CompositionConicGradientBrushChangedFields::SCALE_ANIMATED) {
591            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionConicGradientBrushProps::id_of_scale_property().base()));
592        } else if changed.contains(CompositionConicGradientBrushChangedFields::SCALE) {
593            writer.write(self.scale.get());
594        }
595        if changed.contains(CompositionConicGradientBrushChangedFields::TRANSFORM_MATRIX_ANIMATED) {
596            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionConicGradientBrushProps::id_of_transform_matrix_property().base()));
597        } else if changed.contains(CompositionConicGradientBrushChangedFields::TRANSFORM_MATRIX) {
598            writer.write(self.transform_matrix.get());
599        }
600        self.changed_fields_of_composition_conic_gradient_brush.set(CompositionConicGradientBrushChangedFields::empty());
601    }
602}
603
604/// The partial methods of `ServerCompositionConicGradientBrush`: implemented by the class that embeds
605/// [`ServerCompositionConicGradientBrushProps`]. Every hook defaults to doing nothing.
606pub trait ServerCompositionConicGradientBrushHooks: IServerAnimatedPropertyHost {
607    /// `base.DeserializeChangesCore(reader, committedAt)`: reads the changes of
608    /// the hand-written base class `ServerCompositionGradientBrush`.
609    fn base_deserialize_changes_core(&self, reader: &mut BatchStreamReader<'_>, committed_at: Duration);
610
611    fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
612    fn on_fields_deserialized(&self, _changed: CompositionConicGradientBrushChangedFields) {}
613}
614
615/// The server-side properties of `ServerCompositionConicGradientBrush`.
616pub struct ServerCompositionConicGradientBrushProps {
617    angle: Cell<f64>,
618    center: Cell<RelativePoint>,
619    anchor_point: Cell<Vector>,
620    center_point: Cell<Vector>,
621    offset: Cell<Vector>,
622    rotation_angle: Cell<f32>,
623    scale: Cell<Vector>,
624    transform_matrix: Cell<Matrix>,
625}
626
627impl Default for ServerCompositionConicGradientBrushProps {
628    fn default() -> Self {
629        Self::new()
630    }
631}
632
633impl ServerCompositionConicGradientBrushProps {
634    /// Creates the properties with every field at the default of its type; the
635    /// values of the UI thread arrive with the first batch.
636    pub fn new() -> Self {
637        Self {
638            angle: Cell::new(Default::default()),
639            center: Cell::new(Default::default()),
640            anchor_point: Cell::new(Default::default()),
641            center_point: Cell::new(Default::default()),
642            offset: Cell::new(Default::default()),
643            rotation_angle: Cell::new(Default::default()),
644            scale: Cell::new(Default::default()),
645            transform_matrix: Cell::new(Default::default()),
646        }
647    }
648
649    /// This block or the block of a base class, by type: what
650    /// `IServerObject::get_props` of the embedding class returns.
651    pub fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
652        if type_id == TypeId::of::<Self>() {
653            return Some(self);
654        }
655        None
656    }
657
658    /// The composition property of `Angle`.
659    pub fn id_of_angle_property() -> &'static CompositionPropertyOf<f64> {
660        static PROPERTY: OnceLock<CompositionPropertyOf<f64>> = OnceLock::new();
661        PROPERTY.get_or_init(|| {
662            CompositionProperty::register::<ServerCompositionConicGradientBrushProps, f64>(
663                "Angle",
664                "ServerCompositionConicGradientBrush",
665                |obj| props_of::<ServerCompositionConicGradientBrushProps>(obj).angle.get(),
666                |obj, v| props_of::<ServerCompositionConicGradientBrushProps>(obj).angle.set(v),
667                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionConicGradientBrushProps>(obj).angle.get())),
668                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionConicGradientBrushProps>(obj).angle.set(v.cast_or_default::<f64>())),
669            )
670        })
671    }
672
673    /// `Angle` (animated).
674    pub fn angle(&self) -> f64 {
675        self.angle.get()
676    }
677
678    pub fn set_angle(&self, host: &dyn ServerCompositionConicGradientBrushHooks, value: f64) {
679        self.angle.set(value);
680        host.remove_animation_for_property(Self::id_of_angle_property().base());
681    }
682
683    /// The composition property of `Center`.
684    pub fn id_of_center_property() -> &'static CompositionPropertyOf<RelativePoint> {
685        static PROPERTY: OnceLock<CompositionPropertyOf<RelativePoint>> = OnceLock::new();
686        PROPERTY.get_or_init(|| {
687            CompositionProperty::register::<ServerCompositionConicGradientBrushProps, RelativePoint>(
688                "Center",
689                "ServerCompositionConicGradientBrush",
690                |obj| props_of::<ServerCompositionConicGradientBrushProps>(obj).center.get(),
691                |obj, v| props_of::<ServerCompositionConicGradientBrushProps>(obj).center.set(v),
692                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionConicGradientBrushProps>(obj).center.get())),
693                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionConicGradientBrushProps>(obj).center.set(v.cast_or_default::<RelativePoint>())),
694            )
695        })
696    }
697
698    /// `Center` (animated).
699    pub fn center(&self) -> RelativePoint {
700        self.center.get()
701    }
702
703    pub fn set_center(&self, host: &dyn ServerCompositionConicGradientBrushHooks, value: RelativePoint) {
704        self.center.set(value);
705        host.remove_animation_for_property(Self::id_of_center_property().base());
706    }
707
708    /// The composition property of `AnchorPoint`.
709    pub fn id_of_anchor_point_property() -> &'static CompositionPropertyOf<Vector> {
710        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
711        PROPERTY.get_or_init(|| {
712            CompositionProperty::register::<ServerCompositionConicGradientBrushProps, Vector>(
713                "AnchorPoint",
714                "ServerCompositionConicGradientBrush",
715                |obj| props_of::<ServerCompositionConicGradientBrushProps>(obj).anchor_point.get(),
716                |obj, v| props_of::<ServerCompositionConicGradientBrushProps>(obj).anchor_point.set(v),
717                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionConicGradientBrushProps>(obj).anchor_point.get())),
718                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionConicGradientBrushProps>(obj).anchor_point.set(v.cast_or_default::<Vector>())),
719            )
720        })
721    }
722
723    /// `AnchorPoint` (animated).
724    pub fn anchor_point(&self) -> Vector {
725        self.anchor_point.get()
726    }
727
728    pub fn set_anchor_point(&self, host: &dyn ServerCompositionConicGradientBrushHooks, value: Vector) {
729        self.anchor_point.set(value);
730        host.remove_animation_for_property(Self::id_of_anchor_point_property().base());
731    }
732
733    /// The composition property of `CenterPoint`.
734    pub fn id_of_center_point_property() -> &'static CompositionPropertyOf<Vector> {
735        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
736        PROPERTY.get_or_init(|| {
737            CompositionProperty::register::<ServerCompositionConicGradientBrushProps, Vector>(
738                "CenterPoint",
739                "ServerCompositionConicGradientBrush",
740                |obj| props_of::<ServerCompositionConicGradientBrushProps>(obj).center_point.get(),
741                |obj, v| props_of::<ServerCompositionConicGradientBrushProps>(obj).center_point.set(v),
742                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionConicGradientBrushProps>(obj).center_point.get())),
743                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionConicGradientBrushProps>(obj).center_point.set(v.cast_or_default::<Vector>())),
744            )
745        })
746    }
747
748    /// `CenterPoint` (animated).
749    pub fn center_point(&self) -> Vector {
750        self.center_point.get()
751    }
752
753    pub fn set_center_point(&self, host: &dyn ServerCompositionConicGradientBrushHooks, value: Vector) {
754        self.center_point.set(value);
755        host.remove_animation_for_property(Self::id_of_center_point_property().base());
756    }
757
758    /// The composition property of `Offset`.
759    pub fn id_of_offset_property() -> &'static CompositionPropertyOf<Vector> {
760        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
761        PROPERTY.get_or_init(|| {
762            CompositionProperty::register::<ServerCompositionConicGradientBrushProps, Vector>(
763                "Offset",
764                "ServerCompositionConicGradientBrush",
765                |obj| props_of::<ServerCompositionConicGradientBrushProps>(obj).offset.get(),
766                |obj, v| props_of::<ServerCompositionConicGradientBrushProps>(obj).offset.set(v),
767                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionConicGradientBrushProps>(obj).offset.get())),
768                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionConicGradientBrushProps>(obj).offset.set(v.cast_or_default::<Vector>())),
769            )
770        })
771    }
772
773    /// `Offset` (animated).
774    pub fn offset(&self) -> Vector {
775        self.offset.get()
776    }
777
778    pub fn set_offset(&self, host: &dyn ServerCompositionConicGradientBrushHooks, value: Vector) {
779        self.offset.set(value);
780        host.remove_animation_for_property(Self::id_of_offset_property().base());
781    }
782
783    /// The composition property of `RotationAngle`.
784    pub fn id_of_rotation_angle_property() -> &'static CompositionPropertyOf<f32> {
785        static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
786        PROPERTY.get_or_init(|| {
787            CompositionProperty::register::<ServerCompositionConicGradientBrushProps, f32>(
788                "RotationAngle",
789                "ServerCompositionConicGradientBrush",
790                |obj| props_of::<ServerCompositionConicGradientBrushProps>(obj).rotation_angle.get(),
791                |obj, v| props_of::<ServerCompositionConicGradientBrushProps>(obj).rotation_angle.set(v),
792                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionConicGradientBrushProps>(obj).rotation_angle.get())),
793                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionConicGradientBrushProps>(obj).rotation_angle.set(v.cast_or_default::<f32>())),
794            )
795        })
796    }
797
798    /// `RotationAngle` (animated).
799    pub fn rotation_angle(&self) -> f32 {
800        self.rotation_angle.get()
801    }
802
803    pub fn set_rotation_angle(&self, host: &dyn ServerCompositionConicGradientBrushHooks, value: f32) {
804        self.rotation_angle.set(value);
805        host.remove_animation_for_property(Self::id_of_rotation_angle_property().base());
806    }
807
808    /// The composition property of `Scale`.
809    pub fn id_of_scale_property() -> &'static CompositionPropertyOf<Vector> {
810        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
811        PROPERTY.get_or_init(|| {
812            CompositionProperty::register::<ServerCompositionConicGradientBrushProps, Vector>(
813                "Scale",
814                "ServerCompositionConicGradientBrush",
815                |obj| props_of::<ServerCompositionConicGradientBrushProps>(obj).scale.get(),
816                |obj, v| props_of::<ServerCompositionConicGradientBrushProps>(obj).scale.set(v),
817                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionConicGradientBrushProps>(obj).scale.get())),
818                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionConicGradientBrushProps>(obj).scale.set(v.cast_or_default::<Vector>())),
819            )
820        })
821    }
822
823    /// `Scale` (animated).
824    pub fn scale(&self) -> Vector {
825        self.scale.get()
826    }
827
828    pub fn set_scale(&self, host: &dyn ServerCompositionConicGradientBrushHooks, value: Vector) {
829        self.scale.set(value);
830        host.remove_animation_for_property(Self::id_of_scale_property().base());
831    }
832
833    /// The composition property of `TransformMatrix`.
834    pub fn id_of_transform_matrix_property() -> &'static CompositionPropertyOf<Matrix> {
835        static PROPERTY: OnceLock<CompositionPropertyOf<Matrix>> = OnceLock::new();
836        PROPERTY.get_or_init(|| {
837            CompositionProperty::register::<ServerCompositionConicGradientBrushProps, Matrix>(
838                "TransformMatrix",
839                "ServerCompositionConicGradientBrush",
840                |obj| props_of::<ServerCompositionConicGradientBrushProps>(obj).transform_matrix.get(),
841                |obj, v| props_of::<ServerCompositionConicGradientBrushProps>(obj).transform_matrix.set(v),
842                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionConicGradientBrushProps>(obj).transform_matrix.get())),
843                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionConicGradientBrushProps>(obj).transform_matrix.set(v.cast_or_default::<Matrix>())),
844            )
845        })
846    }
847
848    /// `TransformMatrix` (animated).
849    pub fn transform_matrix(&self) -> Matrix {
850        self.transform_matrix.get()
851    }
852
853    pub fn set_transform_matrix(&self, host: &dyn ServerCompositionConicGradientBrushHooks, value: Matrix) {
854        self.transform_matrix.set(value);
855        host.remove_animation_for_property(Self::id_of_transform_matrix_property().base());
856    }
857
858    /// Reads the changes of the object: the base class first, then the
859    /// changed-fields mask and the changed members of this class.
860    pub fn deserialize_changes_core(
861        &self,
862        host: &dyn ServerCompositionConicGradientBrushHooks,
863        reader: &mut BatchStreamReader<'_>,
864        committed_at: Duration,
865    ) {
866        ServerCompositionConicGradientBrushHooks::base_deserialize_changes_core(host, reader, committed_at);
867        ServerCompositionConicGradientBrushHooks::deserialize_changes_extra(host, reader);
868        let changed = reader.read::<CompositionConicGradientBrushChangedFields>();
869        if changed.contains(CompositionConicGradientBrushChangedFields::ANGLE_ANIMATED) {
870            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
871                panic!("a batch starts an animation of `Angle` without an animation instance");
872            };
873            host.set_animated_value(
874                Self::id_of_angle_property().base(),
875                ExpressionVariant::create(self.angle.get()),
876                committed_at,
877                animation,
878            );
879        } else if changed.contains(CompositionConicGradientBrushChangedFields::ANGLE) {
880            let value = reader.read::<f64>();
881            self.set_angle(host, value);
882        }
883        if changed.contains(CompositionConicGradientBrushChangedFields::CENTER_ANIMATED) {
884            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
885                panic!("a batch starts an animation of `Center` without an animation instance");
886            };
887            host.set_animated_value(
888                Self::id_of_center_property().base(),
889                ExpressionVariant::create(self.center.get()),
890                committed_at,
891                animation,
892            );
893        } else if changed.contains(CompositionConicGradientBrushChangedFields::CENTER) {
894            let value = reader.read::<RelativePoint>();
895            self.set_center(host, value);
896        }
897        if changed.contains(CompositionConicGradientBrushChangedFields::ANCHOR_POINT_ANIMATED) {
898            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
899                panic!("a batch starts an animation of `AnchorPoint` without an animation instance");
900            };
901            host.set_animated_value(
902                Self::id_of_anchor_point_property().base(),
903                ExpressionVariant::create(self.anchor_point.get()),
904                committed_at,
905                animation,
906            );
907        } else if changed.contains(CompositionConicGradientBrushChangedFields::ANCHOR_POINT) {
908            let value = reader.read::<Vector>();
909            self.set_anchor_point(host, value);
910        }
911        if changed.contains(CompositionConicGradientBrushChangedFields::CENTER_POINT_ANIMATED) {
912            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
913                panic!("a batch starts an animation of `CenterPoint` without an animation instance");
914            };
915            host.set_animated_value(
916                Self::id_of_center_point_property().base(),
917                ExpressionVariant::create(self.center_point.get()),
918                committed_at,
919                animation,
920            );
921        } else if changed.contains(CompositionConicGradientBrushChangedFields::CENTER_POINT) {
922            let value = reader.read::<Vector>();
923            self.set_center_point(host, value);
924        }
925        if changed.contains(CompositionConicGradientBrushChangedFields::OFFSET_ANIMATED) {
926            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
927                panic!("a batch starts an animation of `Offset` without an animation instance");
928            };
929            host.set_animated_value(
930                Self::id_of_offset_property().base(),
931                ExpressionVariant::create(self.offset.get()),
932                committed_at,
933                animation,
934            );
935        } else if changed.contains(CompositionConicGradientBrushChangedFields::OFFSET) {
936            let value = reader.read::<Vector>();
937            self.set_offset(host, value);
938        }
939        if changed.contains(CompositionConicGradientBrushChangedFields::ROTATION_ANGLE_ANIMATED) {
940            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
941                panic!("a batch starts an animation of `RotationAngle` without an animation instance");
942            };
943            host.set_animated_value(
944                Self::id_of_rotation_angle_property().base(),
945                ExpressionVariant::create(self.rotation_angle.get()),
946                committed_at,
947                animation,
948            );
949        } else if changed.contains(CompositionConicGradientBrushChangedFields::ROTATION_ANGLE) {
950            let value = reader.read::<f32>();
951            self.set_rotation_angle(host, value);
952        }
953        if changed.contains(CompositionConicGradientBrushChangedFields::SCALE_ANIMATED) {
954            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
955                panic!("a batch starts an animation of `Scale` without an animation instance");
956            };
957            host.set_animated_value(
958                Self::id_of_scale_property().base(),
959                ExpressionVariant::create(self.scale.get()),
960                committed_at,
961                animation,
962            );
963        } else if changed.contains(CompositionConicGradientBrushChangedFields::SCALE) {
964            let value = reader.read::<Vector>();
965            self.set_scale(host, value);
966        }
967        if changed.contains(CompositionConicGradientBrushChangedFields::TRANSFORM_MATRIX_ANIMATED) {
968            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
969                panic!("a batch starts an animation of `TransformMatrix` without an animation instance");
970            };
971            host.set_animated_value(
972                Self::id_of_transform_matrix_property().base(),
973                ExpressionVariant::create(self.transform_matrix.get()),
974                committed_at,
975                animation,
976            );
977        } else if changed.contains(CompositionConicGradientBrushChangedFields::TRANSFORM_MATRIX) {
978            let value = reader.read::<Matrix>();
979            self.set_transform_matrix(host, value);
980        }
981        ServerCompositionConicGradientBrushHooks::on_fields_deserialized(host, changed);
982    }
983
984    /// The composition property with the given name, among the properties
985    /// of this class and of its generated bases that have a variant form.
986    pub fn get_composition_property(name: &str) -> Option<&'static CompositionProperty> {
987        if name == "Angle" {
988            return Some(Self::id_of_angle_property().base());
989        }
990        if name == "Center" {
991            return Some(Self::id_of_center_property().base());
992        }
993        if name == "AnchorPoint" {
994            return Some(Self::id_of_anchor_point_property().base());
995        }
996        if name == "CenterPoint" {
997            return Some(Self::id_of_center_point_property().base());
998        }
999        if name == "Offset" {
1000            return Some(Self::id_of_offset_property().base());
1001        }
1002        if name == "RotationAngle" {
1003            return Some(Self::id_of_rotation_angle_property().base());
1004        }
1005        if name == "Scale" {
1006            return Some(Self::id_of_scale_property().base());
1007        }
1008        if name == "TransformMatrix" {
1009            return Some(Self::id_of_transform_matrix_property().base());
1010        }
1011        None
1012    }
1013}