Skip to main content

ferroui_base/rendering/composition/generated/
composition_rectangle_geometry.rs

1// @generated by scripts/generate_composition.py — do not edit
2
3//! `CompositionRectangleGeometry`.
4//!
5//! Defined by the FerroUI overlay (scripts/composition-schema-winui.xml).
6
7use bitflags::bitflags;
8use crate::Vector;
9use crate::rendering::composition::animations::AnimationInstanceFactory;
10use crate::rendering::composition::animations::ICompositionAnimation;
11use crate::rendering::composition::expressions::ExpressionVariant;
12use crate::rendering::composition::server::CompositionProperty;
13use crate::rendering::composition::server::CompositionPropertyOf;
14use crate::rendering::composition::server::ServerPropertyValue;
15use crate::rendering::composition::server::props_of;
16use crate::rendering::composition::transport::BatchStreamReader;
17use crate::rendering::composition::transport::BatchStreamWriter;
18use crate::rendering::composition::transport::BatchValue;
19use crate::rendering::composition::transport::BatchValueReader;
20use std::any::Any;
21use std::any::TypeId;
22use std::cell::Cell;
23use std::sync::OnceLock;
24use std::time::Duration;
25use super::CompositionGeometryHooks;
26use super::CompositionGeometryProps;
27use super::ServerCompositionGeometryHooks;
28use super::ServerCompositionGeometryProps;
29
30bitflags! {
31    /// The fields of `CompositionRectangleGeometry` that changed since its last serialization.
32    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
33    pub struct CompositionRectangleGeometryChangedFields: u8 {
34        const OFFSET = 1;
35        const OFFSET_ANIMATED = 2;
36        const SIZE = 4;
37        const SIZE_ANIMATED = 8;
38    }
39}
40
41impl BatchValue for CompositionRectangleGeometryChangedFields {
42    #[inline]
43    fn write_to(&self, out: &mut Vec<u8>) {
44        self.bits().write_to(out);
45    }
46
47    #[inline]
48    fn read_from(input: &mut BatchValueReader<'_>) -> Self {
49        CompositionRectangleGeometryChangedFields::from_bits_retain(u8::read_from(input))
50    }
51}
52
53/// The partial methods of `CompositionRectangleGeometry`: implemented by the class that embeds
54/// [`CompositionRectangleGeometryProps`]. Every hook defaults to doing nothing.
55pub trait CompositionRectangleGeometryHooks: CompositionGeometryHooks {
56    fn initialize_defaults_extra(&self) {}
57
58    fn validate_offset_change(&self, _old_value: Vector, _new_value: Vector) {}
59    fn on_offset_changed(&self) {}
60    fn on_offset_changing(&self) {}
61
62    fn validate_size_change(&self, _old_value: Vector, _new_value: Vector) {}
63    fn on_size_changed(&self) {}
64    fn on_size_changing(&self) {}
65}
66
67/// The UI-thread properties of `CompositionRectangleGeometry`.
68pub struct CompositionRectangleGeometryProps {
69    base: CompositionGeometryProps,
70    changed_fields_of_composition_rectangle_geometry: Cell<CompositionRectangleGeometryChangedFields>,
71    offset: Cell<Vector>,
72    size: Cell<Vector>,
73}
74
75impl Default for CompositionRectangleGeometryProps {
76    fn default() -> Self {
77        Self::new()
78    }
79}
80
81impl CompositionRectangleGeometryProps {
82    /// Creates the properties with every field at the default of its type.
83    /// The defaults of the schema are applied by
84    /// [`initialize_defaults`](Self::initialize_defaults).
85    pub fn new() -> Self {
86        Self {
87            base: CompositionGeometryProps::new(),
88            changed_fields_of_composition_rectangle_geometry: Cell::new(CompositionRectangleGeometryChangedFields::empty()),
89            offset: Cell::new(Default::default()),
90            size: Cell::new(Default::default()),
91        }
92    }
93
94    /// The properties of the base class.
95    pub fn base(&self) -> &CompositionGeometryProps {
96        &self.base
97    }
98
99    /// The `InitializeDefaults` calls of the constructor chain: the base
100    /// classes first, then this class.
101    pub fn initialize_defaults(&self, host: &dyn CompositionRectangleGeometryHooks) {
102        self.base.initialize_defaults(host);
103        self.initialize_own_defaults(host);
104    }
105
106    /// `InitializeDefaults` of this class alone.
107    pub fn initialize_own_defaults(&self, host: &dyn CompositionRectangleGeometryHooks) {
108        CompositionRectangleGeometryHooks::initialize_defaults_extra(host);
109    }
110
111    /// `Offset` (animated, FerroUI overlay).
112    pub fn offset(&self) -> Vector {
113        self.offset.get()
114    }
115
116    /// Sets `Offset` (animated, FerroUI overlay).
117    pub fn set_offset(&self, host: &dyn CompositionRectangleGeometryHooks, value: Vector) {
118        let mut changed = false;
119        let old_value = self.offset.get();
120        if old_value.differs(&value) {
121            CompositionRectangleGeometryHooks::validate_offset_change(host, old_value, value);
122            CompositionRectangleGeometryHooks::on_offset_changing(host);
123            changed = true;
124            // Update the backing value
125            self.offset.set(value);
126            // Register object for serialization in the next batch
127            self.changed_fields_of_composition_rectangle_geometry.set(self.changed_fields_of_composition_rectangle_geometry.get() | CompositionRectangleGeometryChangedFields::OFFSET);
128            host.register_for_serialization();
129            // Reset previous animation if any
130            host.pending_animations().remove(ServerCompositionRectangleGeometryProps::id_of_offset_property().base());
131            self.changed_fields_of_composition_rectangle_geometry.set(self.changed_fields_of_composition_rectangle_geometry.get() & !CompositionRectangleGeometryChangedFields::OFFSET_ANIMATED);
132            // Check for implicit animations
133            if let Some(animation) = host.implicit_animation("Offset") {
134                // Animation affects only current property
135                if let Some(a) = animation.as_composition_animation() {
136                    self.changed_fields_of_composition_rectangle_geometry.set(self.changed_fields_of_composition_rectangle_geometry.get() | CompositionRectangleGeometryChangedFields::OFFSET_ANIMATED);
137                    host.pending_animations().set(
138                        ServerCompositionRectangleGeometryProps::id_of_offset_property().base(),
139                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
140                    );
141                }
142                // Animation is triggered by the current field, but does not necessary affects it
143                host.start_animation_group(&animation, "Offset", ExpressionVariant::create(value));
144            }
145        }
146        self.offset.set(value);
147        if changed {
148            CompositionRectangleGeometryHooks::on_offset_changed(host);
149        }
150    }
151
152    /// `Size` (animated, FerroUI overlay).
153    pub fn size(&self) -> Vector {
154        self.size.get()
155    }
156
157    /// Sets `Size` (animated, FerroUI overlay).
158    pub fn set_size(&self, host: &dyn CompositionRectangleGeometryHooks, value: Vector) {
159        let mut changed = false;
160        let old_value = self.size.get();
161        if old_value.differs(&value) {
162            CompositionRectangleGeometryHooks::validate_size_change(host, old_value, value);
163            CompositionRectangleGeometryHooks::on_size_changing(host);
164            changed = true;
165            // Update the backing value
166            self.size.set(value);
167            // Register object for serialization in the next batch
168            self.changed_fields_of_composition_rectangle_geometry.set(self.changed_fields_of_composition_rectangle_geometry.get() | CompositionRectangleGeometryChangedFields::SIZE);
169            host.register_for_serialization();
170            // Reset previous animation if any
171            host.pending_animations().remove(ServerCompositionRectangleGeometryProps::id_of_size_property().base());
172            self.changed_fields_of_composition_rectangle_geometry.set(self.changed_fields_of_composition_rectangle_geometry.get() & !CompositionRectangleGeometryChangedFields::SIZE_ANIMATED);
173            // Check for implicit animations
174            if let Some(animation) = host.implicit_animation("Size") {
175                // Animation affects only current property
176                if let Some(a) = animation.as_composition_animation() {
177                    self.changed_fields_of_composition_rectangle_geometry.set(self.changed_fields_of_composition_rectangle_geometry.get() | CompositionRectangleGeometryChangedFields::SIZE_ANIMATED);
178                    host.pending_animations().set(
179                        ServerCompositionRectangleGeometryProps::id_of_size_property().base(),
180                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
181                    );
182                }
183                // Animation is triggered by the current field, but does not necessary affects it
184                host.start_animation_group(&animation, "Size", ExpressionVariant::create(value));
185            }
186        }
187        self.size.set(value);
188        if changed {
189            CompositionRectangleGeometryHooks::on_size_changed(host);
190        }
191    }
192
193    /// Connects an animation with the named property. Returns `false` when
194    /// neither this class nor its generated bases have an animated property
195    /// of that name: the caller continues with its hand-written base.
196    pub fn start_animation(
197        &self,
198        host: &dyn CompositionRectangleGeometryHooks,
199        property_name: &str,
200        animation: &dyn ICompositionAnimation,
201        final_value: Option<ExpressionVariant>,
202    ) -> bool {
203        if property_name == "Offset" {
204            let server = animation.create_instance(host.server(), final_value);
205            host.pending_animations().set(ServerCompositionRectangleGeometryProps::id_of_offset_property().base(), server);
206            self.changed_fields_of_composition_rectangle_geometry.set(self.changed_fields_of_composition_rectangle_geometry.get() | CompositionRectangleGeometryChangedFields::OFFSET_ANIMATED);
207            host.register_for_serialization();
208            return true;
209        }
210        if property_name == "Size" {
211            let server = animation.create_instance(host.server(), final_value);
212            host.pending_animations().set(ServerCompositionRectangleGeometryProps::id_of_size_property().base(), server);
213            self.changed_fields_of_composition_rectangle_geometry.set(self.changed_fields_of_composition_rectangle_geometry.get() | CompositionRectangleGeometryChangedFields::SIZE_ANIMATED);
214            host.register_for_serialization();
215            return true;
216        }
217        self.base.start_animation(host, property_name, animation, final_value)
218    }
219
220    /// Writes the changes of the object: the base class first, then the
221    /// changed-fields mask and the changed members of this class.
222    pub fn serialize_changes_core(&self, host: &dyn CompositionRectangleGeometryHooks, writer: &mut BatchStreamWriter<'_>) {
223        self.base.serialize_changes_core(host, writer);
224        let changed = self.changed_fields_of_composition_rectangle_geometry.get();
225        writer.write(changed);
226        if changed.contains(CompositionRectangleGeometryChangedFields::OFFSET_ANIMATED) {
227            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRectangleGeometryProps::id_of_offset_property().base()));
228        } else if changed.contains(CompositionRectangleGeometryChangedFields::OFFSET) {
229            writer.write(self.offset.get());
230        }
231        if changed.contains(CompositionRectangleGeometryChangedFields::SIZE_ANIMATED) {
232            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRectangleGeometryProps::id_of_size_property().base()));
233        } else if changed.contains(CompositionRectangleGeometryChangedFields::SIZE) {
234            writer.write(self.size.get());
235        }
236        self.changed_fields_of_composition_rectangle_geometry.set(CompositionRectangleGeometryChangedFields::empty());
237    }
238}
239
240/// The partial methods of `ServerCompositionRectangleGeometry`: implemented by the class that embeds
241/// [`ServerCompositionRectangleGeometryProps`]. Every hook defaults to doing nothing.
242pub trait ServerCompositionRectangleGeometryHooks: ServerCompositionGeometryHooks {
243    fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
244    fn on_fields_deserialized(&self, _changed: CompositionRectangleGeometryChangedFields) {}
245}
246
247/// The server-side properties of `ServerCompositionRectangleGeometry`.
248pub struct ServerCompositionRectangleGeometryProps {
249    base: ServerCompositionGeometryProps,
250    offset: Cell<Vector>,
251    size: Cell<Vector>,
252}
253
254impl Default for ServerCompositionRectangleGeometryProps {
255    fn default() -> Self {
256        Self::new()
257    }
258}
259
260impl ServerCompositionRectangleGeometryProps {
261    /// Creates the properties with every field at the default of its type; the
262    /// values of the UI thread arrive with the first batch.
263    pub fn new() -> Self {
264        Self {
265            base: ServerCompositionGeometryProps::new(),
266            offset: Cell::new(Default::default()),
267            size: Cell::new(Default::default()),
268        }
269    }
270
271    /// The properties of the base class.
272    pub fn base(&self) -> &ServerCompositionGeometryProps {
273        &self.base
274    }
275
276    /// This block or the block of a base class, by type: what
277    /// `IServerObject::get_props` of the embedding class returns.
278    pub fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
279        if type_id == TypeId::of::<Self>() {
280            return Some(self);
281        }
282        self.base.find_props(type_id)
283    }
284
285    /// The composition property of `Offset`.
286    pub fn id_of_offset_property() -> &'static CompositionPropertyOf<Vector> {
287        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
288        PROPERTY.get_or_init(|| {
289            CompositionProperty::register::<ServerCompositionRectangleGeometryProps, Vector>(
290                "Offset",
291                "ServerCompositionRectangleGeometry",
292                |obj| props_of::<ServerCompositionRectangleGeometryProps>(obj).offset.get(),
293                |obj, v| props_of::<ServerCompositionRectangleGeometryProps>(obj).offset.set(v),
294                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRectangleGeometryProps>(obj).offset.get())),
295                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRectangleGeometryProps>(obj).offset.set(v.cast_or_default::<Vector>())),
296            )
297        })
298    }
299
300    /// `Offset` (animated).
301    pub fn offset(&self) -> Vector {
302        self.offset.get()
303    }
304
305    pub fn set_offset(&self, host: &dyn ServerCompositionRectangleGeometryHooks, value: Vector) {
306        self.offset.set(value);
307        host.remove_animation_for_property(Self::id_of_offset_property().base());
308    }
309
310    /// The composition property of `Size`.
311    pub fn id_of_size_property() -> &'static CompositionPropertyOf<Vector> {
312        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
313        PROPERTY.get_or_init(|| {
314            CompositionProperty::register::<ServerCompositionRectangleGeometryProps, Vector>(
315                "Size",
316                "ServerCompositionRectangleGeometry",
317                |obj| props_of::<ServerCompositionRectangleGeometryProps>(obj).size.get(),
318                |obj, v| props_of::<ServerCompositionRectangleGeometryProps>(obj).size.set(v),
319                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRectangleGeometryProps>(obj).size.get())),
320                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRectangleGeometryProps>(obj).size.set(v.cast_or_default::<Vector>())),
321            )
322        })
323    }
324
325    /// `Size` (animated).
326    pub fn size(&self) -> Vector {
327        self.size.get()
328    }
329
330    pub fn set_size(&self, host: &dyn ServerCompositionRectangleGeometryHooks, value: Vector) {
331        self.size.set(value);
332        host.remove_animation_for_property(Self::id_of_size_property().base());
333    }
334
335    /// Reads the changes of the object: the base class first, then the
336    /// changed-fields mask and the changed members of this class.
337    pub fn deserialize_changes_core(
338        &self,
339        host: &dyn ServerCompositionRectangleGeometryHooks,
340        reader: &mut BatchStreamReader<'_>,
341        committed_at: Duration,
342    ) {
343        self.base.deserialize_changes_core(host, reader, committed_at);
344        ServerCompositionRectangleGeometryHooks::deserialize_changes_extra(host, reader);
345        let changed = reader.read::<CompositionRectangleGeometryChangedFields>();
346        if changed.contains(CompositionRectangleGeometryChangedFields::OFFSET_ANIMATED) {
347            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
348                panic!("a batch starts an animation of `Offset` without an animation instance");
349            };
350            host.set_animated_value(
351                Self::id_of_offset_property().base(),
352                ExpressionVariant::create(self.offset.get()),
353                committed_at,
354                animation,
355            );
356        } else if changed.contains(CompositionRectangleGeometryChangedFields::OFFSET) {
357            let value = reader.read::<Vector>();
358            self.set_offset(host, value);
359        }
360        if changed.contains(CompositionRectangleGeometryChangedFields::SIZE_ANIMATED) {
361            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
362                panic!("a batch starts an animation of `Size` without an animation instance");
363            };
364            host.set_animated_value(
365                Self::id_of_size_property().base(),
366                ExpressionVariant::create(self.size.get()),
367                committed_at,
368                animation,
369            );
370        } else if changed.contains(CompositionRectangleGeometryChangedFields::SIZE) {
371            let value = reader.read::<Vector>();
372            self.set_size(host, value);
373        }
374        ServerCompositionRectangleGeometryHooks::on_fields_deserialized(host, changed);
375    }
376
377    /// The composition property with the given name, among the properties
378    /// of this class and of its generated bases that have a variant form.
379    pub fn get_composition_property(name: &str) -> Option<&'static CompositionProperty> {
380        if name == "Offset" {
381            return Some(Self::id_of_offset_property().base());
382        }
383        if name == "Size" {
384            return Some(Self::id_of_size_property().base());
385        }
386        ServerCompositionGeometryProps::get_composition_property(name)
387    }
388}