From 0577309b19c4cc77525f44877eac4b0d9b219884 Mon Sep 17 00:00:00 2001 From: okay stopped screaming Date: Fri, 20 Mar 2026 02:49:24 +0200 Subject: [PATCH] bumpin tengri --- Cargo.toml | 2 +- app/tek.rs | 28 +++++++++- app/tek_impls.rs | 129 +++++++++++++++++++++++------------------------ tengri | 2 +- 4 files changed, 92 insertions(+), 69 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1a05aaf7..fd3888d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ path = "app/tek.rs" rustflags = ["-C", "link-arg=-fuse-ld=mold"] [dependencies] -tengri = { path = "./tengri", features = [ "tui", "dsl" ] } +tengri = { path = "./tengri", features = [ "term", "lang" ] } ansi_term = { version = "0.12.1" } atomic_float = { version = "1.0.0" } diff --git a/app/tek.rs b/app/tek.rs index 6b2d9963..d7279804 100644 --- a/app/tek.rs +++ b/app/tek.rs @@ -20,6 +20,12 @@ pub(crate) use ::midly::{Smf, TrackEventKind, MidiMessage, Error as MidiError, n pub extern crate tengri; pub(crate) use tengri::{ *, + lang::*, + play::*, + sing::*, + time::*, + draw::*, + tui::*, crossterm::event::{Event, KeyEvent}, ratatui::{ self, @@ -62,8 +68,26 @@ pub(crate) use ConnectStatus::*; /// Command-line entrypoint. #[cfg(feature = "cli")] pub fn main () -> Usually<()> { - use clap::Parser; - Cli::parse().run() + Config::watch(|config|{ + Exit::enter(|exit|{ + Jack::connect("tek", |jack|{ + let state = Arc::new(RwLock::new(App { + color: ItemTheme::random(), + config: Config::init(), + dialog: Dialog::welcome(), + jack: jack.clone(), + mode: ":menu", + project: Arrangement::new(&jack, &Clock::new(&jack, 51)), + ..Default::default() + })); + // TODO: Sync these timings with main clock, so that things + // "accidentally" fall on the beat in overload conditions. + let keyboard = run_tui_in(&exit, &state, Duration::from_millis(100))?; + let terminal = run_tui_out(&exit, &state, Duration::from_millis(10))?; + (keyboard, terminal) + }) + }) + }) } /// Create a new application from a backend, project, config, and mode diff --git a/app/tek_impls.rs b/app/tek_impls.rs index 563ce8ff..67a6a9d1 100644 --- a/app/tek_impls.rs +++ b/app/tek_impls.rs @@ -1,6 +1,69 @@ use crate::*; use std::fmt::Write; +/// Implement an arithmetic operation for a unit of time +#[macro_export] macro_rules! impl_op { + ($T:ident, $Op:ident, $method:ident, |$a:ident,$b:ident|{$impl:expr}) => { + impl $Op for $T { + type Output = Self; #[inline] fn $method (self, other: Self) -> Self::Output { + let $a = self.get(); let $b = other.get(); Self($impl.into()) + } + } + impl $Op for $T { + type Output = Self; #[inline] fn $method (self, other: usize) -> Self::Output { + let $a = self.get(); let $b = other as f64; Self($impl.into()) + } + } + impl $Op for $T { + type Output = Self; #[inline] fn $method (self, other: f64) -> Self::Output { + let $a = self.get(); let $b = other; Self($impl.into()) + } + } + } +} + +/// Define and implement a unit of time +#[macro_export] macro_rules! impl_time_unit { + ($T:ident) => { + impl Gettable for $T { + fn get (&self) -> f64 { self.0.load(Relaxed) } + } + impl InteriorMutable for $T { + fn set (&self, value: f64) -> f64 { + let old = self.get(); + self.0.store(value, Relaxed); + old + } + } + impl TimeUnit for $T {} + impl_op!($T, Add, add, |a, b|{a + b}); + impl_op!($T, Sub, sub, |a, b|{a - b}); + impl_op!($T, Mul, mul, |a, b|{a * b}); + impl_op!($T, Div, div, |a, b|{a / b}); + impl_op!($T, Rem, rem, |a, b|{a % b}); + impl From for $T { fn from (value: f64) -> Self { Self(value.into()) } } + impl From for $T { fn from (value: usize) -> Self { Self((value as f64).into()) } } + impl From<$T> for f64 { fn from (value: $T) -> Self { value.get() } } + impl From<$T> for usize { fn from (value: $T) -> Self { value.get() as usize } } + impl From<&$T> for f64 { fn from (value: &$T) -> Self { value.get() } } + impl From<&$T> for usize { fn from (value: &$T) -> Self { value.get() as usize } } + impl Clone for $T { fn clone (&self) -> Self { Self(self.get().into()) } } + } +} + +#[macro_export] macro_rules! impl_has_clips { + (|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => { + impl $(<$($L),*$($T $(: $U)?),*>)? HasClips for $Struct $(<$($L),*$($T),*>)? { + fn clips <'a> (&'a $self) -> std::sync::RwLockReadGuard<'a, ClipPool> { + $cb.read().unwrap() + } + fn clips_mut <'a> (&'a $self) -> std::sync::RwLockWriteGuard<'a, ClipPool> { + $cb.write().unwrap() + } + } + } +} + impl +AsMut> HasClock for T {} impl +AsMut> HasSelection for T {} impl +AsMut> HasSequencer for T {} @@ -40,7 +103,7 @@ mod app { impl Draw for App { fn draw (&self, to: &mut TuiOut) { if let Some(e) = self.error.read().unwrap().as_ref() { - to.place_at(to.area(), e); + to.show(to.area(), e); } for (index, dsl) in self.mode.view.iter().enumerate() { if let Err(e) = self.understand(to, dsl) { @@ -51,7 +114,6 @@ mod app { } } - impl<'a> Namespace<'a, AppCommand> for App { symbols!('a |app| -> AppCommand { "x/inc" => AppCommand::Inc { axis: ControlAxis::X }, @@ -1082,9 +1144,6 @@ impl> RegisterPorts for J { impl_debug!(MenuItem |self, w| { write!(w, "{}", &self.0) }); impl_debug!(Condition |self, w| { write!(w, "*") }); -macro_rules!primitive(($T:ty: $name:ident)=>{ - fn $name (src: impl Language) -> Perhaps<$T> { - Ok(if let Some(src) = src.src()? { Some(to_number(src)? as $T) } else { None }) } }); primitive!(u8: try_to_u8); primitive!(u16: try_to_u16); primitive!(usize: try_to_usize); @@ -1364,54 +1423,6 @@ mod time { } } - /// Implement an arithmetic operation for a unit of time - #[macro_export] macro_rules! impl_op { - ($T:ident, $Op:ident, $method:ident, |$a:ident,$b:ident|{$impl:expr}) => { - impl $Op for $T { - type Output = Self; #[inline] fn $method (self, other: Self) -> Self::Output { - let $a = self.get(); let $b = other.get(); Self($impl.into()) - } - } - impl $Op for $T { - type Output = Self; #[inline] fn $method (self, other: usize) -> Self::Output { - let $a = self.get(); let $b = other as f64; Self($impl.into()) - } - } - impl $Op for $T { - type Output = Self; #[inline] fn $method (self, other: f64) -> Self::Output { - let $a = self.get(); let $b = other; Self($impl.into()) - } - } - } - } - /// Define and implement a unit of time - #[macro_export] macro_rules! impl_time_unit { - ($T:ident) => { - impl Gettable for $T { - fn get (&self) -> f64 { self.0.load(Relaxed) } - } - impl InteriorMutable for $T { - fn set (&self, value: f64) -> f64 { - let old = self.get(); - self.0.store(value, Relaxed); - old - } - } - impl TimeUnit for $T {} - impl_op!($T, Add, add, |a, b|{a + b}); - impl_op!($T, Sub, sub, |a, b|{a - b}); - impl_op!($T, Mul, mul, |a, b|{a * b}); - impl_op!($T, Div, div, |a, b|{a / b}); - impl_op!($T, Rem, rem, |a, b|{a % b}); - impl From for $T { fn from (value: f64) -> Self { Self(value.into()) } } - impl From for $T { fn from (value: usize) -> Self { Self((value as f64).into()) } } - impl From<$T> for f64 { fn from (value: $T) -> Self { value.get() } } - impl From<$T> for usize { fn from (value: $T) -> Self { value.get() as usize } } - impl From<&$T> for f64 { fn from (value: &$T) -> Self { value.get() } } - impl From<&$T> for usize { fn from (value: &$T) -> Self { value.get() as usize } } - impl Clone for $T { fn clone (&self) -> Self { Self(self.get().into()) } } - } - } impl_time_unit!(SampleCount); impl_time_unit!(SampleRate); impl_time_unit!(Microsecond); @@ -3495,18 +3506,6 @@ mod pool { format!("{:>02}", self.ticks()).into() } } - #[macro_export] macro_rules! has_clips { - (|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => { - impl $(<$($L),*$($T $(: $U)?),*>)? HasClips for $Struct $(<$($L),*$($T),*>)? { - fn clips <'a> (&'a $self) -> std::sync::RwLockReadGuard<'a, ClipPool> { - $cb.read().unwrap() - } - fn clips_mut <'a> (&'a $self) -> std::sync::RwLockWriteGuard<'a, ClipPool> { - $cb.write().unwrap() - } - } - } - } impl Pool { fn _todo_usize_ (&self) -> usize { todo!() } diff --git a/tengri b/tengri index f1dda6af..9dbf4fca 160000 --- a/tengri +++ b/tengri @@ -1 +1 @@ -Subproject commit f1dda6af07b94928481d062c3d3fda5b9e969633 +Subproject commit 9dbf4fcab5f31a68e3d24c8f8f7fc866159e89f1