1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
use super::complex_shapes::{ComplexShape, Drawable, DynDrawable};
use super::rendering::Renderer;
use super::solving::{Constrainable, SolverContext};
const RECURSION_LIMIT: u64 = 10_000;
pub struct Runtime<'a> {
solver_ctx: Box<dyn SolverContext + 'a>,
renderer: Box<dyn Renderer>,
drawables: Vec<DynDrawable>,
}
impl<'a> Runtime<'a> {
pub fn new(solver_ctx: Box<dyn SolverContext + 'a>, renderer: Box<dyn Renderer>) -> Self {
Self {
solver_ctx,
renderer,
drawables: Vec::new(),
}
}
pub fn add_drawable<T: ComplexShape + 'static>(&mut self, drawable: Drawable<T>) {
self.drawables.push(drawable.into())
}
pub fn solver_ctx(&mut self) -> &mut (dyn SolverContext + 'a) {
&mut *self.solver_ctx
}
// TODO: preserve ordering of shapes
pub fn render(mut self) {
let mut drawables = self.drawables;
let mut waited_on_variables = Vec::new();
let mut core_shapes = Vec::new();
/*
for drawable in &self.shapes {
let bounds = &drawable.bounds;
let shape = &drawable.shape;
if let Some(core_shape) = shape.to_render() {
drawables.push((*drawable).clone());
continue;
}
let mut result = shape.draw(bounds);
drawables.append(&mut result.subshapes);
waited_on_variables.append(&mut result.waiting_on);
}
*/
let mut recursion_count = 0;
while !drawables.is_empty() {
recursion_count += 1;
if recursion_count > RECURSION_LIMIT {
panic!("Recursion limit reached");
}
let mut tmp_drawables = Vec::new();
for drawable in drawables.drain(..) {
let shape_ctx = &drawable.context;
let shape = &drawable.shape;
if let Some(core_shape) = shape.as_core_shape() {
core_shape.constrain(shape_ctx, &mut *self.solver_ctx, &*self.renderer);
core_shapes.push((shape.dyn_clone(), shape_ctx.clone())); // Better to Arc? Cow?
continue;
}
let mut result = shape.draw(shape_ctx, &mut *self.solver_ctx);
tmp_drawables.append(&mut result.subshapes);
waited_on_variables.append(&mut result.waiting_on);
}
drawables = tmp_drawables;
}
let model = self.solver_ctx.solve();
// Delay rendering core shapes until later to have all the constraints
for (core_shape, shape_ctx) in core_shapes {
let core_shape = core_shape.as_core_shape().unwrap();
match (core_shape.to_render(&*model), shape_ctx.fixate(&*model)) {
(Some(defined_shape), Some(shape_ctx)) => {
defined_shape.render(shape_ctx, &mut *self.renderer)
}
_ => panic!("Failed to fixate core shape"),
}
}
}
}
|