compiled layouts

This commit is contained in:
i do not exist 2026-08-29 18:46:46 +03:00
parent 6771b24f79
commit ab6959a84f
21 changed files with 534 additions and 263 deletions

View file

@ -16,6 +16,15 @@ pub fn show_version () {
#[allow(unused)]
#[hotpath::main]
fn main () -> Usually<()> {
#[cfg(feature = "prof")] let _flame_guard = {
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
//let tracy = tracing_tracy::TracyLayer::default();
let (flame, _guard) = tracing_flame::FlameLayer::with_file("./tracing.folded").unwrap();
//let registry = tracing_subscriber::registry().with(flame).init();
//tracing::subscriber::set_global_default(registry)?;
tracing::subscriber::set_global_default(tracing_subscriber::registry().with(flame))?;
_guard
};
tengri::Tui::setup_panic();
#[cfg(feature = "cli")] {
Config::watched(crate::cli::run_with_config)?;
@ -62,7 +71,7 @@ fn run_new_plain (config: Config) -> Usually<()> {
//Tui::run_main(&jack.run(move|jack|{
//// Between jack init and app's first cycle:
////jack.sync_lead(*sync_lead, |mut state|{
////let clock = app.write().unwrap().clock();
////let clock = app.try_write().unwrap().clock();
////clock.playhead.update_from_sample(state.position.frame() as f64);
////state.position.bbt = Some(clock.bbt());
////state.position
@ -493,12 +502,13 @@ mod bind {
use crate::*;
tui_keys!(self: App, input {
#[cfg(feature = "prof")] profiling::scope!("App::tui_keys!");
let name = self.mode.as_ref();
let mode = name.and_then(|m|self.config.get_mode(m)).as_ref().map(Arc::clone);
if let Some(mode) = mode {
let binds = self.config.binds.clone();
for id in mode.keys.iter() {
if let Some(event_map) = binds.read().unwrap().get(id.as_ref())
if let Some(event_map) = binds.try_read().unwrap().get(id.as_ref())
&& let Some(bindings) = event_map.query(input) {
for binding in bindings {
for command in binding.commands.iter() {
@ -702,7 +712,11 @@ mod device {
}
}
impl HasJack<'static> for App { fn jack (&self) -> &Jack<'static> { &self.jack } }
impl HasJack<'static> for App {
fn jack (&self) -> &Jack<'static> {
&self.jack
}
}
impl_audio!(App: tek_jack_process, tek_jack_event);
@ -894,10 +908,12 @@ mod draw {
/// Then, every top-level form of the DSL description is rendered.
impl Draw<Tui> for App {
fn draw (&self, to: &mut Tui) -> Drawn<u16> {
#[cfg(feature = "prof")] profiling::scope!("App::draw");
//self.perf.cycle(&mut |_|{
self.draw_error(to)?;
self.draw_modes(to)?;
//self.draw_debug(to)?;
self.draw_debug(to)?;
#[cfg(feature = "prof")] profiling::finish_frame!();
Ok(Some(to.area().into()))
//})
}
@ -905,7 +921,7 @@ mod draw {
impl App {
fn draw_error (&self, to: &mut Tui) -> Usually<()> {
if let Some(e) = self.error.read().unwrap().as_ref() {
if let Some(e) = self.error.try_read().unwrap().as_ref() {
e.as_ref().align_c().draw(to)?;
}
Ok(())
@ -914,27 +930,27 @@ mod draw {
fn draw_modes (&self, to: &mut Tui) -> Usually<()> {
if let Some(mode) = self.mode.as_ref().and_then(|m|self.config.get_mode(m)) {
let mut error = false;
for (index, dsl) in mode.view.iter().enumerate() {
match self.interpret(to, dsl) {
for (index, view) in mode.view.iter().enumerate() {
match (view.render)(self, to) {
Ok(None) => {},
Ok(Some(XYWH(.., w, h))) => {
self.size.0.store(w as usize, Relaxed);
self.size.1.store(h as usize, Relaxed);
},
Err(e) => {
let src = &dsl.src().unwrap_or(Some("<source error>")).unwrap_or("<no source>");
let message = format!(
"Mode: {:?}\n\nLayer: #{index}\n\nError: {e}\n\nSource:\n{src}",
&mode.name
"Mode: {:?}\n\nLayer: #{index}\n\nError: {e}\n\nSource:\n{}",
&mode.name,
&view.source
);
*self.error.write().unwrap() = Some(message.into());
*self.error.try_write().unwrap() = Some(message.into());
error = true;
break;
}
}
}
if !error {
*self.error.write().unwrap() = None;
*self.error.try_write().unwrap() = None;
}
}
Ok(())
@ -942,78 +958,17 @@ mod draw {
#[allow(unused)] fn draw_debug (&self, to: &mut Tui) -> Drawn<u16> {
east(
format!("{}x{} ", self.size.0.load(Relaxed), self.size.1.load(Relaxed)),
format!("{}% {} ", self.perf.percentage().unwrap_or_default(), self.perf.clock.raw() / 1000000000),
format!("{}x{} ",
self.size.0.load(Relaxed),
self.size.1.load(Relaxed)),
format!("{}/{} {} ",
self.perf.used.load(Relaxed),
self.perf.window.load(Relaxed),
self.perf.clock.raw() / 1000000000),
).align_se().draw(to)
}
}
impl Interpret<Tui, Option<XYWH<u16>>> for App {
fn interpret <L: Language> (&self, to: &mut Tui, dsl: L) -> Drawn<u16> {
if let Ok(Some(expr)) = dsl.expr() {
ok_flat(expr.head()?.map(|head|{
match head.split('/').next() {
Some("when") => kw_when(self, to, expr),
Some("either") => kw_either(self, to, expr),
Some("bsp") => kw_split(self, to, expr),
Some("split") => kw_split(self, to, expr),
Some("align") => kw_align(self, to, expr),
Some("full") => kw_full(self, to, expr),
Some("exact") => kw_exact(self, to, expr),
Some("min") => kw_min(self, to, expr),
Some("max") => kw_max(self, to, expr),
Some("push") => kw_push(self, to, expr),
Some("pull") => kw_pull(self, to, expr),
Some("text") => kw_tui_text(self, to, expr),
Some("fg") => kw_tui_fg(self, to, expr),
Some("bg") => kw_tui_bg(self, to, expr),
_ => Err(format!("interpret_expr: unexpected: {expr:?}").into())
}
}))
} else if let Ok(Some(word)) = dsl.word() {
let mut frags = word.src()?.unwrap().split("/");
match frags.next() {
//Some(":logo") => view_logo().draw(to),
Some(":meters") => match frags.next() {
Some("input") => bg(Rgb(30, 30, 30), "Input Meters".align_s().full_h()).draw(to),
Some("output") => bg(Rgb(30, 30, 30), "Output Meters".align_s().full_h()).draw(to),
_ => panic!()
},
Some(":tracks") => match frags.next() {
None => "TODO tracks".draw(to),
Some("names") => self.project.view_track_names(self.color.clone()).draw(to),//bg(Rgb(40, 40, 40), full_w(align_w("Track Names")))),
Some("inputs") => self.project.view_track_inputs(self.color.clone()).draw(to),//bg(Rgb(40, 40, 40), "Track Inputs".align_w().full_w()).draw(to),
Some("devices") => self.project.view_track_devices(self.color.clone()).draw(to),//bg(Rgb(40, 40, 40), "Track Devices".align_w().full_w()).draw(to),
Some("outputs") => self.project.view_track_outputs(self.color.clone(), 0).draw(to),
_ => panic!()
},
Some(":scenes") => match frags.next() {
None => self.view_scenes_clips().draw(to),
Some("names") => self.view_scenes_names().draw(to),
_ => panic!()
},
Some(":dialog") => draw_dialog(to, frags, self),
Some(":templates") => view_templates(frags, self).draw(to),
Some(":sessions") => view_sessions().draw(to),
Some(":browse/title") => view_browse_title(self).draw(to),
Some(":device") => view_device(self).draw(to),
Some(":status") => "TODO: Status Bar".draw(to),
Some(":editor") => "TODO Editor".draw(to),
Some(":transport") => view_transport(true, "", "", "").draw(to),
Some(":debug") => format!("[{:?}]", to.area()).exact_h(1).draw(to),
Some(_) => if let Some(lang) = self.config.get_view(word) {
self.interpret(to, lang)
} else {
fg(Color::Rgb(128, 32, 32), format!("undefined: {word:?}")).draw(to)
},
_ => unreachable!()
}
} else {
Err(format!("not word/expr:\n{dsl:?}").into())
}
}
}
impl_has!(Sizer: |self: App|self.size);
pub trait HasWidth {
@ -1024,9 +979,7 @@ mod draw {
fn width_dec (&mut self);
}
pub fn view_templates <'a> (_frags: std::str::Split<&str>, state: &'a App)
-> impl Draw<Tui> + use<'a>
{
pub fn view_templates <'a> (state: &'a App) -> impl Draw<Tui> + use<'a> {
let height = (state.config.modes.len() * 2) as u16;
draw(move |to: &mut Tui|{
let mut index = 0;