use bitflags::bitflags;
use crate::RelativeRect;
use crate::media::AlignmentX;
use crate::media::AlignmentY;
use crate::media::Stretch;
use crate::media::TileMode;
use crate::rendering::composition::server::CompositionProperty;
use crate::rendering::composition::server::CompositionPropertyOf;
use crate::rendering::composition::server::ServerPropertyValue;
use crate::rendering::composition::server::ServerValueChange;
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::ServerCompositionBrushHooks;
use super::ServerCompositionBrushProps;
bitflags! {
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct CompositionTileBrushChangedFields: u8 {
const ALIGNMENT_X = 1;
const ALIGNMENT_Y = 2;
const DESTINATION_RECT = 4;
const SOURCE_RECT = 8;
const STRETCH = 16;
const TILE_MODE = 32;
}
}
impl BatchValue for CompositionTileBrushChangedFields {
#[inline]
fn write_to(&self, out: &mut Vec<u8>) {
self.bits().write_to(out);
}
#[inline]
fn read_from(input: &mut BatchValueReader<'_>) -> Self {
CompositionTileBrushChangedFields::from_bits_retain(u8::read_from(input))
}
}
pub trait ServerCompositionTileBrushHooks: ServerCompositionBrushHooks {
fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
fn on_fields_deserialized(&self, _changed: CompositionTileBrushChangedFields) {}
fn on_alignment_x_changed(&self) {}
fn on_alignment_x_changing(&self) {}
fn on_alignment_y_changed(&self) {}
fn on_alignment_y_changing(&self) {}
fn on_destination_rect_changed(&self) {}
fn on_destination_rect_changing(&self) {}
fn on_source_rect_changed(&self) {}
fn on_source_rect_changing(&self) {}
fn on_stretch_changed(&self) {}
fn on_stretch_changing(&self) {}
fn on_tile_mode_changed(&self) {}
fn on_tile_mode_changing(&self) {}
}
pub struct ServerCompositionTileBrushProps {
base: ServerCompositionBrushProps,
alignment_x: Cell<AlignmentX>,
alignment_y: Cell<AlignmentY>,
destination_rect: Cell<RelativeRect>,
source_rect: Cell<RelativeRect>,
stretch: Cell<Stretch>,
tile_mode: Cell<TileMode>,
}
impl Default for ServerCompositionTileBrushProps {
fn default() -> Self {
Self::new()
}
}
impl ServerCompositionTileBrushProps {
pub fn new() -> Self {
Self {
base: ServerCompositionBrushProps::new(),
alignment_x: Cell::new(Default::default()),
alignment_y: Cell::new(Default::default()),
destination_rect: Cell::new(Default::default()),
source_rect: Cell::new(Default::default()),
stretch: Cell::new(Default::default()),
tile_mode: Cell::new(Default::default()),
}
}
pub fn base(&self) -> &ServerCompositionBrushProps {
&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_alignment_x_property() -> &'static CompositionPropertyOf<AlignmentX> {
static PROPERTY: OnceLock<CompositionPropertyOf<AlignmentX>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerCompositionTileBrushProps, AlignmentX>(
"AlignmentX",
"ServerCompositionTileBrush",
|obj| props_of::<ServerCompositionTileBrushProps>(obj).alignment_x.get(),
|obj, v| props_of::<ServerCompositionTileBrushProps>(obj).alignment_x.set(v),
None,
None,
)
})
}
pub fn alignment_x(&self) -> AlignmentX {
self.alignment_x.get()
}
pub fn set_alignment_x(&self, host: &dyn ServerCompositionTileBrushHooks, value: AlignmentX) {
let old_value = self.alignment_x.get();
let mut changed = false;
if old_value.differs(&value) {
ServerCompositionTileBrushHooks::on_alignment_x_changing(host);
changed = true;
}
host.set_value(
Self::id_of_alignment_x_property().base(),
ServerValueChange {
equal: old_value.default_equals(&value),
old_resource: None,
new_resource: None,
assign: &mut || self.alignment_x.set(value),
},
);
if changed {
ServerCompositionTileBrushHooks::on_alignment_x_changed(host);
}
}
pub fn id_of_alignment_y_property() -> &'static CompositionPropertyOf<AlignmentY> {
static PROPERTY: OnceLock<CompositionPropertyOf<AlignmentY>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerCompositionTileBrushProps, AlignmentY>(
"AlignmentY",
"ServerCompositionTileBrush",
|obj| props_of::<ServerCompositionTileBrushProps>(obj).alignment_y.get(),
|obj, v| props_of::<ServerCompositionTileBrushProps>(obj).alignment_y.set(v),
None,
None,
)
})
}
pub fn alignment_y(&self) -> AlignmentY {
self.alignment_y.get()
}
pub fn set_alignment_y(&self, host: &dyn ServerCompositionTileBrushHooks, value: AlignmentY) {
let old_value = self.alignment_y.get();
let mut changed = false;
if old_value.differs(&value) {
ServerCompositionTileBrushHooks::on_alignment_y_changing(host);
changed = true;
}
host.set_value(
Self::id_of_alignment_y_property().base(),
ServerValueChange {
equal: old_value.default_equals(&value),
old_resource: None,
new_resource: None,
assign: &mut || self.alignment_y.set(value),
},
);
if changed {
ServerCompositionTileBrushHooks::on_alignment_y_changed(host);
}
}
pub fn id_of_destination_rect_property() -> &'static CompositionPropertyOf<RelativeRect> {
static PROPERTY: OnceLock<CompositionPropertyOf<RelativeRect>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerCompositionTileBrushProps, RelativeRect>(
"DestinationRect",
"ServerCompositionTileBrush",
|obj| props_of::<ServerCompositionTileBrushProps>(obj).destination_rect.get(),
|obj, v| props_of::<ServerCompositionTileBrushProps>(obj).destination_rect.set(v),
None,
None,
)
})
}
pub fn destination_rect(&self) -> RelativeRect {
self.destination_rect.get()
}
pub fn set_destination_rect(&self, host: &dyn ServerCompositionTileBrushHooks, value: RelativeRect) {
let old_value = self.destination_rect.get();
let mut changed = false;
if old_value.differs(&value) {
ServerCompositionTileBrushHooks::on_destination_rect_changing(host);
changed = true;
}
host.set_value(
Self::id_of_destination_rect_property().base(),
ServerValueChange {
equal: old_value.default_equals(&value),
old_resource: None,
new_resource: None,
assign: &mut || self.destination_rect.set(value),
},
);
if changed {
ServerCompositionTileBrushHooks::on_destination_rect_changed(host);
}
}
pub fn id_of_source_rect_property() -> &'static CompositionPropertyOf<RelativeRect> {
static PROPERTY: OnceLock<CompositionPropertyOf<RelativeRect>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerCompositionTileBrushProps, RelativeRect>(
"SourceRect",
"ServerCompositionTileBrush",
|obj| props_of::<ServerCompositionTileBrushProps>(obj).source_rect.get(),
|obj, v| props_of::<ServerCompositionTileBrushProps>(obj).source_rect.set(v),
None,
None,
)
})
}
pub fn source_rect(&self) -> RelativeRect {
self.source_rect.get()
}
pub fn set_source_rect(&self, host: &dyn ServerCompositionTileBrushHooks, value: RelativeRect) {
let old_value = self.source_rect.get();
let mut changed = false;
if old_value.differs(&value) {
ServerCompositionTileBrushHooks::on_source_rect_changing(host);
changed = true;
}
host.set_value(
Self::id_of_source_rect_property().base(),
ServerValueChange {
equal: old_value.default_equals(&value),
old_resource: None,
new_resource: None,
assign: &mut || self.source_rect.set(value),
},
);
if changed {
ServerCompositionTileBrushHooks::on_source_rect_changed(host);
}
}
pub fn id_of_stretch_property() -> &'static CompositionPropertyOf<Stretch> {
static PROPERTY: OnceLock<CompositionPropertyOf<Stretch>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerCompositionTileBrushProps, Stretch>(
"Stretch",
"ServerCompositionTileBrush",
|obj| props_of::<ServerCompositionTileBrushProps>(obj).stretch.get(),
|obj, v| props_of::<ServerCompositionTileBrushProps>(obj).stretch.set(v),
None,
None,
)
})
}
pub fn stretch(&self) -> Stretch {
self.stretch.get()
}
pub fn set_stretch(&self, host: &dyn ServerCompositionTileBrushHooks, value: Stretch) {
let old_value = self.stretch.get();
let mut changed = false;
if old_value.differs(&value) {
ServerCompositionTileBrushHooks::on_stretch_changing(host);
changed = true;
}
host.set_value(
Self::id_of_stretch_property().base(),
ServerValueChange {
equal: old_value.default_equals(&value),
old_resource: None,
new_resource: None,
assign: &mut || self.stretch.set(value),
},
);
if changed {
ServerCompositionTileBrushHooks::on_stretch_changed(host);
}
}
pub fn id_of_tile_mode_property() -> &'static CompositionPropertyOf<TileMode> {
static PROPERTY: OnceLock<CompositionPropertyOf<TileMode>> = OnceLock::new();
PROPERTY.get_or_init(|| {
CompositionProperty::register::<ServerCompositionTileBrushProps, TileMode>(
"TileMode",
"ServerCompositionTileBrush",
|obj| props_of::<ServerCompositionTileBrushProps>(obj).tile_mode.get(),
|obj, v| props_of::<ServerCompositionTileBrushProps>(obj).tile_mode.set(v),
None,
None,
)
})
}
pub fn tile_mode(&self) -> TileMode {
self.tile_mode.get()
}
pub fn set_tile_mode(&self, host: &dyn ServerCompositionTileBrushHooks, value: TileMode) {
let old_value = self.tile_mode.get();
let mut changed = false;
if old_value.differs(&value) {
ServerCompositionTileBrushHooks::on_tile_mode_changing(host);
changed = true;
}
host.set_value(
Self::id_of_tile_mode_property().base(),
ServerValueChange {
equal: old_value.default_equals(&value),
old_resource: None,
new_resource: None,
assign: &mut || self.tile_mode.set(value),
},
);
if changed {
ServerCompositionTileBrushHooks::on_tile_mode_changed(host);
}
}
pub fn deserialize_changes_core(
&self,
host: &dyn ServerCompositionTileBrushHooks,
reader: &mut BatchStreamReader<'_>,
committed_at: Duration,
) {
self.base.deserialize_changes_core(host, reader, committed_at);
ServerCompositionTileBrushHooks::deserialize_changes_extra(host, reader);
let changed = reader.read::<CompositionTileBrushChangedFields>();
if changed.contains(CompositionTileBrushChangedFields::ALIGNMENT_X) {
let value = reader.read::<AlignmentX>();
self.set_alignment_x(host, value);
}
if changed.contains(CompositionTileBrushChangedFields::ALIGNMENT_Y) {
let value = reader.read::<AlignmentY>();
self.set_alignment_y(host, value);
}
if changed.contains(CompositionTileBrushChangedFields::DESTINATION_RECT) {
let value = reader.read::<RelativeRect>();
self.set_destination_rect(host, value);
}
if changed.contains(CompositionTileBrushChangedFields::SOURCE_RECT) {
let value = reader.read::<RelativeRect>();
self.set_source_rect(host, value);
}
if changed.contains(CompositionTileBrushChangedFields::STRETCH) {
let value = reader.read::<Stretch>();
self.set_stretch(host, value);
}
if changed.contains(CompositionTileBrushChangedFields::TILE_MODE) {
let value = reader.read::<TileMode>();
self.set_tile_mode(host, value);
}
ServerCompositionTileBrushHooks::on_fields_deserialized(host, changed);
}
pub fn serialize_all_changes(
writer: &mut BatchStreamWriter<'_>,
alignment_x: AlignmentX,
alignment_y: AlignmentY,
destination_rect: RelativeRect,
source_rect: RelativeRect,
stretch: Stretch,
tile_mode: TileMode,
) {
writer.write(CompositionTileBrushChangedFields::ALIGNMENT_X | CompositionTileBrushChangedFields::ALIGNMENT_Y | CompositionTileBrushChangedFields::DESTINATION_RECT | CompositionTileBrushChangedFields::SOURCE_RECT | CompositionTileBrushChangedFields::STRETCH | CompositionTileBrushChangedFields::TILE_MODE);
writer.write(alignment_x);
writer.write(alignment_y);
writer.write(destination_rect);
writer.write(source_rect);
writer.write(stretch);
writer.write(tile_mode);
}
}