use bitflags::bitflags;
use crate::Vector;
use crate::rendering::composition::animations::AnimationInstanceFactory;
use crate::rendering::composition::animations::ICompositionAnimation;
use crate::rendering::composition::expressions::ExpressionVariant;
use crate::rendering::composition::server::CompositionProperty;
use crate::rendering::composition::server::CompositionPropertyOf;
use crate::rendering::composition::server::ServerPropertyValue;
use crate::rendering::composition::server::props_of;
use crate::rendering::composition::transport::BatchStreamReader;
use crate::rendering::composition::transport::BatchStreamWriter;
use crate::rendering::composition::transport::BatchValue;
use crate::rendering::composition::transport::BatchValueReader;
use std::any::Any;
use std::any::TypeId;
use std::cell::Cell;
use std::sync::OnceLock;
use std::time::Duration;
use super::CompositionClipHooks;
use super::CompositionClipProps;
use super::ServerCompositionClipHooks;
use super::ServerCompositionClipProps;
bitflags! {
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct RectangleClipChangedFields: u16 {
const LEFT = 1;
const LEFT_ANIMATED = 2;
const TOP = 4;
const TOP_ANIMATED = 8;
const RIGHT = 16;
const RIGHT_ANIMATED = 32;
const BOTTOM = 64;
const BOTTOM_ANIMATED = 128;
const TOP_LEFT_RADIUS = 256;
const TOP_LEFT_RADIUS_ANIMATED = 512;
const TOP_RIGHT_RADIUS = 1024;
const TOP_RIGHT_RADIUS_ANIMATED = 2048;
const BOTTOM_LEFT_RADIUS = 4096;
const BOTTOM_LEFT_RADIUS_ANIMATED = 8192;
const BOTTOM_RIGHT_RADIUS = 16384;
const BOTTOM_RIGHT_RADIUS_ANIMATED = 32768;
}
}
impl BatchValue for RectangleClipChangedFields {
#[inline]
fn write_to(&self, out: &mut Vec<u8>) {
self.bits().write_to(out);
}
#[inline]
fn read_from(input: &mut BatchValueReader<'_>) -> Self {
RectangleClipChangedFields::from_bits_retain(u16::read_from(input))
}
}
pub trait RectangleClipHooks: CompositionClipHooks {
fn initialize_defaults_extra(&self) {}
fn validate_left_change(&self, _old_value: f32, _new_value: f32) {}
fn on_left_changed(&self) {}
fn on_left_changing(&self) {}
fn validate_top_change(&self, _old_value: f32, _new_value: f32) {}
fn on_top_changed(&self) {}
fn on_top_changing(&self) {}
fn validate_right_change(&self, _old_value: f32, _new_value: f32) {}
fn on_right_changed(&self) {}
fn on_right_changing(&self) {}
fn validate_bottom_change(&self, _old_value: f32, _new_value: f32) {}
fn on_bottom_changed(&self) {}
fn on_bottom_changing(&self) {}
fn validate_top_left_radius_change(&self, _old_value: Vector, _new_value: Vector) {}
fn on_top_left_radius_changed(&self) {}
fn on_top_left_radius_changing(&self) {}
fn validate_top_right_radius_change(&self, _old_value: Vector, _new_value: Vector) {}
fn on_top_right_radius_changed(&self) {}
fn on_top_right_radius_changing(&self) {}
fn validate_bottom_left_radius_change(&self, _old_value: Vector, _new_value: Vector) {}
fn on_bottom_left_radius_changed(&self) {}
fn on_bottom_left_radius_changing(&self) {}
fn validate_bottom_right_radius_change(&self, _old_value: Vector, _new_value: Vector) {}
fn on_bottom_right_radius_changed(&self) {}
fn on_bottom_right_radius_changing(&self) {}
}
pub struct RectangleClipProps {
base: CompositionClipProps,
changed_fields_of_rectangle_clip: Cell<RectangleClipChangedFields>,
left: Cell<f32>,
top: Cell<f32>,
right: Cell<f32>,
bottom: Cell<f32>,
top_left_radius: Cell<Vector>,
top_right_radius: Cell<Vector>,
bottom_left_radius: Cell<Vector>,
bottom_right_radius: Cell<Vector>,
}
impl Default for RectangleClipProps {
fn default() -> Self {
Self::new()
}
}
impl RectangleClipProps {
pub fn new() -> Self {
Self {
base: CompositionClipProps::new(),
changed_fields_of_rectangle_clip: Cell::new(RectangleClipChangedFields::empty()),
left: Cell::new(Default::default()),
top: Cell::new(Default::default()),
right: Cell::new(Default::default()),
bottom: Cell::new(Default::default()),
top_left_radius: Cell::new(Default::default()),
top_right_radius: Cell::new(Default::default()),
bottom_left_radius: Cell::new(Default::default()),
bottom_right_radius: Cell::new(Default::default()),
}
}
pub fn base(&self) -> &CompositionClipProps {
&self.base
}
pub fn initialize_defaults(&self, host: &dyn RectangleClipHooks) {
self.base.initialize_defaults(host);
self.initialize_own_defaults(host);
}
pub fn initialize_own_defaults(&self, host: &dyn RectangleClipHooks) {
RectangleClipHooks::initialize_defaults_extra(host);
}
pub fn left(&self) -> f32 {
self.left.get()
}
pub fn set_left(&self, host: &dyn RectangleClipHooks, value: f32) {
let mut changed = false;
let old_value = self.left.get();
if old_value.differs(&value) {
RectangleClipHooks::validate_left_change(host, old_value, value);
RectangleClipHooks::on_left_changing(host);
changed = true;
self.left.set(value);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::LEFT);
host.register_for_serialization();
host.pending_animations().remove(ServerRectangleClipProps::id_of_left_property().base());
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() & !RectangleClipChangedFields::LEFT_ANIMATED);
if let Some(animation) = host.implicit_animation("Left") {
if let Some(a) = animation.as_composition_animation() {
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::LEFT_ANIMATED);
host.pending_animations().set(
ServerRectangleClipProps::id_of_left_property().base(),
a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
);
}
host.start_animation_group(&animation, "Left", ExpressionVariant::create(value));
}
}
self.left.set(value);
if changed {
RectangleClipHooks::on_left_changed(host);
}
}
pub fn top(&self) -> f32 {
self.top.get()
}
pub fn set_top(&self, host: &dyn RectangleClipHooks, value: f32) {
let mut changed = false;
let old_value = self.top.get();
if old_value.differs(&value) {
RectangleClipHooks::validate_top_change(host, old_value, value);
RectangleClipHooks::on_top_changing(host);
changed = true;
self.top.set(value);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::TOP);
host.register_for_serialization();
host.pending_animations().remove(ServerRectangleClipProps::id_of_top_property().base());
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() & !RectangleClipChangedFields::TOP_ANIMATED);
if let Some(animation) = host.implicit_animation("Top") {
if let Some(a) = animation.as_composition_animation() {
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::TOP_ANIMATED);
host.pending_animations().set(
ServerRectangleClipProps::id_of_top_property().base(),
a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
);
}
host.start_animation_group(&animation, "Top", ExpressionVariant::create(value));
}
}
self.top.set(value);
if changed {
RectangleClipHooks::on_top_changed(host);
}
}
pub fn right(&self) -> f32 {
self.right.get()
}
pub fn set_right(&self, host: &dyn RectangleClipHooks, value: f32) {
let mut changed = false;
let old_value = self.right.get();
if old_value.differs(&value) {
RectangleClipHooks::validate_right_change(host, old_value, value);
RectangleClipHooks::on_right_changing(host);
changed = true;
self.right.set(value);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::RIGHT);
host.register_for_serialization();
host.pending_animations().remove(ServerRectangleClipProps::id_of_right_property().base());
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() & !RectangleClipChangedFields::RIGHT_ANIMATED);
if let Some(animation) = host.implicit_animation("Right") {
if let Some(a) = animation.as_composition_animation() {
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::RIGHT_ANIMATED);
host.pending_animations().set(
ServerRectangleClipProps::id_of_right_property().base(),
a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
);
}
host.start_animation_group(&animation, "Right", ExpressionVariant::create(value));
}
}
self.right.set(value);
if changed {
RectangleClipHooks::on_right_changed(host);
}
}
pub fn bottom(&self) -> f32 {
self.bottom.get()
}
pub fn set_bottom(&self, host: &dyn RectangleClipHooks, value: f32) {
let mut changed = false;
let old_value = self.bottom.get();
if old_value.differs(&value) {
RectangleClipHooks::validate_bottom_change(host, old_value, value);
RectangleClipHooks::on_bottom_changing(host);
changed = true;
self.bottom.set(value);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::BOTTOM);
host.register_for_serialization();
host.pending_animations().remove(ServerRectangleClipProps::id_of_bottom_property().base());
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() & !RectangleClipChangedFields::BOTTOM_ANIMATED);
if let Some(animation) = host.implicit_animation("Bottom") {
if let Some(a) = animation.as_composition_animation() {
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::BOTTOM_ANIMATED);
host.pending_animations().set(
ServerRectangleClipProps::id_of_bottom_property().base(),
a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
);
}
host.start_animation_group(&animation, "Bottom", ExpressionVariant::create(value));
}
}
self.bottom.set(value);
if changed {
RectangleClipHooks::on_bottom_changed(host);
}
}
pub fn top_left_radius(&self) -> Vector {
self.top_left_radius.get()
}
pub fn set_top_left_radius(&self, host: &dyn RectangleClipHooks, value: Vector) {
let mut changed = false;
let old_value = self.top_left_radius.get();
if old_value.differs(&value) {
RectangleClipHooks::validate_top_left_radius_change(host, old_value, value);
RectangleClipHooks::on_top_left_radius_changing(host);
changed = true;
self.top_left_radius.set(value);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::TOP_LEFT_RADIUS);
host.register_for_serialization();
host.pending_animations().remove(ServerRectangleClipProps::id_of_top_left_radius_property().base());
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() & !RectangleClipChangedFields::TOP_LEFT_RADIUS_ANIMATED);
if let Some(animation) = host.implicit_animation("TopLeftRadius") {
if let Some(a) = animation.as_composition_animation() {
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::TOP_LEFT_RADIUS_ANIMATED);
host.pending_animations().set(
ServerRectangleClipProps::id_of_top_left_radius_property().base(),
a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
);
}
host.start_animation_group(&animation, "TopLeftRadius", ExpressionVariant::create(value));
}
}
self.top_left_radius.set(value);
if changed {
RectangleClipHooks::on_top_left_radius_changed(host);
}
}
pub fn top_right_radius(&self) -> Vector {
self.top_right_radius.get()
}
pub fn set_top_right_radius(&self, host: &dyn RectangleClipHooks, value: Vector) {
let mut changed = false;
let old_value = self.top_right_radius.get();
if old_value.differs(&value) {
RectangleClipHooks::validate_top_right_radius_change(host, old_value, value);
RectangleClipHooks::on_top_right_radius_changing(host);
changed = true;
self.top_right_radius.set(value);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::TOP_RIGHT_RADIUS);
host.register_for_serialization();
host.pending_animations().remove(ServerRectangleClipProps::id_of_top_right_radius_property().base());
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() & !RectangleClipChangedFields::TOP_RIGHT_RADIUS_ANIMATED);
if let Some(animation) = host.implicit_animation("TopRightRadius") {
if let Some(a) = animation.as_composition_animation() {
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::TOP_RIGHT_RADIUS_ANIMATED);
host.pending_animations().set(
ServerRectangleClipProps::id_of_top_right_radius_property().base(),
a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
);
}
host.start_animation_group(&animation, "TopRightRadius", ExpressionVariant::create(value));
}
}
self.top_right_radius.set(value);
if changed {
RectangleClipHooks::on_top_right_radius_changed(host);
}
}
pub fn bottom_left_radius(&self) -> Vector {
self.bottom_left_radius.get()
}
pub fn set_bottom_left_radius(&self, host: &dyn RectangleClipHooks, value: Vector) {
let mut changed = false;
let old_value = self.bottom_left_radius.get();
if old_value.differs(&value) {
RectangleClipHooks::validate_bottom_left_radius_change(host, old_value, value);
RectangleClipHooks::on_bottom_left_radius_changing(host);
changed = true;
self.bottom_left_radius.set(value);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::BOTTOM_LEFT_RADIUS);
host.register_for_serialization();
host.pending_animations().remove(ServerRectangleClipProps::id_of_bottom_left_radius_property().base());
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() & !RectangleClipChangedFields::BOTTOM_LEFT_RADIUS_ANIMATED);
if let Some(animation) = host.implicit_animation("BottomLeftRadius") {
if let Some(a) = animation.as_composition_animation() {
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::BOTTOM_LEFT_RADIUS_ANIMATED);
host.pending_animations().set(
ServerRectangleClipProps::id_of_bottom_left_radius_property().base(),
a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
);
}
host.start_animation_group(&animation, "BottomLeftRadius", ExpressionVariant::create(value));
}
}
self.bottom_left_radius.set(value);
if changed {
RectangleClipHooks::on_bottom_left_radius_changed(host);
}
}
pub fn bottom_right_radius(&self) -> Vector {
self.bottom_right_radius.get()
}
pub fn set_bottom_right_radius(&self, host: &dyn RectangleClipHooks, value: Vector) {
let mut changed = false;
let old_value = self.bottom_right_radius.get();
if old_value.differs(&value) {
RectangleClipHooks::validate_bottom_right_radius_change(host, old_value, value);
RectangleClipHooks::on_bottom_right_radius_changing(host);
changed = true;
self.bottom_right_radius.set(value);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::BOTTOM_RIGHT_RADIUS);
host.register_for_serialization();
host.pending_animations().remove(ServerRectangleClipProps::id_of_bottom_right_radius_property().base());
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() & !RectangleClipChangedFields::BOTTOM_RIGHT_RADIUS_ANIMATED);
if let Some(animation) = host.implicit_animation("BottomRightRadius") {
if let Some(a) = animation.as_composition_animation() {
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::BOTTOM_RIGHT_RADIUS_ANIMATED);
host.pending_animations().set(
ServerRectangleClipProps::id_of_bottom_right_radius_property().base(),
a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
);
}
host.start_animation_group(&animation, "BottomRightRadius", ExpressionVariant::create(value));
}
}
self.bottom_right_radius.set(value);
if changed {
RectangleClipHooks::on_bottom_right_radius_changed(host);
}
}
pub fn start_animation(
&self,
host: &dyn RectangleClipHooks,
property_name: &str,
animation: &dyn ICompositionAnimation,
final_value: Option<ExpressionVariant>,
) -> bool {
if property_name == "Left" {
let server = animation.create_instance(host.server(), final_value);
host.pending_animations().set(ServerRectangleClipProps::id_of_left_property().base(), server);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::LEFT_ANIMATED);
host.register_for_serialization();
return true;
}
if property_name == "Top" {
let server = animation.create_instance(host.server(), final_value);
host.pending_animations().set(ServerRectangleClipProps::id_of_top_property().base(), server);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::TOP_ANIMATED);
host.register_for_serialization();
return true;
}
if property_name == "Right" {
let server = animation.create_instance(host.server(), final_value);
host.pending_animations().set(ServerRectangleClipProps::id_of_right_property().base(), server);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::RIGHT_ANIMATED);
host.register_for_serialization();
return true;
}
if property_name == "Bottom" {
let server = animation.create_instance(host.server(), final_value);
host.pending_animations().set(ServerRectangleClipProps::id_of_bottom_property().base(), server);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::BOTTOM_ANIMATED);
host.register_for_serialization();
return true;
}
if property_name == "TopLeftRadius" {
let server = animation.create_instance(host.server(), final_value);
host.pending_animations().set(ServerRectangleClipProps::id_of_top_left_radius_property().base(), server);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::TOP_LEFT_RADIUS_ANIMATED);
host.register_for_serialization();
return true;
}
if property_name == "TopRightRadius" {
let server = animation.create_instance(host.server(), final_value);
host.pending_animations().set(ServerRectangleClipProps::id_of_top_right_radius_property().base(), server);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::TOP_RIGHT_RADIUS_ANIMATED);
host.register_for_serialization();
return true;
}
if property_name == "BottomLeftRadius" {
let server = animation.create_instance(host.server(), final_value);
host.pending_animations().set(ServerRectangleClipProps::id_of_bottom_left_radius_property().base(), server);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::BOTTOM_LEFT_RADIUS_ANIMATED);
host.register_for_serialization();
return true;
}
if property_name == "BottomRightRadius" {
let server = animation.create_instance(host.server(), final_value);
host.pending_animations().set(ServerRectangleClipProps::id_of_bottom_right_radius_property().base(), server);
self.changed_fields_of_rectangle_clip.set(self.changed_fields_of_rectangle_clip.get() | RectangleClipChangedFields::BOTTOM_RIGHT_RADIUS_ANIMATED);
host.register_for_serialization();
return true;
}
self.base.start_animation(host, property_name, animation, final_value)
}
pub fn serialize_changes_core(&self, host: &dyn RectangleClipHooks, writer: &mut BatchStreamWriter<'_>) {
self.base.serialize_changes_core(host, writer);
let changed = self.changed_fields_of_rectangle_clip.get();
writer.write(changed);
if changed.contains(RectangleClipChangedFields::LEFT_ANIMATED) {
writer.write_value(host.pending_animations().get_and_remove(ServerRectangleClipProps::id_of_left_property().base()));
} else if changed.contains(RectangleClipChangedFields::LEFT) {
writer.write(self.left.get());
}
if changed.contains(RectangleClipChangedFields::TOP_ANIMATED) {
writer.write_value(host.pending_animations().get_and_remove(ServerRectangleClipProps::id_of_top_property().base()));
} else if changed.contains(RectangleClipChangedFields::TOP) {
writer.write(self.top.get());
}
if changed.contains(RectangleClipChangedFields::RIGHT_ANIMATED) {
writer.write_value(host.pending_animations().get_and_remove(ServerRectangleClipProps::id_of_right_property().base()));
} else if changed.contains(RectangleClipChangedFields::RIGHT) {
writer.write(self.right.get());
}
if changed.contains(RectangleClipChangedFields::BOTTOM_ANIMATED) {
writer.write_value(host.pending_animations().get_and_remove(ServerRectangleClipProps::id_of_bottom_property().base()));
} else if changed.contains(RectangleClipChangedFields::BOTTOM) {
writer.write(self.bottom.get());
}
if changed.contains(RectangleClipChangedFields::TOP_LEFT_RADIUS_ANIMATED) {
writer.write_value(host.pending_animations().get_and_remove(ServerRectangleClipProps::id_of_top_left_radius_property().base()));
} else if changed.contains(RectangleClipChangedFields::TOP_LEFT_RADIUS) {
writer.write(self.top_left_radius.get());
}
if changed.contains(RectangleClipChangedFields::TOP_RIGHT_RADIUS_ANIMATED) {
writer.write_value(host.pending_animations().get_and_remove(ServerRectangleClipProps::id_of_top_right_radius_property().base()));
} else if changed.contains(RectangleClipChangedFields::TOP_RIGHT_RADIUS) {
writer.write(self.top_right_radius.get());
}
if changed.contains(RectangleClipChangedFields::BOTTOM_LEFT_RADIUS_ANIMATED) {
writer.write_value(host.pending_animations().get_and_remove(ServerRectangleClipProps::id_of_bottom_left_radius_property().base()));
} else if changed.contains(RectangleClipChangedFields::BOTTOM_LEFT_RADIUS) {
writer.write(self.bottom_left_radius.get());
}
if changed.contains(RectangleClipChangedFields::BOTTOM_RIGHT_RADIUS_ANIMATED) {
writer.write_value(host.pending_animations().get_and_remove(ServerRectangleClipProps::id_of_bottom_right_radius_property().base()));
} else if changed.contains(RectangleClipChangedFields::BOTTOM_RIGHT_RADIUS) {
writer.write(self.bottom_right_radius.get());
}
self.changed_fields_of_rectangle_clip.set(RectangleClipChangedFields::empty());
}
}
pub trait ServerRectangleClipHooks: ServerCompositionClipHooks {
fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
fn on_fields_deserialized(&self, _changed: RectangleClipChangedFields) {}
}
pub struct ServerRectangleClipProps {
base: ServerCompositionClipProps,
left: Cell<f32>,
top: Cell<f32>,
right: Cell<f32>,
bottom: Cell<f32>,
top_left_radius: Cell<Vector>,
top_right_radius: Cell<Vector>,
bottom_left_radius: Cell<Vector>,
bottom_right_radius: Cell<Vector>,
}
impl Default for ServerRectangleClipProps {
fn default() -> Self {
Self::new()
}
}
impl ServerRectangleClipProps {
pub fn new() -> Self {
Self {
base: ServerCompositionClipProps::new(),
left: Cell::new(Default::default()),
top: Cell::new(Default::default()),
right: Cell::new(Default::default()),
bottom: Cell::new(Default::default()),
top_left_radius: Cell::new(Default::default()),
top_right_radius: Cell::new(Default::default()),
bottom_left_radius: Cell::new(Default::default()),
bottom_right_radius: Cell::new(Default::default()),
}
}
pub fn base(&self) -> &ServerCompositionClipProps {
&self.base
}
pub fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
if type_id == TypeId::of::<Self>() {
return Some(self);
}
self.base.find_props(type_id)
}
pub fn id_of_left_property() -> &'static CompositionPropertyOf<f32> {
static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerRectangleClipProps, f32>(
"Left",
"ServerRectangleClip",
|obj| props_of::<ServerRectangleClipProps>(obj).left.get(),
|obj, v| props_of::<ServerRectangleClipProps>(obj).left.set(v),
Some(|obj| ExpressionVariant::create(props_of::<ServerRectangleClipProps>(obj).left.get())),
Some(|obj, v: ExpressionVariant| props_of::<ServerRectangleClipProps>(obj).left.set(v.cast_or_default::<f32>())),
)
})
}
pub fn left(&self) -> f32 {
self.left.get()
}
pub fn set_left(&self, host: &dyn ServerRectangleClipHooks, value: f32) {
self.left.set(value);
host.remove_animation_for_property(Self::id_of_left_property().base());
}
pub fn id_of_top_property() -> &'static CompositionPropertyOf<f32> {
static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerRectangleClipProps, f32>(
"Top",
"ServerRectangleClip",
|obj| props_of::<ServerRectangleClipProps>(obj).top.get(),
|obj, v| props_of::<ServerRectangleClipProps>(obj).top.set(v),
Some(|obj| ExpressionVariant::create(props_of::<ServerRectangleClipProps>(obj).top.get())),
Some(|obj, v: ExpressionVariant| props_of::<ServerRectangleClipProps>(obj).top.set(v.cast_or_default::<f32>())),
)
})
}
pub fn top(&self) -> f32 {
self.top.get()
}
pub fn set_top(&self, host: &dyn ServerRectangleClipHooks, value: f32) {
self.top.set(value);
host.remove_animation_for_property(Self::id_of_top_property().base());
}
pub fn id_of_right_property() -> &'static CompositionPropertyOf<f32> {
static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerRectangleClipProps, f32>(
"Right",
"ServerRectangleClip",
|obj| props_of::<ServerRectangleClipProps>(obj).right.get(),
|obj, v| props_of::<ServerRectangleClipProps>(obj).right.set(v),
Some(|obj| ExpressionVariant::create(props_of::<ServerRectangleClipProps>(obj).right.get())),
Some(|obj, v: ExpressionVariant| props_of::<ServerRectangleClipProps>(obj).right.set(v.cast_or_default::<f32>())),
)
})
}
pub fn right(&self) -> f32 {
self.right.get()
}
pub fn set_right(&self, host: &dyn ServerRectangleClipHooks, value: f32) {
self.right.set(value);
host.remove_animation_for_property(Self::id_of_right_property().base());
}
pub fn id_of_bottom_property() -> &'static CompositionPropertyOf<f32> {
static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerRectangleClipProps, f32>(
"Bottom",
"ServerRectangleClip",
|obj| props_of::<ServerRectangleClipProps>(obj).bottom.get(),
|obj, v| props_of::<ServerRectangleClipProps>(obj).bottom.set(v),
Some(|obj| ExpressionVariant::create(props_of::<ServerRectangleClipProps>(obj).bottom.get())),
Some(|obj, v: ExpressionVariant| props_of::<ServerRectangleClipProps>(obj).bottom.set(v.cast_or_default::<f32>())),
)
})
}
pub fn bottom(&self) -> f32 {
self.bottom.get()
}
pub fn set_bottom(&self, host: &dyn ServerRectangleClipHooks, value: f32) {
self.bottom.set(value);
host.remove_animation_for_property(Self::id_of_bottom_property().base());
}
pub fn id_of_top_left_radius_property() -> &'static CompositionPropertyOf<Vector> {
static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerRectangleClipProps, Vector>(
"TopLeftRadius",
"ServerRectangleClip",
|obj| props_of::<ServerRectangleClipProps>(obj).top_left_radius.get(),
|obj, v| props_of::<ServerRectangleClipProps>(obj).top_left_radius.set(v),
Some(|obj| ExpressionVariant::create(props_of::<ServerRectangleClipProps>(obj).top_left_radius.get())),
Some(|obj, v: ExpressionVariant| props_of::<ServerRectangleClipProps>(obj).top_left_radius.set(v.cast_or_default::<Vector>())),
)
})
}
pub fn top_left_radius(&self) -> Vector {
self.top_left_radius.get()
}
pub fn set_top_left_radius(&self, host: &dyn ServerRectangleClipHooks, value: Vector) {
self.top_left_radius.set(value);
host.remove_animation_for_property(Self::id_of_top_left_radius_property().base());
}
pub fn id_of_top_right_radius_property() -> &'static CompositionPropertyOf<Vector> {
static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerRectangleClipProps, Vector>(
"TopRightRadius",
"ServerRectangleClip",
|obj| props_of::<ServerRectangleClipProps>(obj).top_right_radius.get(),
|obj, v| props_of::<ServerRectangleClipProps>(obj).top_right_radius.set(v),
Some(|obj| ExpressionVariant::create(props_of::<ServerRectangleClipProps>(obj).top_right_radius.get())),
Some(|obj, v: ExpressionVariant| props_of::<ServerRectangleClipProps>(obj).top_right_radius.set(v.cast_or_default::<Vector>())),
)
})
}
pub fn top_right_radius(&self) -> Vector {
self.top_right_radius.get()
}
pub fn set_top_right_radius(&self, host: &dyn ServerRectangleClipHooks, value: Vector) {
self.top_right_radius.set(value);
host.remove_animation_for_property(Self::id_of_top_right_radius_property().base());
}
pub fn id_of_bottom_left_radius_property() -> &'static CompositionPropertyOf<Vector> {
static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerRectangleClipProps, Vector>(
"BottomLeftRadius",
"ServerRectangleClip",
|obj| props_of::<ServerRectangleClipProps>(obj).bottom_left_radius.get(),
|obj, v| props_of::<ServerRectangleClipProps>(obj).bottom_left_radius.set(v),
Some(|obj| ExpressionVariant::create(props_of::<ServerRectangleClipProps>(obj).bottom_left_radius.get())),
Some(|obj, v: ExpressionVariant| props_of::<ServerRectangleClipProps>(obj).bottom_left_radius.set(v.cast_or_default::<Vector>())),
)
})
}
pub fn bottom_left_radius(&self) -> Vector {
self.bottom_left_radius.get()
}
pub fn set_bottom_left_radius(&self, host: &dyn ServerRectangleClipHooks, value: Vector) {
self.bottom_left_radius.set(value);
host.remove_animation_for_property(Self::id_of_bottom_left_radius_property().base());
}
pub fn id_of_bottom_right_radius_property() -> &'static CompositionPropertyOf<Vector> {
static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerRectangleClipProps, Vector>(
"BottomRightRadius",
"ServerRectangleClip",
|obj| props_of::<ServerRectangleClipProps>(obj).bottom_right_radius.get(),
|obj, v| props_of::<ServerRectangleClipProps>(obj).bottom_right_radius.set(v),
Some(|obj| ExpressionVariant::create(props_of::<ServerRectangleClipProps>(obj).bottom_right_radius.get())),
Some(|obj, v: ExpressionVariant| props_of::<ServerRectangleClipProps>(obj).bottom_right_radius.set(v.cast_or_default::<Vector>())),
)
})
}
pub fn bottom_right_radius(&self) -> Vector {
self.bottom_right_radius.get()
}
pub fn set_bottom_right_radius(&self, host: &dyn ServerRectangleClipHooks, value: Vector) {
self.bottom_right_radius.set(value);
host.remove_animation_for_property(Self::id_of_bottom_right_radius_property().base());
}
pub fn deserialize_changes_core(
&self,
host: &dyn ServerRectangleClipHooks,
reader: &mut BatchStreamReader<'_>,
committed_at: Duration,
) {
self.base.deserialize_changes_core(host, reader, committed_at);
ServerRectangleClipHooks::deserialize_changes_extra(host, reader);
let changed = reader.read::<RectangleClipChangedFields>();
if changed.contains(RectangleClipChangedFields::LEFT_ANIMATED) {
let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
panic!("a batch starts an animation of `Left` without an animation instance");
};
host.set_animated_value(
Self::id_of_left_property().base(),
ExpressionVariant::create(self.left.get()),
committed_at,
animation,
);
} else if changed.contains(RectangleClipChangedFields::LEFT) {
let value = reader.read::<f32>();
self.set_left(host, value);
}
if changed.contains(RectangleClipChangedFields::TOP_ANIMATED) {
let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
panic!("a batch starts an animation of `Top` without an animation instance");
};
host.set_animated_value(
Self::id_of_top_property().base(),
ExpressionVariant::create(self.top.get()),
committed_at,
animation,
);
} else if changed.contains(RectangleClipChangedFields::TOP) {
let value = reader.read::<f32>();
self.set_top(host, value);
}
if changed.contains(RectangleClipChangedFields::RIGHT_ANIMATED) {
let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
panic!("a batch starts an animation of `Right` without an animation instance");
};
host.set_animated_value(
Self::id_of_right_property().base(),
ExpressionVariant::create(self.right.get()),
committed_at,
animation,
);
} else if changed.contains(RectangleClipChangedFields::RIGHT) {
let value = reader.read::<f32>();
self.set_right(host, value);
}
if changed.contains(RectangleClipChangedFields::BOTTOM_ANIMATED) {
let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
panic!("a batch starts an animation of `Bottom` without an animation instance");
};
host.set_animated_value(
Self::id_of_bottom_property().base(),
ExpressionVariant::create(self.bottom.get()),
committed_at,
animation,
);
} else if changed.contains(RectangleClipChangedFields::BOTTOM) {
let value = reader.read::<f32>();
self.set_bottom(host, value);
}
if changed.contains(RectangleClipChangedFields::TOP_LEFT_RADIUS_ANIMATED) {
let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
panic!("a batch starts an animation of `TopLeftRadius` without an animation instance");
};
host.set_animated_value(
Self::id_of_top_left_radius_property().base(),
ExpressionVariant::create(self.top_left_radius.get()),
committed_at,
animation,
);
} else if changed.contains(RectangleClipChangedFields::TOP_LEFT_RADIUS) {
let value = reader.read::<Vector>();
self.set_top_left_radius(host, value);
}
if changed.contains(RectangleClipChangedFields::TOP_RIGHT_RADIUS_ANIMATED) {
let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
panic!("a batch starts an animation of `TopRightRadius` without an animation instance");
};
host.set_animated_value(
Self::id_of_top_right_radius_property().base(),
ExpressionVariant::create(self.top_right_radius.get()),
committed_at,
animation,
);
} else if changed.contains(RectangleClipChangedFields::TOP_RIGHT_RADIUS) {
let value = reader.read::<Vector>();
self.set_top_right_radius(host, value);
}
if changed.contains(RectangleClipChangedFields::BOTTOM_LEFT_RADIUS_ANIMATED) {
let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
panic!("a batch starts an animation of `BottomLeftRadius` without an animation instance");
};
host.set_animated_value(
Self::id_of_bottom_left_radius_property().base(),
ExpressionVariant::create(self.bottom_left_radius.get()),
committed_at,
animation,
);
} else if changed.contains(RectangleClipChangedFields::BOTTOM_LEFT_RADIUS) {
let value = reader.read::<Vector>();
self.set_bottom_left_radius(host, value);
}
if changed.contains(RectangleClipChangedFields::BOTTOM_RIGHT_RADIUS_ANIMATED) {
let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
panic!("a batch starts an animation of `BottomRightRadius` without an animation instance");
};
host.set_animated_value(
Self::id_of_bottom_right_radius_property().base(),
ExpressionVariant::create(self.bottom_right_radius.get()),
committed_at,
animation,
);
} else if changed.contains(RectangleClipChangedFields::BOTTOM_RIGHT_RADIUS) {
let value = reader.read::<Vector>();
self.set_bottom_right_radius(host, value);
}
ServerRectangleClipHooks::on_fields_deserialized(host, changed);
}
pub fn get_composition_property(name: &str) -> Option<&'static CompositionProperty> {
if name == "Left" {
return Some(Self::id_of_left_property().base());
}
if name == "Top" {
return Some(Self::id_of_top_property().base());
}
if name == "Right" {
return Some(Self::id_of_right_property().base());
}
if name == "Bottom" {
return Some(Self::id_of_bottom_property().base());
}
if name == "TopLeftRadius" {
return Some(Self::id_of_top_left_radius_property().base());
}
if name == "TopRightRadius" {
return Some(Self::id_of_top_right_radius_property().base());
}
if name == "BottomLeftRadius" {
return Some(Self::id_of_bottom_left_radius_property().base());
}
if name == "BottomRightRadius" {
return Some(Self::id_of_bottom_right_radius_property().base());
}
ServerCompositionClipProps::get_composition_property(name)
}
}