ferroui_base/rendering/composition/generated/
composition_rectangle_geometry.rs1use 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 #[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
53pub 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
67pub 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 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 pub fn base(&self) -> &CompositionGeometryProps {
96 &self.base
97 }
98
99 pub fn initialize_defaults(&self, host: &dyn CompositionRectangleGeometryHooks) {
102 self.base.initialize_defaults(host);
103 self.initialize_own_defaults(host);
104 }
105
106 pub fn initialize_own_defaults(&self, host: &dyn CompositionRectangleGeometryHooks) {
108 CompositionRectangleGeometryHooks::initialize_defaults_extra(host);
109 }
110
111 pub fn offset(&self) -> Vector {
113 self.offset.get()
114 }
115
116 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 self.offset.set(value);
126 self.changed_fields_of_composition_rectangle_geometry.set(self.changed_fields_of_composition_rectangle_geometry.get() | CompositionRectangleGeometryChangedFields::OFFSET);
128 host.register_for_serialization();
129 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 if let Some(animation) = host.implicit_animation("Offset") {
134 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 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 pub fn size(&self) -> Vector {
154 self.size.get()
155 }
156
157 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 self.size.set(value);
167 self.changed_fields_of_composition_rectangle_geometry.set(self.changed_fields_of_composition_rectangle_geometry.get() | CompositionRectangleGeometryChangedFields::SIZE);
169 host.register_for_serialization();
170 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 if let Some(animation) = host.implicit_animation("Size") {
175 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 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 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 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
240pub trait ServerCompositionRectangleGeometryHooks: ServerCompositionGeometryHooks {
243 fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
244 fn on_fields_deserialized(&self, _changed: CompositionRectangleGeometryChangedFields) {}
245}
246
247pub 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 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 pub fn base(&self) -> &ServerCompositionGeometryProps {
273 &self.base
274 }
275
276 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 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 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 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 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 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 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}