1use std::rc::Rc;
5
6use nifty_check::hir::Program;
7use nifty_runtime::{Backend, Engine, Ui};
8
9use crate::logic::Interpreter;
10use crate::lower;
11use crate::machine::{Machine, Result, RuntimeError};
12
13pub type ErrorHandler = nifty_runtime::ErrorHandler<RuntimeError>;
14
15pub struct App<B: Backend> {
17 engine: Rc<Engine<Interpreter, B>>,
18}
19
20impl<B: Backend> std::fmt::Debug for App<B> {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 f.debug_struct("App").finish_non_exhaustive()
23 }
24}
25
26impl<B: Backend> App<B> {
27 pub fn start(program: Program, ui: Ui<B>, on_error: ErrorHandler) -> Result<Self> {
35 let machine = Machine::new(Rc::new(program), None)?;
36 let app = lower::app(machine.program());
37 let engine = Engine::start(ui, app, on_error, |ui, engine| {
38 Interpreter::new(machine, ui, engine)
39 })?;
40 Ok(Self { engine })
41 }
42
43 pub fn reload(&self, program: Program) -> Result<Self> {
53 let machine = Machine::new(Rc::new(program), Some(self.engine.logic().machine()))?;
54 let app = lower::app(machine.program());
55 let engine = self
56 .engine
57 .reload(app, |ui, engine| Interpreter::new(machine, ui, engine))?;
58 Ok(Self { engine })
59 }
60
61 pub fn run(&self) {
63 self.engine.run();
64 }
65
66 #[cfg(test)]
67 pub(crate) fn machine(&self) -> &Machine {
68 self.engine.logic().machine()
69 }
70
71 #[cfg(test)]
73 pub(crate) fn wait_for_downloads(&self) {
74 self.engine.logic().wait_for_downloads();
75 }
76
77 #[cfg(test)]
79 pub(crate) fn wait_for_download_report(&self) {
80 self.engine.logic().wait_for_download_report();
81 }
82}