Skip to main content

ferroui_base/rendering/composition/generated/
inset_clip.rs

1// @generated by scripts/generate_composition.py — do not edit
2
3//! `InsetClip`.
4//!
5//! Defined by the FerroUI overlay (scripts/composition-schema-winui.xml).
6
7use bitflags::bitflags;
8use crate::rendering::composition::animations::AnimationInstanceFactory;
9use crate::rendering::composition::animations::ICompositionAnimation;
10use crate::rendering::composition::expressions::ExpressionVariant;
11use crate::rendering::composition::server::CompositionProperty;
12use crate::rendering::composition::server::CompositionPropertyOf;
13use crate::rendering::composition::server::ServerPropertyValue;
14use crate::rendering::composition::server::props_of;
15use crate::rendering::composition::transport::BatchStreamReader;
16use crate::rendering::composition::transport::BatchStreamWriter;
17use crate::rendering::composition::transport::BatchValue;
18use crate::rendering::composition::transport::BatchValueReader;
19use std::any::Any;
20use std::any::TypeId;
21use std::cell::Cell;
22use std::sync::OnceLock;
23use std::time::Duration;
24use super::CompositionClipHooks;
25use super::CompositionClipProps;
26use super::ServerCompositionClipHooks;
27use super::ServerCompositionClipProps;
28
29bitflags! {
30    /// The fields of `InsetClip` that changed since its last serialization.
31    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
32    pub struct InsetClipChangedFields: u8 {
33        const LEFT_INSET = 1;
34        const LEFT_INSET_ANIMATED = 2;
35        const TOP_INSET = 4;
36        const TOP_INSET_ANIMATED = 8;
37        const RIGHT_INSET = 16;
38        const RIGHT_INSET_ANIMATED = 32;
39        const BOTTOM_INSET = 64;
40        const BOTTOM_INSET_ANIMATED = 128;
41    }
42}
43
44impl BatchValue for InsetClipChangedFields {
45    #[inline]
46    fn write_to(&self, out: &mut Vec<u8>) {
47        self.bits().write_to(out);
48    }
49
50    #[inline]
51    fn read_from(input: &mut BatchValueReader<'_>) -> Self {
52        InsetClipChangedFields::from_bits_retain(u8::read_from(input))
53    }
54}
55
56/// The partial methods of `InsetClip`: implemented by the class that embeds
57/// [`InsetClipProps`]. Every hook defaults to doing nothing.
58pub trait InsetClipHooks: CompositionClipHooks {
59    fn initialize_defaults_extra(&self) {}
60
61    fn validate_left_inset_change(&self, _old_value: f32, _new_value: f32) {}
62    fn on_left_inset_changed(&self) {}
63    fn on_left_inset_changing(&self) {}
64
65    fn validate_top_inset_change(&self, _old_value: f32, _new_value: f32) {}
66    fn on_top_inset_changed(&self) {}
67    fn on_top_inset_changing(&self) {}
68
69    fn validate_right_inset_change(&self, _old_value: f32, _new_value: f32) {}
70    fn on_right_inset_changed(&self) {}
71    fn on_right_inset_changing(&self) {}
72
73    fn validate_bottom_inset_change(&self, _old_value: f32, _new_value: f32) {}
74    fn on_bottom_inset_changed(&self) {}
75    fn on_bottom_inset_changing(&self) {}
76}
77
78/// The UI-thread properties of `InsetClip`.
79pub struct InsetClipProps {
80    base: CompositionClipProps,
81    changed_fields_of_inset_clip: Cell<InsetClipChangedFields>,
82    left_inset: Cell<f32>,
83    top_inset: Cell<f32>,
84    right_inset: Cell<f32>,
85    bottom_inset: Cell<f32>,
86}
87
88impl Default for InsetClipProps {
89    fn default() -> Self {
90        Self::new()
91    }
92}
93
94impl InsetClipProps {
95    /// Creates the properties with every field at the default of its type.
96    /// The defaults of the schema are applied by
97    /// [`initialize_defaults`](Self::initialize_defaults).
98    pub fn new() -> Self {
99        Self {
100            base: CompositionClipProps::new(),
101            changed_fields_of_inset_clip: Cell::new(InsetClipChangedFields::empty()),
102            left_inset: Cell::new(Default::default()),
103            top_inset: Cell::new(Default::default()),
104            right_inset: Cell::new(Default::default()),
105            bottom_inset: Cell::new(Default::default()),
106        }
107    }
108
109    /// The properties of the base class.
110    pub fn base(&self) -> &CompositionClipProps {
111        &self.base
112    }
113
114    /// The `InitializeDefaults` calls of the constructor chain: the base
115    /// classes first, then this class.
116    pub fn initialize_defaults(&self, host: &dyn InsetClipHooks) {
117        self.base.initialize_defaults(host);
118        self.initialize_own_defaults(host);
119    }
120
121    /// `InitializeDefaults` of this class alone.
122    pub fn initialize_own_defaults(&self, host: &dyn InsetClipHooks) {
123        InsetClipHooks::initialize_defaults_extra(host);
124    }
125
126    /// `LeftInset` (animated, FerroUI overlay).
127    pub fn left_inset(&self) -> f32 {
128        self.left_inset.get()
129    }
130
131    /// Sets `LeftInset` (animated, FerroUI overlay).
132    pub fn set_left_inset(&self, host: &dyn InsetClipHooks, value: f32) {
133        let mut changed = false;
134        let old_value = self.left_inset.get();
135        if old_value.differs(&value) {
136            InsetClipHooks::validate_left_inset_change(host, old_value, value);
137            InsetClipHooks::on_left_inset_changing(host);
138            changed = true;
139            // Update the backing value
140            self.left_inset.set(value);
141            // Register object for serialization in the next batch
142            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::LEFT_INSET);
143            host.register_for_serialization();
144            // Reset previous animation if any
145            host.pending_animations().remove(ServerInsetClipProps::id_of_left_inset_property().base());
146            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() & !InsetClipChangedFields::LEFT_INSET_ANIMATED);
147            // Check for implicit animations
148            if let Some(animation) = host.implicit_animation("LeftInset") {
149                // Animation affects only current property
150                if let Some(a) = animation.as_composition_animation() {
151                    self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::LEFT_INSET_ANIMATED);
152                    host.pending_animations().set(
153                        ServerInsetClipProps::id_of_left_inset_property().base(),
154                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
155                    );
156                }
157                // Animation is triggered by the current field, but does not necessary affects it
158                host.start_animation_group(&animation, "LeftInset", ExpressionVariant::create(value));
159            }
160        }
161        self.left_inset.set(value);
162        if changed {
163            InsetClipHooks::on_left_inset_changed(host);
164        }
165    }
166
167    /// `TopInset` (animated, FerroUI overlay).
168    pub fn top_inset(&self) -> f32 {
169        self.top_inset.get()
170    }
171
172    /// Sets `TopInset` (animated, FerroUI overlay).
173    pub fn set_top_inset(&self, host: &dyn InsetClipHooks, value: f32) {
174        let mut changed = false;
175        let old_value = self.top_inset.get();
176        if old_value.differs(&value) {
177            InsetClipHooks::validate_top_inset_change(host, old_value, value);
178            InsetClipHooks::on_top_inset_changing(host);
179            changed = true;
180            // Update the backing value
181            self.top_inset.set(value);
182            // Register object for serialization in the next batch
183            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::TOP_INSET);
184            host.register_for_serialization();
185            // Reset previous animation if any
186            host.pending_animations().remove(ServerInsetClipProps::id_of_top_inset_property().base());
187            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() & !InsetClipChangedFields::TOP_INSET_ANIMATED);
188            // Check for implicit animations
189            if let Some(animation) = host.implicit_animation("TopInset") {
190                // Animation affects only current property
191                if let Some(a) = animation.as_composition_animation() {
192                    self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::TOP_INSET_ANIMATED);
193                    host.pending_animations().set(
194                        ServerInsetClipProps::id_of_top_inset_property().base(),
195                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
196                    );
197                }
198                // Animation is triggered by the current field, but does not necessary affects it
199                host.start_animation_group(&animation, "TopInset", ExpressionVariant::create(value));
200            }
201        }
202        self.top_inset.set(value);
203        if changed {
204            InsetClipHooks::on_top_inset_changed(host);
205        }
206    }
207
208    /// `RightInset` (animated, FerroUI overlay).
209    pub fn right_inset(&self) -> f32 {
210        self.right_inset.get()
211    }
212
213    /// Sets `RightInset` (animated, FerroUI overlay).
214    pub fn set_right_inset(&self, host: &dyn InsetClipHooks, value: f32) {
215        let mut changed = false;
216        let old_value = self.right_inset.get();
217        if old_value.differs(&value) {
218            InsetClipHooks::validate_right_inset_change(host, old_value, value);
219            InsetClipHooks::on_right_inset_changing(host);
220            changed = true;
221            // Update the backing value
222            self.right_inset.set(value);
223            // Register object for serialization in the next batch
224            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::RIGHT_INSET);
225            host.register_for_serialization();
226            // Reset previous animation if any
227            host.pending_animations().remove(ServerInsetClipProps::id_of_right_inset_property().base());
228            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() & !InsetClipChangedFields::RIGHT_INSET_ANIMATED);
229            // Check for implicit animations
230            if let Some(animation) = host.implicit_animation("RightInset") {
231                // Animation affects only current property
232                if let Some(a) = animation.as_composition_animation() {
233                    self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::RIGHT_INSET_ANIMATED);
234                    host.pending_animations().set(
235                        ServerInsetClipProps::id_of_right_inset_property().base(),
236                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
237                    );
238                }
239                // Animation is triggered by the current field, but does not necessary affects it
240                host.start_animation_group(&animation, "RightInset", ExpressionVariant::create(value));
241            }
242        }
243        self.right_inset.set(value);
244        if changed {
245            InsetClipHooks::on_right_inset_changed(host);
246        }
247    }
248
249    /// `BottomInset` (animated, FerroUI overlay).
250    pub fn bottom_inset(&self) -> f32 {
251        self.bottom_inset.get()
252    }
253
254    /// Sets `BottomInset` (animated, FerroUI overlay).
255    pub fn set_bottom_inset(&self, host: &dyn InsetClipHooks, value: f32) {
256        let mut changed = false;
257        let old_value = self.bottom_inset.get();
258        if old_value.differs(&value) {
259            InsetClipHooks::validate_bottom_inset_change(host, old_value, value);
260            InsetClipHooks::on_bottom_inset_changing(host);
261            changed = true;
262            // Update the backing value
263            self.bottom_inset.set(value);
264            // Register object for serialization in the next batch
265            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::BOTTOM_INSET);
266            host.register_for_serialization();
267            // Reset previous animation if any
268            host.pending_animations().remove(ServerInsetClipProps::id_of_bottom_inset_property().base());
269            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() & !InsetClipChangedFields::BOTTOM_INSET_ANIMATED);
270            // Check for implicit animations
271            if let Some(animation) = host.implicit_animation("BottomInset") {
272                // Animation affects only current property
273                if let Some(a) = animation.as_composition_animation() {
274                    self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::BOTTOM_INSET_ANIMATED);
275                    host.pending_animations().set(
276                        ServerInsetClipProps::id_of_bottom_inset_property().base(),
277                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
278                    );
279                }
280                // Animation is triggered by the current field, but does not necessary affects it
281                host.start_animation_group(&animation, "BottomInset", ExpressionVariant::create(value));
282            }
283        }
284        self.bottom_inset.set(value);
285        if changed {
286            InsetClipHooks::on_bottom_inset_changed(host);
287        }
288    }
289
290    /// Connects an animation with the named property. Returns `false` when
291    /// neither this class nor its generated bases have an animated property
292    /// of that name: the caller continues with its hand-written base.
293    pub fn start_animation(
294        &self,
295        host: &dyn InsetClipHooks,
296        property_name: &str,
297        animation: &dyn ICompositionAnimation,
298        final_value: Option<ExpressionVariant>,
299    ) -> bool {
300        if property_name == "LeftInset" {
301            let server = animation.create_instance(host.server(), final_value);
302            host.pending_animations().set(ServerInsetClipProps::id_of_left_inset_property().base(), server);
303            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::LEFT_INSET_ANIMATED);
304            host.register_for_serialization();
305            return true;
306        }
307        if property_name == "TopInset" {
308            let server = animation.create_instance(host.server(), final_value);
309            host.pending_animations().set(ServerInsetClipProps::id_of_top_inset_property().base(), server);
310            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::TOP_INSET_ANIMATED);
311            host.register_for_serialization();
312            return true;
313        }
314        if property_name == "RightInset" {
315            let server = animation.create_instance(host.server(), final_value);
316            host.pending_animations().set(ServerInsetClipProps::id_of_right_inset_property().base(), server);
317            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::RIGHT_INSET_ANIMATED);
318            host.register_for_serialization();
319            return true;
320        }
321        if property_name == "BottomInset" {
322            let server = animation.create_instance(host.server(), final_value);
323            host.pending_animations().set(ServerInsetClipProps::id_of_bottom_inset_property().base(), server);
324            self.changed_fields_of_inset_clip.set(self.changed_fields_of_inset_clip.get() | InsetClipChangedFields::BOTTOM_INSET_ANIMATED);
325            host.register_for_serialization();
326            return true;
327        }
328        self.base.start_animation(host, property_name, animation, final_value)
329    }
330
331    /// Writes the changes of the object: the base class first, then the
332    /// changed-fields mask and the changed members of this class.
333    pub fn serialize_changes_core(&self, host: &dyn InsetClipHooks, writer: &mut BatchStreamWriter<'_>) {
334        self.base.serialize_changes_core(host, writer);
335        let changed = self.changed_fields_of_inset_clip.get();
336        writer.write(changed);
337        if changed.contains(InsetClipChangedFields::LEFT_INSET_ANIMATED) {
338            writer.write_value(host.pending_animations().get_and_remove(ServerInsetClipProps::id_of_left_inset_property().base()));
339        } else if changed.contains(InsetClipChangedFields::LEFT_INSET) {
340            writer.write(self.left_inset.get());
341        }
342        if changed.contains(InsetClipChangedFields::TOP_INSET_ANIMATED) {
343            writer.write_value(host.pending_animations().get_and_remove(ServerInsetClipProps::id_of_top_inset_property().base()));
344        } else if changed.contains(InsetClipChangedFields::TOP_INSET) {
345            writer.write(self.top_inset.get());
346        }
347        if changed.contains(InsetClipChangedFields::RIGHT_INSET_ANIMATED) {
348            writer.write_value(host.pending_animations().get_and_remove(ServerInsetClipProps::id_of_right_inset_property().base()));
349        } else if changed.contains(InsetClipChangedFields::RIGHT_INSET) {
350            writer.write(self.right_inset.get());
351        }
352        if changed.contains(InsetClipChangedFields::BOTTOM_INSET_ANIMATED) {
353            writer.write_value(host.pending_animations().get_and_remove(ServerInsetClipProps::id_of_bottom_inset_property().base()));
354        } else if changed.contains(InsetClipChangedFields::BOTTOM_INSET) {
355            writer.write(self.bottom_inset.get());
356        }
357        self.changed_fields_of_inset_clip.set(InsetClipChangedFields::empty());
358    }
359}
360
361/// The partial methods of `ServerInsetClip`: implemented by the class that embeds
362/// [`ServerInsetClipProps`]. Every hook defaults to doing nothing.
363pub trait ServerInsetClipHooks: ServerCompositionClipHooks {
364    fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
365    fn on_fields_deserialized(&self, _changed: InsetClipChangedFields) {}
366}
367
368/// The server-side properties of `ServerInsetClip`.
369pub struct ServerInsetClipProps {
370    base: ServerCompositionClipProps,
371    left_inset: Cell<f32>,
372    top_inset: Cell<f32>,
373    right_inset: Cell<f32>,
374    bottom_inset: Cell<f32>,
375}
376
377impl Default for ServerInsetClipProps {
378    fn default() -> Self {
379        Self::new()
380    }
381}
382
383impl ServerInsetClipProps {
384    /// Creates the properties with every field at the default of its type; the
385    /// values of the UI thread arrive with the first batch.
386    pub fn new() -> Self {
387        Self {
388            base: ServerCompositionClipProps::new(),
389            left_inset: Cell::new(Default::default()),
390            top_inset: Cell::new(Default::default()),
391            right_inset: Cell::new(Default::default()),
392            bottom_inset: Cell::new(Default::default()),
393        }
394    }
395
396    /// The properties of the base class.
397    pub fn base(&self) -> &ServerCompositionClipProps {
398        &self.base
399    }
400
401    /// This block or the block of a base class, by type: what
402    /// `IServerObject::get_props` of the embedding class returns.
403    pub fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
404        if type_id == TypeId::of::<Self>() {
405            return Some(self);
406        }
407        self.base.find_props(type_id)
408    }
409
410    /// The composition property of `LeftInset`.
411    pub fn id_of_left_inset_property() -> &'static CompositionPropertyOf<f32> {
412        static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
413        PROPERTY.get_or_init(|| {
414            CompositionProperty::register::<ServerInsetClipProps, f32>(
415                "LeftInset",
416                "ServerInsetClip",
417                |obj| props_of::<ServerInsetClipProps>(obj).left_inset.get(),
418                |obj, v| props_of::<ServerInsetClipProps>(obj).left_inset.set(v),
419                Some(|obj| ExpressionVariant::create(props_of::<ServerInsetClipProps>(obj).left_inset.get())),
420                Some(|obj, v: ExpressionVariant| props_of::<ServerInsetClipProps>(obj).left_inset.set(v.cast_or_default::<f32>())),
421            )
422        })
423    }
424
425    /// `LeftInset` (animated).
426    pub fn left_inset(&self) -> f32 {
427        self.left_inset.get()
428    }
429
430    pub fn set_left_inset(&self, host: &dyn ServerInsetClipHooks, value: f32) {
431        self.left_inset.set(value);
432        host.remove_animation_for_property(Self::id_of_left_inset_property().base());
433    }
434
435    /// The composition property of `TopInset`.
436    pub fn id_of_top_inset_property() -> &'static CompositionPropertyOf<f32> {
437        static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
438        PROPERTY.get_or_init(|| {
439            CompositionProperty::register::<ServerInsetClipProps, f32>(
440                "TopInset",
441                "ServerInsetClip",
442                |obj| props_of::<ServerInsetClipProps>(obj).top_inset.get(),
443                |obj, v| props_of::<ServerInsetClipProps>(obj).top_inset.set(v),
444                Some(|obj| ExpressionVariant::create(props_of::<ServerInsetClipProps>(obj).top_inset.get())),
445                Some(|obj, v: ExpressionVariant| props_of::<ServerInsetClipProps>(obj).top_inset.set(v.cast_or_default::<f32>())),
446            )
447        })
448    }
449
450    /// `TopInset` (animated).
451    pub fn top_inset(&self) -> f32 {
452        self.top_inset.get()
453    }
454
455    pub fn set_top_inset(&self, host: &dyn ServerInsetClipHooks, value: f32) {
456        self.top_inset.set(value);
457        host.remove_animation_for_property(Self::id_of_top_inset_property().base());
458    }
459
460    /// The composition property of `RightInset`.
461    pub fn id_of_right_inset_property() -> &'static CompositionPropertyOf<f32> {
462        static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
463        PROPERTY.get_or_init(|| {
464            CompositionProperty::register::<ServerInsetClipProps, f32>(
465                "RightInset",
466                "ServerInsetClip",
467                |obj| props_of::<ServerInsetClipProps>(obj).right_inset.get(),
468                |obj, v| props_of::<ServerInsetClipProps>(obj).right_inset.set(v),
469                Some(|obj| ExpressionVariant::create(props_of::<ServerInsetClipProps>(obj).right_inset.get())),
470                Some(|obj, v: ExpressionVariant| props_of::<ServerInsetClipProps>(obj).right_inset.set(v.cast_or_default::<f32>())),
471            )
472        })
473    }
474
475    /// `RightInset` (animated).
476    pub fn right_inset(&self) -> f32 {
477        self.right_inset.get()
478    }
479
480    pub fn set_right_inset(&self, host: &dyn ServerInsetClipHooks, value: f32) {
481        self.right_inset.set(value);
482        host.remove_animation_for_property(Self::id_of_right_inset_property().base());
483    }
484
485    /// The composition property of `BottomInset`.
486    pub fn id_of_bottom_inset_property() -> &'static CompositionPropertyOf<f32> {
487        static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
488        PROPERTY.get_or_init(|| {
489            CompositionProperty::register::<ServerInsetClipProps, f32>(
490                "BottomInset",
491                "ServerInsetClip",
492                |obj| props_of::<ServerInsetClipProps>(obj).bottom_inset.get(),
493                |obj, v| props_of::<ServerInsetClipProps>(obj).bottom_inset.set(v),
494                Some(|obj| ExpressionVariant::create(props_of::<ServerInsetClipProps>(obj).bottom_inset.get())),
495                Some(|obj, v: ExpressionVariant| props_of::<ServerInsetClipProps>(obj).bottom_inset.set(v.cast_or_default::<f32>())),
496            )
497        })
498    }
499
500    /// `BottomInset` (animated).
501    pub fn bottom_inset(&self) -> f32 {
502        self.bottom_inset.get()
503    }
504
505    pub fn set_bottom_inset(&self, host: &dyn ServerInsetClipHooks, value: f32) {
506        self.bottom_inset.set(value);
507        host.remove_animation_for_property(Self::id_of_bottom_inset_property().base());
508    }
509
510    /// Reads the changes of the object: the base class first, then the
511    /// changed-fields mask and the changed members of this class.
512    pub fn deserialize_changes_core(
513        &self,
514        host: &dyn ServerInsetClipHooks,
515        reader: &mut BatchStreamReader<'_>,
516        committed_at: Duration,
517    ) {
518        self.base.deserialize_changes_core(host, reader, committed_at);
519        ServerInsetClipHooks::deserialize_changes_extra(host, reader);
520        let changed = reader.read::<InsetClipChangedFields>();
521        if changed.contains(InsetClipChangedFields::LEFT_INSET_ANIMATED) {
522            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
523                panic!("a batch starts an animation of `LeftInset` without an animation instance");
524            };
525            host.set_animated_value(
526                Self::id_of_left_inset_property().base(),
527                ExpressionVariant::create(self.left_inset.get()),
528                committed_at,
529                animation,
530            );
531        } else if changed.contains(InsetClipChangedFields::LEFT_INSET) {
532            let value = reader.read::<f32>();
533            self.set_left_inset(host, value);
534        }
535        if changed.contains(InsetClipChangedFields::TOP_INSET_ANIMATED) {
536            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
537                panic!("a batch starts an animation of `TopInset` without an animation instance");
538            };
539            host.set_animated_value(
540                Self::id_of_top_inset_property().base(),
541                ExpressionVariant::create(self.top_inset.get()),
542                committed_at,
543                animation,
544            );
545        } else if changed.contains(InsetClipChangedFields::TOP_INSET) {
546            let value = reader.read::<f32>();
547            self.set_top_inset(host, value);
548        }
549        if changed.contains(InsetClipChangedFields::RIGHT_INSET_ANIMATED) {
550            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
551                panic!("a batch starts an animation of `RightInset` without an animation instance");
552            };
553            host.set_animated_value(
554                Self::id_of_right_inset_property().base(),
555                ExpressionVariant::create(self.right_inset.get()),
556                committed_at,
557                animation,
558            );
559        } else if changed.contains(InsetClipChangedFields::RIGHT_INSET) {
560            let value = reader.read::<f32>();
561            self.set_right_inset(host, value);
562        }
563        if changed.contains(InsetClipChangedFields::BOTTOM_INSET_ANIMATED) {
564            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
565                panic!("a batch starts an animation of `BottomInset` without an animation instance");
566            };
567            host.set_animated_value(
568                Self::id_of_bottom_inset_property().base(),
569                ExpressionVariant::create(self.bottom_inset.get()),
570                committed_at,
571                animation,
572            );
573        } else if changed.contains(InsetClipChangedFields::BOTTOM_INSET) {
574            let value = reader.read::<f32>();
575            self.set_bottom_inset(host, value);
576        }
577        ServerInsetClipHooks::on_fields_deserialized(host, changed);
578    }
579
580    /// The composition property with the given name, among the properties
581    /// of this class and of its generated bases that have a variant form.
582    pub fn get_composition_property(name: &str) -> Option<&'static CompositionProperty> {
583        if name == "LeftInset" {
584            return Some(Self::id_of_left_inset_property().base());
585        }
586        if name == "TopInset" {
587            return Some(Self::id_of_top_inset_property().base());
588        }
589        if name == "RightInset" {
590            return Some(Self::id_of_right_inset_property().base());
591        }
592        if name == "BottomInset" {
593            return Some(Self::id_of_bottom_inset_property().base());
594        }
595        ServerCompositionClipProps::get_composition_property(name)
596    }
597}