diff --git a/Justfile b/Justfile index 48b3ef3b..0887febd 100644 --- a/Justfile +++ b/Justfile @@ -1,42 +1,4 @@ -default: - bacon -sj test -tui: - cargo run --example tui -cloc: - for src in {cli,edn/src,input/src,jack/src,midi/src,output/src,plugin/src,sampler/src,tek/src,time/src,tui/src}; do echo; echo $src; cloc --quiet $src; done -test: - cargo test --workspace --exclude jack -covfig := "CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' RUSTDOCFLAGS='-Cinstrument-coverage' LLVM_PROFILE_FILE='cov/cargo-test-%p-%m.profraw'" -cov: - rm -rf target/coverage/html || true - {{covfig}} time cargo test --workspace --exclude jack --profile coverage - {{covfig}} time grcov . --binary-path ./target/coverage/deps/ -s . -t html --ignore-not-existing --ignore '../*' --ignore "/*" --ignore 'target/*' -o target/coverage/html -llcov: - time cargo llvm-cov --workspace --exclude jack --profile coverage --no-report - time cargo llvm-cov --workspace --exclude jack --profile coverage --no-report --doc - time cargo llvm-cov report --doctests --html #--output-path target/coverage/html -prof: - CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph -- arranger -status: - cargo c - cloc --by-file src/ - git status -doc: - cargo doc --document-private-items - -upstreams := "codeberg origin" # TODO! - -amend: - git commit --amend -push: - git push -u codeberg main && git push -u origin main -tpush: - git push --tags -u codeberg && git push --tags -u origin -fpush: - git push -fu codeberg main && git push -fu origin main -ftpush: - git push --tags -fu codeberg && git push --tags -fu origin - +upstreams := "codeberg origin" # TODO! debug := "reset && cargo run --" release := "reset && cargo run --release --" name := "-n tek" @@ -47,15 +9,37 @@ audio-in := "-l 'Komplete Audio 6 Pro:capture_AUX1' -r 'Komplete Audio 6 Pro:c audio-out := "-L 'Komplete Audio 6 Pro:playback_AUX1' -R 'Komplete Audio 6 Pro:playback_AUX1'" firefox-in := "-l 'Firefox:output_FL' -r 'Firefox:output_FR'" -# TODO: arranger track mappings -#-i "1=Midi-Bridge:nanoKEY Studio 2:(capture_0) nanoKEY Studio nanoKEY Studio _" -#-o "1=Midi-Bridge:Komplete Audio 6 1:(playback_0) Komplete Audio 6 MIDI 1" -#-i "2=Midi-Bridge:nanoKEY Studio 2:(capture_0) nanoKEY Studio nanoKEY Studio _" -#-o "2=Midi-Bridge:Komplete Audio 6 1:(playback_0) Komplete Audio 6 MIDI 1" -#-i "3=Midi-Bridge:nanoKEY Studio 2:(capture_0) nanoKEY Studio nanoKEY Studio _" -#-o "3=Midi-Bridge:Komplete Audio 6 1:(playback_0) Komplete Audio 6 MIDI 1" -#-i "4=Midi-Bridge:nanoKEY Studio 2:(capture_0) nanoKEY Studio nanoKEY Studio _" -#-o "4=Midi-Bridge:Komplete Audio 6 1:(playback_0) Komplete Audio 6 MIDI 1" +default: + bacon -s +tui: + cargo run --example tui +cloc: + for src in {cli,edn/src,input/src,jack/src,midi/src,output/src,plugin/src,sampler/src,tek/src,time/src,tui/src}; do echo; echo $src; cloc --quiet $src; done +test: + cargo test --workspace --exclude jack +prof: + CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph -- arranger +doc: + cargo doc --workspace --document-private-items +covfig := "CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' RUSTDOCFLAGS='-Cinstrument-coverage' LLVM_PROFILE_FILE='cov/cargo-test-%p-%m.profraw'" +cov: + rm -rf target/coverage/html || true + {{covfig}} time cargo test --workspace --exclude jack --profile coverage + {{covfig}} time grcov . --binary-path ./target/coverage/deps/ -s . -t html --ignore-not-existing --ignore '../*' --ignore "/*" --ignore 'target/*' -o target/coverage/html +llcov: + time cargo llvm-cov --workspace --exclude jack --profile coverage --no-report + time cargo llvm-cov --workspace --exclude jack --profile coverage --no-report --doc + time cargo llvm-cov report --doctests --html #--output-path target/coverage/html +amend: + git commit --amend +push: + git push -u codeberg main && git push -u origin main +tpush: + git push --tags -u codeberg && git push --tags -u origin +fpush: + git push -fu codeberg main && git push -fu origin main +ftpush: + git push --tags -fu codeberg && git push --tags -fu origin run: {{debug}} diff --git a/output/Cargo.toml b/output/Cargo.toml index 147a1c23..627c621f 100644 --- a/output/Cargo.toml +++ b/output/Cargo.toml @@ -8,4 +8,4 @@ tek_edn = { path = "../edn" } [dev-dependencies] tek_tui = { path = "../tui" } -proptest = "^1" +proptest = "^1.6.0" diff --git a/output/proptest-regressions/area.txt b/output/proptest-regressions/area.txt new file mode 100644 index 00000000..1c957a54 --- /dev/null +++ b/output/proptest-regressions/area.txt @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc d2cd65ec39a1bf43c14bb2d3196c7e84ba854411360e570f06dd7ede62b0fd61 # shrinks to x = 0, y = 43998, w = 0, h = 43076, a = 0, b = 0 diff --git a/output/proptest-regressions/direction.txt b/output/proptest-regressions/direction.txt new file mode 100644 index 00000000..76b3facc --- /dev/null +++ b/output/proptest-regressions/direction.txt @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 5b236150b286e479089d5bf6accc8ffbc3c0b0a1f955682af1987f342930d31e # shrinks to x = 0, y = 0, w = 0, h = 0, a = 1 diff --git a/output/src/area.rs b/output/src/area.rs index f4867949..a571582c 100644 --- a/output/src/area.rs +++ b/output/src/area.rs @@ -6,6 +6,17 @@ pub trait Area: From<[N;4]> + Debug + Copy { fn y (&self) -> N; fn w (&self) -> N; fn h (&self) -> N; + #[inline] fn zero () -> [N;4] { + [N::zero(), N::zero(), N::zero(), N::zero()] + } + #[inline] fn from_position (pos: impl Size) -> [N;4] { + let [x, y] = pos.wh(); + [x, y, 0.into(), 0.into()] + } + #[inline] fn from_size (size: impl Size) -> [N;4] { + let [w, h] = size.wh(); + [0.into(), 0.into(), w, h] + } #[inline] fn expect_min (&self, w: N, h: N) -> Usually<&Self> { if self.w() < w || self.h() < h { Err(format!("min {w}x{h}").into()) @@ -49,14 +60,13 @@ pub trait Area: From<[N;4]> + Debug + Copy { #[inline] fn center (&self) -> [N;2] { [self.x().plus(self.w()/2.into()), self.y().plus(self.h()/2.into())] } - #[inline] fn center_x (&self, n: N) -> [N;4] { let [x, y, w, h] = self.xywh(); [(x.plus(w / 2.into())).minus(n / 2.into()), y.plus(h / 2.into()), n, 1.into()] } #[inline] fn center_y (&self, n: N) -> [N;4] { let [x, y, w, h] = self.xywh(); - [x.plus(w / 2.into()), (y + h / 2.into()).minus(n / 2.into()), 1.into(), n] + [x.plus(w / 2.into()), (y.plus(h / 2.into())).minus(n / 2.into()), 1.into(), n] } #[inline] fn center_xy (&self, [n, m]: [N;2]) -> [N;4] { let [x, y, w, h] = self.xywh(); @@ -66,17 +76,6 @@ pub trait Area: From<[N;4]> + Debug + Copy { #[inline] fn centered (&self) -> [N;2] { [self.x().minus(self.w()/2.into()), self.y().minus(self.h()/2.into())] } - #[inline] fn zero () -> [N;4] { - [N::zero(), N::zero(), N::zero(), N::zero()] - } - #[inline] fn from_position (pos: impl Size) -> [N;4] { - let [x, y] = pos.wh(); - [x, y, 0.into(), 0.into()] - } - #[inline] fn from_size (size: impl Size) -> [N;4] { - let [w, h] = size.wh(); - [0.into(), 0.into(), w, h] - } } impl Area for (N, N, N, N) { @@ -92,3 +91,40 @@ impl Area for [N;4] { #[inline] fn w (&self) -> N { self[2] } #[inline] fn h (&self) -> N { self[3] } } + +#[cfg(test)] mod test_area { + use super::*; + use proptest::prelude::*; + proptest! { + #[test] fn test_area ( + x in u16::MIN..u16::MAX, + y in u16::MIN..u16::MAX, + w in u16::MIN..u16::MAX, + h in u16::MIN..u16::MAX, + a in u16::MIN..u16::MAX, + b in u16::MIN..u16::MAX, + ) { + let _: [u16;4] = <[u16;4] as Area>::zero(); + let _: [u16;4] = <[u16;4] as Area>::from_position([a, b]); + let _: [u16;4] = <[u16;4] as Area>::from_size([a, b]); + let area: [u16;4] = [x, y, w, h]; + let _ = area.expect_min(a, b); + let _ = area.xy(); + let _ = area.wh(); + let _ = area.xywh(); + let _ = area.clip_h(a); + let _ = area.clip_w(b); + let _ = area.clip([a, b]); + let _ = area.set_w(a); + let _ = area.set_h(b); + let _ = area.x2(); + let _ = area.y2(); + let _ = area.lrtb(); + let _ = area.center(); + let _ = area.center_x(a); + let _ = area.center_y(b); + let _ = area.center_xy([a, b]); + let _ = area.centered(); + } + } +} diff --git a/output/src/direction.rs b/output/src/direction.rs new file mode 100644 index 00000000..1fabc193 --- /dev/null +++ b/output/src/direction.rs @@ -0,0 +1,33 @@ +use crate::*; +/// A cardinal direction. +#[derive(Copy, Clone, PartialEq)] +pub enum Direction { North, South, East, West, Above, Below } +impl Direction { + pub fn split_fixed (self, area: impl Area, a: N) -> ([N;4],[N;4]) { + let [x, y, w, h] = area.xywh(); + match self { + North => ([x, y.plus(h).minus(a), w, a], [x, y, w, h.minus(a)]), + South => ([x, y, w, a], [x, y.plus(a), w, h.minus(a)]), + East => ([x, y, a, h], [x.plus(a), y, w.minus(a), h]), + West => ([x.plus(w).minus(a), y, a, h], [x, y, w.minus(a), h]), + Above | Below => (area.xywh(), area.xywh()) + } + } +} +#[cfg(test)] mod test_op_transform { + use super::*; + use proptest::prelude::*; + proptest! { + #[test] fn test_direction ( + x in u16::MIN..u16::MAX, + y in u16::MIN..u16::MAX, + w in u16::MIN..u16::MAX, + h in u16::MIN..u16::MAX, + a in u16::MIN..u16::MAX, + ) { + for d in [North, South, East, West, Above, Below].iter() { + let _ = d.split_fixed([x, y, w, h], a); + } + } + } +} diff --git a/output/src/lib.rs b/output/src/lib.rs index a9565583..3b27b6b6 100644 --- a/output/src/lib.rs +++ b/output/src/lib.rs @@ -1,6 +1,7 @@ //#![feature(lazy_type_alias)] #![feature(type_alias_impl_trait)] #![feature(impl_trait_in_assoc_type)] +mod direction; pub use self::direction::*; mod coordinate; pub use self::coordinate::*; mod size; pub use self::size::*; mod area; pub use self::area::*; diff --git a/output/src/op_bsp.rs b/output/src/op_bsp.rs index cf828ce3..2cd7e395 100644 --- a/output/src/op_bsp.rs +++ b/output/src/op_bsp.rs @@ -1,20 +1,5 @@ use crate::*; -pub use self::Direction::*; -/// A cardinal direction. -#[derive(Copy, Clone, PartialEq)] -pub enum Direction { North, South, East, West, Above, Below } -impl Direction { - pub fn split_fixed (self, area: impl Area, a: N) -> ([N;4],[N;4]) { - let [x, y, w, h] = area.xywh(); - match self { - North => ([x, (y+h).minus(a), w, a], [x, y, w, h.minus(a)]), - South => ([x, y, w, a], [x, y + a, w, h.minus(a)]), - East => ([x, y, a, h], [x + a, y, w.minus(a), h]), - West => ([(x+w).minus(a), y, a, h], [x, y, w - a, h]), - Above | Below => (area.xywh(), area.xywh()) - } - } -} +pub use Direction::*; /// A split or layer. pub struct Bsp(Direction, X, Y); impl, B: Content> Content for Bsp { diff --git a/output/src/size.rs b/output/src/size.rs index ea080d18..c0518d86 100644 --- a/output/src/size.rs +++ b/output/src/size.rs @@ -38,3 +38,26 @@ impl Size for [N;2] { #[inline] fn x (&self) -> N { self[0] } #[inline] fn y (&self) -> N { self[1] } } + +#[cfg(test)] mod test_size { + use super::*; + use proptest::prelude::*; + proptest! { + #[test] fn test_size ( + x in u16::MIN..u16::MAX, + y in u16::MIN..u16::MAX, + a in u16::MIN..u16::MAX, + b in u16::MIN..u16::MAX, + ) { + let size = [x, y]; + let _ = size.w(); + let _ = size.h(); + let _ = size.wh(); + let _ = size.clip_w(a); + let _ = size.clip_h(b); + let _ = size.expect_min(a, b); + let _ = size.to_area_pos(); + let _ = size.to_area_size(); + } + } +}