use crate::{ core_shapes::CoreDrawable, rendering::{Render, Renderer}, solving::{Constrainable, SolverContext}, types::Bounds, }; // TODO: // const RECURSION_LIMIT: u64 = 10_000; pub struct Runtime<'a> { solver_ctx: Box, renderer: Box, // drawables: Vec, drawables: Vec, } impl<'a> Runtime<'a> { pub fn new(solver_ctx: Box, renderer: Box) -> Self { Self { solver_ctx, renderer, drawables: Vec::new(), } } 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(self, bounds: Bounds) { // Separate self into several variables, so we can get mutable references to each at the // same time let Runtime { mut solver_ctx, mut renderer, drawables, } = self; for drawable in &drawables { drawable.inherent_constraints(&mut *solver_ctx, &mut *renderer); } let model = solver_ctx.solve(); let bounds = bounds .fixate(&*model) .expect("Could not fixate figure bounds"); renderer.set_size(bounds.width, bounds.height); for drawable in &drawables { let defined_drawable = drawable .fixate(&*model) .expect("Could not fixate core shape"); defined_drawable .shape .render(defined_drawable.context, &mut *renderer); } } }