use super::{
impl_simple_server_render_resource, IServerObject, IServerRenderResource, ServerCompositor, SimpleServerRenderResource,
};
use crate::media::immutable::ImmutableGradientStop;
use crate::media::{
AlignmentX, AlignmentY, Color, GradientSpreadMethod, IBrush, IConicGradientBrush, IGradientBrush, IGradientStop,
ILinearGradientBrush, IRadialGradientBrush, ISolidColorBrush, ITileBrush, ITransform, Stretch, TileMode,
};
use crate::rendering::composition::generated::{
ServerCompositionSimpleBrushHooks, ServerCompositionSimpleBrushProps, ServerCompositionSimpleConicGradientBrushHooks,
ServerCompositionSimpleConicGradientBrushProps, ServerCompositionSimpleLinearGradientBrushHooks,
ServerCompositionSimpleLinearGradientBrushProps, ServerCompositionSimpleRadialGradientBrushHooks,
ServerCompositionSimpleRadialGradientBrushProps, ServerCompositionSimpleSolidColorBrushHooks,
ServerCompositionSimpleSolidColorBrushProps, ServerCompositionSimpleTileBrushHooks,
ServerCompositionSimpleTileBrushProps,
};
use crate::rendering::composition::transport::BatchStreamReader;
use crate::{RelativePoint, RelativeRect, RelativeScalar};
use std::any::{Any, TypeId};
use std::cell::{Cell, RefCell};
use std::rc::{Rc, Weak};
use std::time::Duration;
pub struct ServerCompositionSimpleGradientBrush {
brush: ServerCompositionSimpleBrushProps,
gradient_stops: RefCell<Vec<Rc<dyn IGradientStop>>>,
spread_method: Cell<GradientSpreadMethod>,
}
impl Default for ServerCompositionSimpleGradientBrush {
fn default() -> Self {
Self::new()
}
}
impl ServerCompositionSimpleGradientBrush {
pub fn new() -> Self {
Self {
brush: ServerCompositionSimpleBrushProps::new(),
gradient_stops: RefCell::new(Vec::new()),
spread_method: Cell::new(GradientSpreadMethod::default()),
}
}
pub fn brush(&self) -> &ServerCompositionSimpleBrushProps {
&self.brush
}
pub fn gradient_stops(&self) -> Vec<Rc<dyn IGradientStop>> {
self.gradient_stops.borrow().clone()
}
pub fn spread_method(&self) -> GradientSpreadMethod {
self.spread_method.get()
}
pub fn deserialize_changes_core(
&self,
host: &dyn ServerCompositionSimpleBrushHooks,
reader: &mut BatchStreamReader<'_>,
committed_at: Duration,
) {
self.brush.deserialize_changes_core(host, reader, committed_at);
self.spread_method.set(reader.read::<GradientSpreadMethod>());
let mut gradient_stops = self.gradient_stops.borrow_mut();
gradient_stops.clear();
let count = reader.read::<i32>();
for _ in 0..count {
match reader.read_value::<ImmutableGradientStop>() {
Some(stop) => gradient_stops.push(Rc::new(stop)),
None => panic!("a batch lists a null gradient stop"),
}
}
}
}
macro_rules! server_simple_brush {
(
$(#[$meta:meta])*
$name:ident { $($field:ident : $field_ty:ty = $field_init:expr),* $(,)? }
brush: |$b:ident| $brush:expr;
deserialize: |$d:ident, $reader:ident, $committed_at:ident| $deserialize:expr;
find: |$f:ident, $type_id:ident| $find:expr;
$(dispose: |$x:ident| $dispose:expr;)?
as: { $($as_fn:ident -> $as_trait:path),* $(,)? }
) => {
$(#[$meta])*
pub struct $name {
base: SimpleServerRenderResource,
this: Weak<$name>,
$($field: $field_ty,)*
}
impl $name {
pub fn new(compositor: &Rc<ServerCompositor>) -> Rc<$name> {
Rc::new_cyclic(|this| {
let this: Weak<$name> = this.clone();
$name {
base: SimpleServerRenderResource::new(compositor, this.clone()),
this,
$($field: $field_init,)*
}
})
}
pub fn to_rc(&self) -> Option<Rc<$name>> {
self.this.upgrade()
}
pub fn is_disposed(&self) -> bool {
self.base.is_disposed()
}
pub fn brush_props(&self) -> &ServerCompositionSimpleBrushProps {
let $b = self;
$brush
}
}
impl_simple_server_render_resource!($name, base);
impl ServerCompositionSimpleBrushHooks for $name {}
impl IServerObject for $name {
fn deserialize_changes_core(&self, $reader: &mut BatchStreamReader<'_>, $committed_at: Duration) {
let $d = self;
$deserialize
}
fn values_invalidated(&self) {
self.base.core().invalidated(self);
}
fn dispose(&self) {
$(
let $x = self;
$dispose;
)?
self.base.core().dispose();
}
fn as_render_resource(self: Rc<Self>) -> Option<Rc<dyn IServerRenderResource>> {
Some(self)
}
fn as_brush(self: Rc<Self>) -> Option<Rc<dyn IBrush>> {
Some(self)
}
fn get_props(&self, $type_id: TypeId) -> Option<&dyn Any> {
let $f = self;
$find
}
fn as_any(&self) -> &dyn Any {
self
}
fn into_any_rc(self: Rc<Self>) -> Rc<dyn Any> {
self
}
}
impl IBrush for $name {
fn opacity(&self) -> f64 {
self.brush_props().opacity()
}
fn transform(&self) -> Option<Rc<dyn ITransform>> {
self.brush_props().transform().map(|transform| transform.value)
}
fn transform_origin(&self) -> RelativePoint {
self.brush_props().transform_origin()
}
fn relative_transform(&self) -> Option<Rc<dyn ITransform>> {
self.brush_props().relative_transform().map(|transform| transform.value)
}
fn as_any(&self) -> &dyn Any {
self
}
$(
fn $as_fn(&self) -> Option<&dyn $as_trait> {
Some(self)
}
)*
}
};
}
pub(crate) use server_simple_brush;
server_simple_brush! {
ServerCompositionSimpleBrush { props: ServerCompositionSimpleBrushProps = ServerCompositionSimpleBrushProps::new() }
brush: |b| &b.props;
deserialize: |d, reader, committed_at| d.props.deserialize_changes_core(d, reader, committed_at);
find: |f, type_id| f.props.find_props(type_id);
as: {}
}
server_simple_brush! {
ServerCompositionSimpleSolidColorBrush {
props: ServerCompositionSimpleSolidColorBrushProps = ServerCompositionSimpleSolidColorBrushProps::new(),
}
brush: |b| b.props.base();
deserialize: |d, reader, committed_at| d.props.deserialize_changes_core(d, reader, committed_at);
find: |f, type_id| f.props.find_props(type_id);
as: { as_solid_color_brush -> ISolidColorBrush }
}
impl ServerCompositionSimpleSolidColorBrushHooks for ServerCompositionSimpleSolidColorBrush {}
impl ServerCompositionSimpleSolidColorBrush {
pub fn props(&self) -> &ServerCompositionSimpleSolidColorBrushProps {
&self.props
}
pub fn set_color(&self, value: Color) {
self.props.set_color(self, value)
}
}
impl ISolidColorBrush for ServerCompositionSimpleSolidColorBrush {
fn color(&self) -> Color {
self.props.color()
}
}
server_simple_brush! {
ServerCompositionSimpleTileBrush {
props: ServerCompositionSimpleTileBrushProps = ServerCompositionSimpleTileBrushProps::new(),
}
brush: |b| b.props.base();
deserialize: |d, reader, committed_at| d.props.deserialize_changes_core(d, reader, committed_at);
find: |f, type_id| f.props.find_props(type_id);
as: { as_tile_brush -> ITileBrush }
}
impl ServerCompositionSimpleTileBrushHooks for ServerCompositionSimpleTileBrush {}
impl ServerCompositionSimpleTileBrush {
pub fn props(&self) -> &ServerCompositionSimpleTileBrushProps {
&self.props
}
}
impl ITileBrush for ServerCompositionSimpleTileBrush {
fn alignment_x(&self) -> AlignmentX {
self.props.alignment_x()
}
fn alignment_y(&self) -> AlignmentY {
self.props.alignment_y()
}
fn destination_rect(&self) -> RelativeRect {
self.props.destination_rect()
}
fn source_rect(&self) -> RelativeRect {
self.props.source_rect()
}
fn stretch(&self) -> Stretch {
self.props.stretch()
}
fn tile_mode(&self) -> TileMode {
self.props.tile_mode()
}
}
macro_rules! server_simple_gradient_brush {
($(#[$meta:meta])* $name:ident, $props:ident, $hooks:ident, $as_fn:ident -> $as_trait:path) => {
server_simple_brush! {
$(#[$meta])*
$name {
gradient: ServerCompositionSimpleGradientBrush = ServerCompositionSimpleGradientBrush::new(),
props: $props = $props::new(),
}
brush: |b| b.gradient.brush();
deserialize: |d, reader, committed_at| d.props.deserialize_changes_core(d, reader, committed_at);
find: |f, type_id| f.props.find_props(type_id).or_else(|| f.gradient.brush().find_props(type_id));
as: { as_gradient_brush -> IGradientBrush, $as_fn -> $as_trait }
}
impl $hooks for $name {
fn base_deserialize_changes_core(&self, reader: &mut BatchStreamReader<'_>, committed_at: Duration) {
self.gradient.deserialize_changes_core(self, reader, committed_at);
}
}
impl $name {
pub fn props(&self) -> &$props {
&self.props
}
}
impl IGradientBrush for $name {
fn gradient_stops(&self) -> Vec<Rc<dyn IGradientStop>> {
self.gradient.gradient_stops()
}
fn spread_method(&self) -> GradientSpreadMethod {
self.gradient.spread_method()
}
}
};
}
server_simple_gradient_brush!(
ServerCompositionSimpleConicGradientBrush,
ServerCompositionSimpleConicGradientBrushProps,
ServerCompositionSimpleConicGradientBrushHooks,
as_conic_gradient_brush -> IConicGradientBrush
);
impl IConicGradientBrush for ServerCompositionSimpleConicGradientBrush {
fn center(&self) -> RelativePoint {
self.props.center()
}
fn angle(&self) -> f64 {
self.props.angle()
}
}
server_simple_gradient_brush!(
ServerCompositionSimpleLinearGradientBrush,
ServerCompositionSimpleLinearGradientBrushProps,
ServerCompositionSimpleLinearGradientBrushHooks,
as_linear_gradient_brush -> ILinearGradientBrush
);
impl ILinearGradientBrush for ServerCompositionSimpleLinearGradientBrush {
fn start_point(&self) -> RelativePoint {
self.props.start_point()
}
fn end_point(&self) -> RelativePoint {
self.props.end_point()
}
}
server_simple_gradient_brush!(
ServerCompositionSimpleRadialGradientBrush,
ServerCompositionSimpleRadialGradientBrushProps,
ServerCompositionSimpleRadialGradientBrushHooks,
as_radial_gradient_brush -> IRadialGradientBrush
);
impl IRadialGradientBrush for ServerCompositionSimpleRadialGradientBrush {
fn center(&self) -> RelativePoint {
self.props.center()
}
fn gradient_origin(&self) -> RelativePoint {
self.props.gradient_origin()
}
fn radius_x(&self) -> RelativeScalar {
self.props.radius_x()
}
fn radius_y(&self) -> RelativeScalar {
self.props.radius_y()
}
}