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§
Sourcefn diff<E: EventQueue>(
&self,
baseline: &Self,
path: PathBuilder,
event_queue: &mut E,
)
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>
Available on crate feature scheduled_events only.
impl Diff for Option<EventInstant>
scheduled_events only.fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<Volume>
impl Diff for Option<Volume>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<bool>
impl Diff for Option<bool>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<f32>
impl Diff for Option<f32>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<f64>
impl Diff for Option<f64>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<i8>
impl Diff for Option<i8>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<i16>
impl Diff for Option<i16>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<i32>
impl Diff for Option<i32>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<i64>
impl Diff for Option<i64>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<isize>
impl Diff for Option<isize>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<u8>
impl Diff for Option<u8>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<u16>
impl Diff for Option<u16>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<u32>
impl Diff for Option<u32>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<u64>
impl Diff for Option<u64>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<usize>
impl Diff for Option<usize>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<DurationMusical>
impl Diff for Option<DurationMusical>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<DurationSamples>
impl Diff for Option<DurationSamples>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<DurationSeconds>
impl Diff for Option<DurationSeconds>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<InstantMusical>
impl Diff for Option<InstantMusical>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<InstantSamples>
impl Diff for Option<InstantSamples>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<InstantSeconds>
impl Diff for Option<InstantSeconds>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<Vec2>
impl Diff for Option<Vec2>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<Vec3>
impl Diff for Option<Vec3>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<Vec2>
impl Diff for Option<Vec2>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<Vec2>
impl Diff for Option<Vec2>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<Vec3>
impl Diff for Option<Vec3>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Option<Vec3>
impl Diff for Option<Vec3>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for bool
impl Diff for bool
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for f32
impl Diff for f32
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for f64
impl Diff for f64
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for i8
impl Diff for i8
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for i16
impl Diff for i16
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for i32
impl Diff for i32
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for i64
impl Diff for i64
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for isize
impl Diff for isize
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for u8
impl Diff for u8
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for u16
impl Diff for u16
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for u32
impl Diff for u32
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for u64
impl Diff for u64
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for usize
impl Diff for usize
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Vec2
impl Diff for Vec2
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Vec2
impl Diff for Vec2
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Vec3
impl Diff for Vec3
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl Diff for Vec3
impl Diff for Vec3
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl<A: Diff> Diff for (A,)
impl<A: Diff> Diff for (A,)
fn diff<EQ: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut EQ, )
Source§impl<A: Diff, B: Diff> Diff for (A, B)
impl<A: Diff, B: Diff> Diff for (A, B)
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)
impl<A: Diff, B: Diff, C: Diff> Diff for (A, B, C)
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)
impl<A: Diff, B: Diff, C: Diff, D: Diff> Diff for (A, B, C, D)
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)
impl<A: Diff, B: Diff, C: Diff, D: Diff, E: Diff> Diff for (A, B, C, D, E)
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)
impl<A: Diff, B: Diff, C: Diff, D: Diff, E: Diff, F: Diff> Diff for (A, B, C, D, E, F)
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)
impl<A: Diff, B: Diff, C: Diff, D: Diff, E: Diff, F: Diff, G: Diff> Diff for (A, B, C, D, E, F, G)
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)
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)
fn diff<EQ: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut EQ, )
Source§impl<A: ?Sized + Send + Sync + 'static> Diff for ArcGc<A>
impl<A: ?Sized + Send + Sync + 'static> Diff for ArcGc<A>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl<T: Send + Sync + RealtimeClone + PartialEq + 'static> Diff for Option<T>
impl<T: Send + Sync + RealtimeClone + PartialEq + 'static> Diff for Option<T>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl<T: Diff> Diff for [T]
impl<T: Diff> Diff for [T]
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl<T: Diff> Diff for Box<[T]>
impl<T: Diff> Diff for Box<[T]>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl<T: Diff> Diff for Vec<T>
impl<T: Diff> Diff for Vec<T>
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Source§impl<T: Diff, const LEN: usize> Diff for [T; LEN]
impl<T: Diff, const LEN: usize> Diff for [T; LEN]
fn diff<E: EventQueue>( &self, baseline: &Self, path: PathBuilder, event_queue: &mut E, )
Implementors§
impl Diff for EventInstant
scheduled_events only.