summaryrefslogtreecommitdiffstats
path: root/core/src/runtime.rs
blob: 6b1b5d1174fa780c63663eeb6b5f94407916b995 (plain)
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use crate::core_shapes::CoreDrawable;
use crate::rendering::Render;
use crate::types::Bounds;

// use super::complex_shapes::{ComplexShape, Drawable};
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>,
    drawables: Vec<CoreDrawable>,
}

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(),
            drawables: Vec::new(),
        }
    }

    // pub fn add_drawable<T: ComplexShape + 'static>(&mut self, drawable: Drawable<T>) {
    //     self.drawables.push(drawable.into())
    // }

    pub fn add_drawable(&mut self, drawable: CoreDrawable) {
        self.drawables.push(drawable)
    }

    pub fn solver_ctx(&mut self) -> &mut (dyn SolverContext + 'a) {
        &mut *self.solver_ctx
    }

    pub fn renderer(&mut self) -> &mut dyn Renderer {
        &mut *self.renderer
    }

    pub fn render(mut self, bounds: Bounds) {
        let model = self.solver_ctx.solve();

        let bounds = bounds
            .fixate(&*model)
            .expect("Could not fixate figure bounds");

        self.renderer.set_size(bounds.width, bounds.height);

        for drawable in &self.drawables {
            let defined_drawable = drawable
                .fixate(&*model)
                .expect("Could not fixate core shape");
            defined_drawable
                .shape
                .render(defined_drawable.context, &mut *self.renderer);
        }
    }

    // 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"),
    //         }
    //     }
    // }
}