blockworx/script/
headless.rs1use crate::schema::model as schema;
7use crate::theme::Theme;
8
9use super::lowering::{Lowering, SimFrame, UnresolvedTarget};
10use super::session::Session;
11use super::step::Script;
12
13pub struct Headless {
14 ctx: egui::Context,
15 theme: Theme,
16 session: Session,
17}
18
19impl Headless {
20 pub fn new(initial_kdl: Option<&str>, name: &str) -> Self {
21 let ctx = egui::Context::default();
22 ctx.set_fonts(crate::font::build_fonts(
26 crate::preferences::FontChoice::default(),
27 ));
28 let _ = ctx.run_ui(egui::RawInput::default(), |_| {});
29 Self {
30 ctx,
31 theme: Theme::default(),
32 session: Session::new(initial_kdl, name),
33 }
34 }
35
36 pub fn run_script(&mut self, script: &Script) -> Result<(), UnresolvedTarget> {
41 let mut lowering = Lowering::new(script);
42 loop {
43 let next = lowering.next(|| self.session.projected())?;
44 match next {
45 Some(frame) => self.step(frame),
46 None => break,
47 }
48 }
49 let idle = self.session.idle_frame();
50 self.step(idle);
51 Ok(())
52 }
53
54 fn step(&mut self, frame: SimFrame) {
57 let Self {
58 ctx,
59 theme,
60 session,
61 } = self;
62 let _ = ctx.clone().run_ui(egui::RawInput::default(), |ui| {
63 let painter = ui.ctx().layer_painter(egui::LayerId::new(
64 egui::Order::Background,
65 egui::Id::new("script_headless"),
66 ));
67 session.step(frame, theme, &painter);
68 });
69 }
70
71 pub fn projected(&self) -> schema::Document {
72 self.session.projected()
73 }
74
75 #[cfg(test)]
78 pub fn renaming(&self) -> bool {
79 self.session.renaming()
80 }
81}