Trait Patch

Source
pub trait Patch {
    // Required method
    fn patch(
        &mut self,
        data: &ParamData,
        path: &[u32],
    ) -> Result<(), PatchError>;

    // Provided methods
    fn patch_event(&mut self, event: &NodeEventType) -> bool { ... }
    fn patch_list(&mut self, event_list: NodeEventList<'_>) -> bool { ... }
}
Expand description

Fine-grained parameter patching.

This trait allows a type to perform patching on itself, applying patches generated from another instance.

For more information, see the module docs.

§Examples

Like with Diff, the typical Patch usage is simple.

use firewheel_core::{diff::Patch, event::*, node::*};

#[derive(Patch)]
struct MyParams {
    a: f32,
    b: f32,
}

struct MyProcessor {
    params: MyParams,
}

impl AudioNodeProcessor for MyProcessor {
    fn process(
        &mut self,
        inputs: &[&[f32]],
        outputs: &mut [&mut [f32]],
        events: NodeEventList,
        proc_info: &ProcInfo,
        scratch_buffers: ScratchBuffers,
    ) -> ProcessStatus {
        // Synchronize `params` from the event list.
        self.params.patch_list(events);

        // ...

        ProcessStatus::outputs_not_silent()
    }
}

Patch::patch_list is a convenience trait method that takes a NodeEventList by value, applies any parameter patches that may be present, and returns a boolean indicating whether any parameters have changed.

If you need finer access to the event list, you can apply patches more directly.

impl AudioNodeProcessor for MyProcessor {
    fn process(
        &mut self,
        inputs: &[&[f32]],
        outputs: &mut [&mut [f32]],
        mut events: NodeEventList,
        proc_info: &ProcInfo,
        scratch_buffers: ScratchBuffers,
    ) -> ProcessStatus {
        events.for_each(|e| {
            // You can take the whole event, which may
            // or may not actually contain a parameter:
            self.params.patch_event(e);

            // Or match on the event and provide
            // each element directly:
            match e {
                NodeEventType::Param { data, path } => {
                    // This allows you to handle errors as well.
                    let _ = self.params.patch(data, &path);
                }
                _ => {}
            }
        });

        // ...

        ProcessStatus::outputs_not_silent()
    }
}

§Manual implementation

Like with Diff, types like parameters should prefer the Patch derive macro. Nonetheless, Firewheel provides a few tools to make manual implementations easy.

use firewheel_core::{diff::{Patch, PatchError}, event::ParamData};

struct MyParams {
    a: f32,
    b: (bool, bool)
}

impl Patch for MyParams {
    fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError> {
        match path {
            [0] => {
                // You can defer to `f32`'s `Patch` implementation, or simply
                // apply the data directly like we do here.
                self.a = data.try_into()?;

                Ok(())
            }
            // Shortening the path slice one element at a time as we descend the tree
            // allows nested types to see the path as they expect it.
            [1, tail @ ..] => {
                self.b.patch(data, tail)
            }
            _ => Err(PatchError::InvalidPath)
        }
    }
}

Required Methods§

Source

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Patch self according to the incoming data. This will generally be called from within the audio thread.

data is intentionally made a shared reference. This should make accidental syscalls due to additional allocations or drops more difficult. If you find yourself reaching for interior mutability, consider whether you’re building realtime-appropriate behavior.

Provided Methods§

Source

fn patch_event(&mut self, event: &NodeEventType) -> bool

Patch a set of parameters with incoming events.

Returns true if any parameters have changed.

This is useful as a convenience method for extracting the path and data components from a NodeEventType. Errors produced here are ignored.

Source

fn patch_list(&mut self, event_list: NodeEventList<'_>) -> bool

Patch a set of parameters with a list of incoming events.

Returns true if any parameters have changed.

This is useful as a convenience method for patching parameters directly from a NodeEventList. Errors produced here are ignored.

Implementations on Foreign Types§

Source§

impl Patch for bool

Source§

fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError>

Source§

impl Patch for f32

Source§

fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError>

Source§

impl Patch for f64

Source§

fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError>

Source§

impl Patch for i8

Source§

fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError>

Source§

impl Patch for i16

Source§

fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError>

Source§

impl Patch for i32

Source§

fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError>

Source§

impl Patch for i64

Source§

fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError>

Source§

impl Patch for u8

Source§

fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError>

Source§

impl Patch for u16

Source§

fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError>

Source§

impl Patch for u32

Source§

fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError>

Source§

impl Patch for u64

Source§

fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError>

Source§

impl Patch for ()

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<A0: Patch> Patch for (A0,)

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<A0: Patch, B0: Patch> Patch for (A0, B0)

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<A0: Patch, B0: Patch, C0: Patch> Patch for (A0, B0, C0)

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<A0: Patch, B0: Patch, C0: Patch, D0: Patch> Patch for (A0, B0, C0, D0)

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<A0: Patch, B0: Patch, C0: Patch, D0: Patch, E0: Patch> Patch for (A0, B0, C0, D0, E0)

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<A0: Patch, B0: Patch, C0: Patch, D0: Patch, E0: Patch, F0: Patch> Patch for (A0, B0, C0, D0, E0, F0)

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<A0: Patch, B0: Patch, C0: Patch, D0: Patch, E0: Patch, F0: Patch, G0: Patch> Patch for (A0, B0, C0, D0, E0, F0, G0)

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<A0: Patch, B0: Patch, C0: Patch, D0: Patch, E0: Patch, F0: Patch, G0: Patch, H0: Patch> Patch for (A0, B0, C0, D0, E0, F0, G0, H0)

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<T: Patch> Patch for [T]

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<T: Patch> Patch for Box<[T]>

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<T: Patch> Patch for Vec<T>

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Source§

impl<T: Patch, const LEN: usize> Patch for [T; LEN]

Source§

fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError>

Implementors§

Source§

impl Patch for PanLaw

Source§

impl Patch for Volume

Source§

impl Patch for Vec2

Source§

impl Patch for Vec3

Source§

impl<A: ?Sized + Send + Sync + 'static> Patch for ArcGc<A>