summaryrefslogtreecommitdiffstats
path: root/core/src/complex_shapes.rs
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/complex_shapes.rs')
-rw-r--r--core/src/complex_shapes.rs285
1 files changed, 285 insertions, 0 deletions
diff --git a/core/src/complex_shapes.rs b/core/src/complex_shapes.rs
new file mode 100644
index 0000000..e23881d
--- /dev/null
+++ b/core/src/complex_shapes.rs
@@ -0,0 +1,285 @@
1use super::core_shapes::CoreShape;
2use super::solving::SolverContext;
3use super::styles::{FillStyle, StrokeStyle};
4use super::types::{Bounds, ShapeContext, ShapeContextBuilder};
5
6pub trait ComplexShape: DynClone {
7 fn as_core_shape(&self) -> Option<&dyn CoreShape> {
8 None
9 }
10
11 fn draw(&self, context: &ShapeContext, solver: &mut dyn SolverContext) -> DrawResult;
12}
13
14pub trait DynClone {
15 fn dyn_clone(&self) -> Box<dyn ComplexShape>;
16}
17
18impl<T: Clone + ComplexShape + 'static> DynClone for T {
19 fn dyn_clone(&self) -> Box<dyn ComplexShape> {
20 Box::new(self.clone())
21 }
22}
23
24#[derive(Debug, Clone)]
25pub struct Drawable<T: ComplexShape> {
26 pub(crate) context: ShapeContext,
27 pub(crate) shape: T,
28}
29
30impl<T: ComplexShape> Drawable<T> {
31 pub fn new(shape: T, context: ShapeContext) -> Self {
32 Self { context, shape }
33 }
34
35 pub fn from_shape(shape: T, solver: &mut dyn SolverContext) -> Self {
36 Self {
37 context: ShapeContext::builder().build(solver),
38 shape,
39 }
40 }
41
42 pub fn builder(shape: T) -> DrawableBuilder<T>
43 where
44 T: Clone,
45 {
46 DrawableBuilder::new(shape)
47 }
48
49 pub fn shape(&self) -> &T {
50 &self.shape
51 }
52
53 pub fn shape_mut(&mut self) -> &mut T {
54 &mut self.shape
55 }
56
57 pub fn bounds(&self) -> &Bounds {
58 &self.context.bounds
59 }
60
61 pub fn bounds_mut(&mut self) -> &mut Bounds {
62 &mut self.context.bounds
63 }
64
65 pub fn fill_style(&mut self) -> &mut FillStyle {
66 &mut self.context.fill
67 }
68
69 pub fn stroke_style(&mut self) -> &mut StrokeStyle {
70 &mut self.context.stroke
71 }
72}
73
74pub struct DrawableBuilder<T: ComplexShape> {
75 context: ShapeContextBuilder,
76 shape: T,
77}
78
79impl<T: ComplexShape + Clone> DrawableBuilder<T> {
80 pub fn new(shape: T) -> Self {
81 Self {
82 context: ShapeContext::builder(),
83 shape,
84 }
85 }
86
87 pub fn bounds(&mut self, bounds: Bounds) -> &mut Self {
88 self.context.bounds(bounds);
89 self
90 }
91
92 pub fn fill(&mut self, fill: FillStyle) -> &mut Self {
93 self.context.fill(fill);
94 self
95 }
96
97 pub fn stroke(&mut self, stroke: StrokeStyle) -> &mut Self {
98 self.context.stroke(stroke);
99 self
100 }
101
102 pub fn build(&self, solver: &mut dyn SolverContext) -> Drawable<T> {
103 Drawable {
104 shape: self.shape.clone(),
105 context: self.context.build(solver),
106 }
107 }
108}
109
110pub struct DynDrawable {
111 pub(crate) context: ShapeContext,
112 pub(crate) shape: Box<dyn ComplexShape>,
113}
114
115// TODO: copy paste is bad?
116impl DynDrawable {
117 pub fn new<T: ComplexShape + 'static>(shape: T, context: ShapeContext) -> Self {
118 Self {
119 context,
120 shape: Box::new(shape),
121 }
122 }
123
124 pub fn new_dyn(shape: Box<dyn ComplexShape>, context: ShapeContext) -> Self {
125 Self { context, shape }
126 }
127
128 pub fn from_shape<T: ComplexShape + 'static>(shape: T, solver: &mut dyn SolverContext) -> Self {
129 Self {
130 context: ShapeContext::builder().build(solver),
131 shape: Box::new(shape),
132 }
133 }
134
135 pub fn from_dyn(shape: Box<dyn ComplexShape>, solver: &mut dyn SolverContext) -> Self {
136 Self {
137 context: ShapeContext::builder().build(solver),
138 shape,
139 }
140 }
141
142 pub fn shape(&self) -> &dyn ComplexShape {
143 &*self.shape
144 }
145
146 pub fn shape_mut(&mut self) -> &mut dyn ComplexShape {
147 &mut *self.shape
148 }
149
150 pub fn bounds(&self) -> &Bounds {
151 &self.context.bounds
152 }
153
154 pub fn bounds_mut(&mut self) -> &mut Bounds {
155 &mut self.context.bounds
156 }
157
158 pub fn fill_style(&mut self) -> &mut FillStyle {
159 &mut self.context.fill
160 }
161
162 pub fn stroke_mut(&mut self) -> &mut StrokeStyle {
163 &mut self.context.stroke
164 }
165}
166
167impl Clone for DynDrawable {
168 fn clone(&self) -> Self {
169 DynDrawable {
170 context: self.context.clone(),
171 shape: self.shape.dyn_clone(),
172 }
173 }
174}
175
176impl<T: ComplexShape + 'static> From<Drawable<T>> for DynDrawable {
177 fn from(drawable: Drawable<T>) -> Self {
178 DynDrawable {
179 context: drawable.context,
180 shape: Box::new(drawable.shape),
181 }
182 }
183}
184
185pub struct DrawResult {
186 pub(crate) subshapes: Vec<DynDrawable>,
187 pub(crate) waiting_on: Vec<()>,
188}
189
190impl DrawResult {
191 pub fn new() -> Self {
192 Self {
193 subshapes: Vec::new(),
194 waiting_on: Vec::new(),
195 }
196 }
197
198 /*
199 pub fn push_shape<T: ComplexShape + 'static>(&mut self, shape: T, context: ShapeContext) {
200 self.subshapes.push(DynDrawable {
201 context,
202 shape: Box::new(shape),
203 })
204 }
205
206 pub fn push_boxed_shape(&mut self, shape: Box<dyn ComplexShape>, context: ShapeContext) {
207 self.subshapes.push(DynDrawable { context, shape })
208 }
209 */
210
211 pub fn push<T: ComplexShape + 'static>(&mut self, drawable: Drawable<T>) {
212 self.subshapes.push(drawable.into())
213 }
214
215 pub fn push_dyn(&mut self, drawable: DynDrawable) {
216 self.subshapes.push(drawable)
217 }
218}
219
220/*
221pub trait Drawable {
222 fn draw<'z3>(&self, bounds: &Bounds<'z3>, z3_ctx: &z3::Context) -> DrawResult;
223}
224
225/*
226impl Drawable for Box<dyn Drawable> {
227 fn draw<'z3>(&self, bounds: &Bounds<'z3>, z3_ctx: &z3::Context) -> DrawResult {
228 (**self).draw(bounds, z3_ctx)
229 }
230}
231*/
232
233impl Drawable for CoreShape {
234 fn draw<'z3>(
235 &self,
236 bounds: &Bounds<'z3>,
237 ) -> (
238 Vec<Bounded<'z3, CoreShape>>,
239 Vec<Bounded<'z3, Box<dyn Drawable>>>,
240 ) {
241 // TODO: clone, really?
242 (
243 vec![Bounded::<CoreShape> {
244 bounds: bounds.clone(),
245 shape: self.clone(),
246 }],
247 vec![],
248 )
249 }
250
251 fn constraints(&self, _bounds: &Bounds, _z3_ctx: &z3::Context) -> Vec<z3::ast::Bool> {
252 vec![]
253 }
254}
255
256/*
257impl<'a, T: Drawable> Drawable for Vec<Bounded<'a, T>> {
258 fn draw<'z3>(
259 &self,
260 _bounds: &Bounds<'z3>,
261 as_render Vec<Bounded<'z3, CoreShape>>,
262 Vec<Bounded<'z3, Box<dyn Drawable>>>,
263 ) {
264 let mut core_shapes = Vec::new();
265 let mut complex_drawables = Vec::new();
266
267 for drawable in self.iter() {
268 let (mut inner_core_shapes, mut inner_complex_drawables) =
269 drawable.shape.draw(&drawable.bounds);
270
271 core_shapes.append(&mut inner_core_shapes);
272 complex_drawables.append(&mut inner_complex_drawables);
273 }
274
275 (core_shapes, complex_drawables)
276 }
277
278 fn constraints(&self, _bounds: &Bounds, z3_ctx: &z3::Context) -> Vec<z3::ast::Bool> {
279 self.iter()
280 .flat_map(|drawable| drawable.shape.constraints(&drawable.bounds, z3_ctx))
281 .collect()
282 }
283}
284*/
285*/