Diff

Trait Diff 

Source
pub trait Diff {
    // Required method
    fn diff<E: EventQueue>(
        &self,
        baseline: &Self,
        path: PathBuilder,
        event_queue: &mut E,
    );
}
Expand description

Fine-grained parameter diffing.

This trait allows a type to perform diffing on itself, generating events that another instance can use to patch itself.

For more information, see the module docs.

§Examples

For most use cases, Diff is fairly straightforward.

use firewheel_core::diff::{Diff, PathBuilder};

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

let mut params = MyParams {
    a: 1.0,
    b: 1.0,
};

// This "baseline" instance allows us to keep track
// of what's changed over time.
let baseline = params.clone();

// A single mutation to a "leaf" type like `f32` will
// produce a single event.
params.a = 0.5;

// `Vec<NodeEventType>` implements `EventQueue`, meaning we
// don't necessarily need to keep track of `NodeID`s for event generation.
let mut event_queue = Vec::new();
// Top-level calls to diff should always provide a default path builder.
params.diff(&baseline, PathBuilder::default(), &mut event_queue);

assert_eq!(event_queue.len(), 1);

When using Firewheel in a standalone context, the Memo type can simplify this process.

use firewheel_core::diff::Memo;

let mut params_memo = Memo::new(MyParams {
    a: 1.0,
    b: 1.0,
});

// `Memo` implements `DerefMut` on the wrapped type, allowing you
// to use it almost transparently.
params_memo.a = 0.5;

let mut event_queue = Vec::new();
// This generates patches and brings the internally managed
// baseline in sync.
params_memo.update_memo(&mut event_queue);

§Manual implementation

Aggregate types like parameters should prefer the derive macro, but manual implementations can occasionally be handy. You should strive to match the derived data model for maximum compatibility.

use firewheel_core::diff::{Diff, PathBuilder, EventQueue};

impl Diff for MyParams {
    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
        // The diffing data model requires a unique path to each field.
        // Because this type can be arbitrarily nested, you should always
        // extend the provided path builder using `PathBuilder::with`.
        //
        // Because this is the first field, we'll extend the path with 0.
        self.a.diff(&baseline.a, path.with(0), event_queue);
        self.b.diff(&baseline.b, path.with(1), event_queue);
    }
}

You can easily override a type’s Diff implementation by simply doing comparisons by hand.

use firewheel_core::event::ParamData;

impl Diff for MyParams {
    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
        // The above is essentially equivalent to:
        if self.a != baseline.a {
            event_queue.push_param(ParamData::F32(self.a), path.with(0));
        }

        if self.b != baseline.b {
            event_queue.push_param(ParamData::F32(self.b), path.with(1));
        }
    }
}

If your type has invariants between fields that must not be violated, you can consider the whole type a “leaf,” similar to how Diff is implemented on primitives. Depending on the type’s data, you may require an allocation.

impl Diff for MyParams {
    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
        if self != baseline {
            // Note that if we consider the whole type to be a leaf, there
            // is no need to extend the path.
            event_queue.push_param(ParamData::any(self.clone()), path);
        }
    }
}

Required Methods§

Source

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Compare self to baseline and generate events to resolve any differences.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl Diff for Option<EventInstant>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<Volume>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<bool>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<f32>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<f64>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<i8>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<i16>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<i32>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<i64>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<u8>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<u16>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<u32>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<u64>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<DurationMusical>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<DurationSamples>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<DurationSeconds>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<InstantMusical>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<InstantSamples>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<InstantSeconds>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<Vec2>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<Vec3>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<Vec2>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Option<Vec3>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for bool

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for f32

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for f64

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for i8

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for i16

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for i32

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for i64

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for u8

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for u16

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for u32

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for u64

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Vec2

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl Diff for Vec3

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl<A: Diff> Diff for (A,)

Source§

fn diff<EQ: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut EQ, )

Source§

impl<A: Diff, B: Diff> Diff for (A, B)

Source§

fn diff<EQ: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut EQ, )

Source§

impl<A: Diff, B: Diff, C: Diff> Diff for (A, B, C)

Source§

fn diff<EQ: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut EQ, )

Source§

impl<A: Diff, B: Diff, C: Diff, D: Diff> Diff for (A, B, C, D)

Source§

fn diff<EQ: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut EQ, )

Source§

impl<A: Diff, B: Diff, C: Diff, D: Diff, E: Diff> Diff for (A, B, C, D, E)

Source§

fn diff<EQ: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut EQ, )

Source§

impl<A: Diff, B: Diff, C: Diff, D: Diff, E: Diff, F: Diff> Diff for (A, B, C, D, E, F)

Source§

fn diff<EQ: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut EQ, )

Source§

impl<A: Diff, B: Diff, C: Diff, D: Diff, E: Diff, F: Diff, G: Diff> Diff for (A, B, C, D, E, F, G)

Source§

fn diff<EQ: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut EQ, )

Source§

impl<A: Diff, B: Diff, C: Diff, D: Diff, E: Diff, F: Diff, G: Diff, H: Diff> Diff for (A, B, C, D, E, F, G, H)

Source§

fn diff<EQ: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut EQ, )

Source§

impl<T: Send + Sync + RealtimeClone + PartialEq + 'static> Diff for Option<T>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl<T: Diff> Diff for [T]

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

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

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

impl<T: Diff> Diff for Vec<T>

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Source§

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

Source§

fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )

Implementors§