use super::core_shapes::CoreShape; use super::solving::SolverContext; use super::styles::{FillStyle, StrokeStyle}; use super::types::{Bounds, ShapeContext, ShapeContextBuilder}; pub trait ComplexShape: DynClone { fn as_core_shape(&self) -> Option<&dyn CoreShape> { None } fn draw(&self, context: &ShapeContext, solver: &mut dyn SolverContext) -> DrawResult; } pub trait DynClone { fn dyn_clone(&self) -> Box; } impl DynClone for T { fn dyn_clone(&self) -> Box { Box::new(self.clone()) } } #[derive(Debug, Clone)] pub struct Drawable { pub(crate) context: ShapeContext, pub(crate) shape: T, } impl Drawable { pub fn new(shape: T, context: ShapeContext) -> Self { Self { context, shape } } pub fn from_shape(shape: T, solver: &mut dyn SolverContext) -> Self { Self { context: ShapeContext::builder().build(solver), shape, } } pub fn builder(shape: T) -> DrawableBuilder where T: Clone, { DrawableBuilder::new(shape) } pub fn shape(&self) -> &T { &self.shape } pub fn shape_mut(&mut self) -> &mut T { &mut self.shape } pub fn bounds(&self) -> &Bounds { &self.context.bounds } pub fn bounds_mut(&mut self) -> &mut Bounds { &mut self.context.bounds } pub fn fill_style(&mut self) -> &mut FillStyle { &mut self.context.fill } pub fn stroke_style(&mut self) -> &mut StrokeStyle { &mut self.context.stroke } } pub struct DrawableBuilder { context: ShapeContextBuilder, shape: T, } impl DrawableBuilder { pub fn new(shape: T) -> Self { Self { context: ShapeContext::builder(), shape, } } pub fn bounds(&mut self, bounds: Bounds) -> &mut Self { self.context.bounds(bounds); self } pub fn fill(&mut self, fill: FillStyle) -> &mut Self { self.context.fill(fill); self } pub fn stroke(&mut self, stroke: StrokeStyle) -> &mut Self { self.context.stroke(stroke); self } pub fn build(&self, solver: &mut dyn SolverContext) -> Drawable { Drawable { shape: self.shape.clone(), context: self.context.build(solver), } } } pub struct DynDrawable { pub(crate) context: ShapeContext, pub(crate) shape: Box, } // TODO: copy paste is bad? impl DynDrawable { pub fn new(shape: T, context: ShapeContext) -> Self { Self { context, shape: Box::new(shape), } } pub fn new_dyn(shape: Box, context: ShapeContext) -> Self { Self { context, shape } } pub fn from_shape(shape: T, solver: &mut dyn SolverContext) -> Self { Self { context: ShapeContext::builder().build(solver), shape: Box::new(shape), } } pub fn from_dyn(shape: Box, solver: &mut dyn SolverContext) -> Self { Self { context: ShapeContext::builder().build(solver), shape, } } pub fn shape(&self) -> &dyn ComplexShape { &*self.shape } pub fn shape_mut(&mut self) -> &mut dyn ComplexShape { &mut *self.shape } pub fn bounds(&self) -> &Bounds { &self.context.bounds } pub fn bounds_mut(&mut self) -> &mut Bounds { &mut self.context.bounds } pub fn fill_style(&mut self) -> &mut FillStyle { &mut self.context.fill } pub fn stroke_mut(&mut self) -> &mut StrokeStyle { &mut self.context.stroke } } impl Clone for DynDrawable { fn clone(&self) -> Self { DynDrawable { context: self.context.clone(), shape: self.shape.dyn_clone(), } } } impl From> for DynDrawable { fn from(drawable: Drawable) -> Self { DynDrawable { context: drawable.context, shape: Box::new(drawable.shape), } } } pub struct DrawResult { pub(crate) subshapes: Vec, pub(crate) waiting_on: Vec<()>, } impl DrawResult { pub fn new() -> Self { Self { subshapes: Vec::new(), waiting_on: Vec::new(), } } /* pub fn push_shape(&mut self, shape: T, context: ShapeContext) { self.subshapes.push(DynDrawable { context, shape: Box::new(shape), }) } pub fn push_boxed_shape(&mut self, shape: Box, context: ShapeContext) { self.subshapes.push(DynDrawable { context, shape }) } */ pub fn push(&mut self, drawable: Drawable) { self.subshapes.push(drawable.into()) } pub fn push_dyn(&mut self, drawable: DynDrawable) { self.subshapes.push(drawable) } } /* pub trait Drawable { fn draw<'z3>(&self, bounds: &Bounds<'z3>, z3_ctx: &z3::Context) -> DrawResult; } /* impl Drawable for Box { fn draw<'z3>(&self, bounds: &Bounds<'z3>, z3_ctx: &z3::Context) -> DrawResult { (**self).draw(bounds, z3_ctx) } } */ impl Drawable for CoreShape { fn draw<'z3>( &self, bounds: &Bounds<'z3>, ) -> ( Vec>, Vec>>, ) { // TODO: clone, really? ( vec![Bounded:: { bounds: bounds.clone(), shape: self.clone(), }], vec![], ) } fn constraints(&self, _bounds: &Bounds, _z3_ctx: &z3::Context) -> Vec { vec![] } } /* impl<'a, T: Drawable> Drawable for Vec> { fn draw<'z3>( &self, _bounds: &Bounds<'z3>, as_render Vec>, Vec>>, ) { let mut core_shapes = Vec::new(); let mut complex_drawables = Vec::new(); for drawable in self.iter() { let (mut inner_core_shapes, mut inner_complex_drawables) = drawable.shape.draw(&drawable.bounds); core_shapes.append(&mut inner_core_shapes); complex_drawables.append(&mut inner_complex_drawables); } (core_shapes, complex_drawables) } fn constraints(&self, _bounds: &Bounds, z3_ctx: &z3::Context) -> Vec { self.iter() .flat_map(|drawable| drawable.shape.constraints(&drawable.bounds, z3_ctx)) .collect() } } */ */