From e0429865cf9be48f55b2fab201591b924de81f4c Mon Sep 17 00:00:00 2001 From: Austin Hicks Date: Thu, 19 Dec 2024 11:50:25 -0800 Subject: [PATCH] Get rid of tick1 --- crates/synthizer/src/chain_mathops.rs | 15 ---------- crates/synthizer/src/core_traits.rs | 28 ++++--------------- crates/synthizer/src/signals/and_then.rs | 16 ----------- crates/synthizer/src/signals/audio_io.rs | 16 ----------- crates/synthizer/src/signals/consume_input.rs | 9 ------ crates/synthizer/src/signals/conversion.rs | 11 -------- crates/synthizer/src/signals/map.rs | 13 --------- crates/synthizer/src/signals/null.rs | 21 ++++++++++---- crates/synthizer/src/signals/periodic_f64.rs | 17 ----------- crates/synthizer/src/signals/scalars.rs | 20 +++++++++---- crates/synthizer/src/signals/slots.rs | 11 -------- crates/synthizer/src/signals/trig.rs | 8 ------ 12 files changed, 35 insertions(+), 150 deletions(-) diff --git a/crates/synthizer/src/chain_mathops.rs b/crates/synthizer/src/chain_mathops.rs index f0b08b2..eb1cec4 100644 --- a/crates/synthizer/src/chain_mathops.rs +++ b/crates/synthizer/src/chain_mathops.rs @@ -42,21 +42,6 @@ macro_rules! impl_mathop { type Parameters = (SignalParameters, SignalParameters); type State = (SignalState, SignalState); - fn tick1>( - ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - input: &'_ Self::Input, - destination: D, - ) { - // The complexity here is that we cannot project the context twice. We need the left value first. - let mut left = None; - S1::tick1(&mut ctx.wrap(|s| &mut s.0, |p| &p.0), input, |y| { - left = Some(y) - }); - S2::tick1(&mut ctx.wrap(|s| &mut s.1, |p| &p.1), input, |y| { - destination.send(left.unwrap().$method(y)); - }) - } - fn on_block_start( ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, ) { diff --git a/crates/synthizer/src/core_traits.rs b/crates/synthizer/src/core_traits.rs index f91392e..508dc10 100644 --- a/crates/synthizer/src/core_traits.rs +++ b/crates/synthizer/src/core_traits.rs @@ -1,7 +1,6 @@ use std::any::Any; use std::sync::Arc; -use crate::config; use crate::context::*; use crate::error::Result; use crate::unique_id::UniqueId; @@ -13,25 +12,15 @@ pub(crate) mod sealed { /// /// # Safety /// - /// This trait is unsafe because the library relies on it to uphold the contracts documented with the method. In - /// particular, calling `tick1` must always send exactly one value to the destination, as the destination may be - /// writing into uninitialized memory. This lets us get performance out, especially in debug builds where things - /// like immediate unwrapping of options will not be optimized away. + /// This trait is unsafe because the library relies on it to uphold the contracts documented with the method. This + /// lets us get performance out, especially in debug builds where things like immediate unwrapping of options will + /// not be optimized away. pub unsafe trait Signal: Sized + Send + Sync { type Input: Sized; type Output: Sized; type State: Sized + Send + Sync; type Parameters: Sized + Send + Sync; - /// Tick this signal once. - /// - /// Must use the destination to send exactly one value. - fn tick1>( - ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - input: &'_ Self::Input, - destination: D, - ); - /// Tick this signal [config::BLOCK_SIZE] times. Implemented via `tick1` by default. /// /// The default implementation is only suitable for signals which are "endpoints" e.g. signals that produce @@ -50,15 +39,10 @@ pub(crate) mod sealed { D: ReusableSignalDestination, >( ctx: &'_ mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - mut input: I, - mut destination: D, + input: I, + destination: D, ) where - Self::Input: 'a, - { - for i in 0..config::BLOCK_SIZE { - Self::tick1(ctx, input(i), |x| destination.send_reusable(x)); - } - } + Self::Input: 'a; /// Called when a signal is starting a new block. /// diff --git a/crates/synthizer/src/signals/and_then.rs b/crates/synthizer/src/signals/and_then.rs index 636ca68..ee47dab 100644 --- a/crates/synthizer/src/signals/and_then.rs +++ b/crates/synthizer/src/signals/and_then.rs @@ -22,22 +22,6 @@ where type State = (S1::State, S2::State); type Parameters = (S1::Parameters, S2::Parameters); - fn tick1>( - ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - input: &'_ Self::Input, - destination: D, - ) { - // LLVM should be able to see through this. Not that that's guaranteed, but it avoids wild unsafety. - let mut left: Option = None; - - S1::tick1(&mut ctx.wrap(|s| &mut s.0, |p| &p.0), input, |x| { - left = Some(x) - }); - let left = left.unwrap(); - - S2::tick1(&mut ctx.wrap(|s| &mut s.1, |p| &p.1), &left, destination); - } - fn on_block_start(ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>) { S1::on_block_start(&mut ctx.wrap(|s| &mut s.0, |p| &p.0)); S2::on_block_start(&mut ctx.wrap(|s| &mut s.1, |p| &p.1)); diff --git a/crates/synthizer/src/signals/audio_io.rs b/crates/synthizer/src/signals/audio_io.rs index 01b42f9..70a6d7c 100644 --- a/crates/synthizer/src/signals/audio_io.rs +++ b/crates/synthizer/src/signals/audio_io.rs @@ -15,22 +15,6 @@ where type State = (S::State, usize); type Parameters = S::Parameters; - fn tick1>( - ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - input: &'_ Self::Input, - destination: D, - ) { - let mut val: Option = None; - S::tick1(&mut ctx.wrap(|s| &mut s.0, |p| p), input, |x| val = Some(x)); - - // We output the unit type instead. - destination.send(()); - - // Later this will go to a bus. But we are not at buses yet. - ctx.fixed.audio_destinationh[ctx.state.1] = val.unwrap(); - ctx.state.1 += 1; - } - fn on_block_start(ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>) { S::on_block_start(&mut ctx.wrap(|s| &mut s.0, |p| p)); diff --git a/crates/synthizer/src/signals/consume_input.rs b/crates/synthizer/src/signals/consume_input.rs index 2dd86c9..9d026c6 100644 --- a/crates/synthizer/src/signals/consume_input.rs +++ b/crates/synthizer/src/signals/consume_input.rs @@ -32,15 +32,6 @@ where type State = S::State; type Parameters = S::Parameters; - fn tick1>( - ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - _input: &'_ Self::Input, - destination: D, - ) { - let new_in: S::Input = Default::default(); - S::tick1(ctx, &new_in, destination); - } - fn on_block_start(ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>) { S::on_block_start(ctx); } diff --git a/crates/synthizer/src/signals/conversion.rs b/crates/synthizer/src/signals/conversion.rs index ce173b0..733fb5b 100644 --- a/crates/synthizer/src/signals/conversion.rs +++ b/crates/synthizer/src/signals/conversion.rs @@ -32,17 +32,6 @@ where type Parameters = Sig::Parameters; type State = Sig::State; - fn tick1>( - ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - input: &'_ Self::Input, - destination: D, - ) { - Sig::tick1(ctx, input, |x: Sig::Output| { - let y: DType = x.into(); - destination.send(y) - }) - } - fn on_block_start(ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>) { Sig::on_block_start(ctx); } diff --git a/crates/synthizer/src/signals/map.rs b/crates/synthizer/src/signals/map.rs index b25579a..53cc7dc 100644 --- a/crates/synthizer/src/signals/map.rs +++ b/crates/synthizer/src/signals/map.rs @@ -37,19 +37,6 @@ where ParSig::on_block_start(&mut ctx.wrap(|s| &mut s.parent_state, |p| p)); } - fn tick1>( - ctx: &mut crate::context::SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - input: &'_ Self::Input, - destination: D, - ) { - let mut par_in = MaybeUninit::uninit(); - ParSig::tick1(&mut ctx.wrap(|s| &mut s.parent_state, |p| p), input, |x| { - par_in.write(x); - }); - - destination.send((ctx.state.closure)(unsafe { par_in.assume_init_ref() })); - } - fn tick_block< 'a, I: FnMut(usize) -> &'a Self::Input, diff --git a/crates/synthizer/src/signals/null.rs b/crates/synthizer/src/signals/null.rs index 0db0a19..b206ace 100644 --- a/crates/synthizer/src/signals/null.rs +++ b/crates/synthizer/src/signals/null.rs @@ -13,12 +13,21 @@ unsafe impl Signal for NullSignal { type State = (); type Parameters = (); - fn tick1>( - _ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - _input: &'_ Self::Input, - destination: D, - ) { - destination.send(()); + fn tick_block< + 'a, + I: FnMut(usize) -> &'a Self::Input, + D: ReusableSignalDestination, + >( + _ctx: &'_ mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, + mut input: I, + mut destination: D, + ) where + Self::Input: 'a, + { + for i in 0..crate::config::BLOCK_SIZE { + input(i); + destination.send_reusable(()); + } } fn on_block_start(_ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>) {} diff --git a/crates/synthizer/src/signals/periodic_f64.rs b/crates/synthizer/src/signals/periodic_f64.rs index cc3d8d9..6ad634f 100644 --- a/crates/synthizer/src/signals/periodic_f64.rs +++ b/crates/synthizer/src/signals/periodic_f64.rs @@ -45,23 +45,6 @@ where type State = PeriodicF64State; type Parameters = PeriodicF64Parameters; - fn tick1>( - ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - input: &'_ Self::Input, - destination: D, - ) { - let mut parent: f64 = 0.0; - SIncr::tick1( - &mut ctx.wrap(|s| &mut s.freq_state, |p| &p.freq_params), - input, - |incr| { - parent = incr; - }, - ); - - destination.send(inc1(ctx.state, ctx.parameters, parent)); - } - fn on_block_start(ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>) { SIncr::on_block_start(&mut ctx.wrap(|s| &mut s.freq_state, |p| &p.freq_params)); } diff --git a/crates/synthizer/src/signals/scalars.rs b/crates/synthizer/src/signals/scalars.rs index 473a47a..e36fa3d 100644 --- a/crates/synthizer/src/signals/scalars.rs +++ b/crates/synthizer/src/signals/scalars.rs @@ -14,12 +14,20 @@ macro_rules! impl_scalar { type State = (); type Parameters = $t; - fn tick1>( - ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - _input: &'_ Self::Input, - destination: D, - ) { - destination.send(*ctx.parameters); + fn tick_block< + 'a, + I: FnMut(usize) -> &'a Self::Input, + D: ReusableSignalDestination, + >( + ctx: &'_ mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, + mut input: I, +mut destination: D, + ) where + Self::Input: 'a { + for i in 0..crate::config::BLOCK_SIZE { + input(i); + destination.send_reusable(*ctx.parameters); + } } fn on_block_start(_ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>) {} diff --git a/crates/synthizer/src/signals/slots.rs b/crates/synthizer/src/signals/slots.rs index f626dac..651dbfc 100644 --- a/crates/synthizer/src/signals/slots.rs +++ b/crates/synthizer/src/signals/slots.rs @@ -151,17 +151,6 @@ where ctx.state.changed_this_block = true; } - fn tick1>( - ctx: &mut crate::context::SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - _input: &'_ Self::Input, - destination: D, - ) { - destination.send(SlotSignalOutput { - value: (*ctx.state.value).clone(), - changed_this_block: ctx.state.changed_this_block, - }); - } - fn tick_block< 'a, I: FnMut(usize) -> &'a Self::Input, diff --git a/crates/synthizer/src/signals/trig.rs b/crates/synthizer/src/signals/trig.rs index 6aa8904..75551c7 100644 --- a/crates/synthizer/src/signals/trig.rs +++ b/crates/synthizer/src/signals/trig.rs @@ -16,14 +16,6 @@ where type State = S::State; type Parameters = S::Parameters; - fn tick1>( - ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>, - input: &'_ Self::Input, - destination: D, - ) { - S::tick1(ctx, input, |x: f64| destination.send(x.sin())); - } - fn on_block_start(ctx: &mut SignalExecutionContext<'_, '_, Self::State, Self::Parameters>) { S::on_block_start(ctx); }