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