bumpin tengri
Some checks failed
/ build (push) Has been cancelled

This commit is contained in:
okay stopped screaming 2026-03-20 02:49:24 +02:00
parent 54f0a95f3a
commit 0577309b19
4 changed files with 92 additions and 69 deletions

View file

@ -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" }

View file

@ -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

View file

@ -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<Self> 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<usize> 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<f64> 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<f64> for $T {
fn get (&self) -> f64 { self.0.load(Relaxed) }
}
impl InteriorMutable<f64> 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<f64> for $T { fn from (value: f64) -> Self { Self(value.into()) } }
impl From<usize> 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 <T: AsRef<Clock>+AsMut<Clock>> HasClock for T {}
impl <T: AsRef<Selection>+AsMut<Selection>> HasSelection for T {}
impl <T: AsRef<Sequencer>+AsMut<Sequencer>> HasSequencer for T {}
@ -40,7 +103,7 @@ mod app {
impl Draw<TuiOut> 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<J: HasJack<'static>> 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<Self> 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<usize> 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<f64> 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<f64> for $T {
fn get (&self) -> f64 { self.0.load(Relaxed) }
}
impl InteriorMutable<f64> 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<f64> for $T { fn from (value: f64) -> Self { Self(value.into()) } }
impl From<usize> 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!() }

2
tengri

@ -1 +1 @@
Subproject commit f1dda6af07b94928481d062c3d3fda5b9e969633
Subproject commit 9dbf4fcab5f31a68e3d24c8f8f7fc866159e89f1