firewheel_core/diff/
leaf.rs

1//! A set of diff and patch implementations for common leaf types.
2
3use super::{Diff, EventQueue, Patch, PatchError, PathBuilder};
4use crate::{
5    clock::{DurationSamples, DurationSeconds, InstantSamples, InstantSeconds},
6    collector::ArcGc,
7    diff::{Notify, RealtimeClone},
8    dsp::volume::Volume,
9    event::{NodeEventType, ParamData},
10    vector::{Vec2, Vec3},
11};
12
13#[cfg(feature = "musical_transport")]
14use crate::clock::{DurationMusical, InstantMusical};
15
16macro_rules! primitive_diff {
17    ($ty:ty, $variant:ident) => {
18        impl Diff for $ty {
19            fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
20                if self != baseline {
21                    event_queue.push_param(*self, path);
22                }
23            }
24        }
25
26        impl Patch for $ty {
27            type Patch = Self;
28
29            fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
30                match data {
31                    ParamData::$variant(value) => Ok((*value).into()),
32                    _ => Err(PatchError::InvalidData),
33                }
34            }
35
36            fn apply(&mut self, value: Self::Patch) {
37                *self = value;
38            }
39        }
40
41        impl Diff for Option<$ty> {
42            fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
43                if self != baseline {
44                    event_queue.push_param(*self, path);
45                }
46            }
47        }
48
49        impl Patch for Option<$ty> {
50            type Patch = Self;
51
52            fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
53                match data {
54                    ParamData::$variant(value) => Ok(Some((*value).into())),
55                    ParamData::None => Ok(None),
56                    _ => Err(PatchError::InvalidData),
57                }
58            }
59
60            fn apply(&mut self, value: Self::Patch) {
61                *self = value;
62            }
63        }
64    };
65
66    ($ty:ty, $cast:ty, $variant:ident) => {
67        impl Diff for $ty {
68            fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
69                if self != baseline {
70                    event_queue.push_param(*self as $cast, path);
71                }
72            }
73        }
74
75        impl Patch for $ty {
76            type Patch = Self;
77
78            fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
79                match data {
80                    ParamData::$variant(value) => Ok(value.clone() as $ty),
81                    _ => Err(PatchError::InvalidData),
82                }
83            }
84
85            fn apply(&mut self, value: Self::Patch) {
86                *self = value;
87            }
88        }
89
90        impl Diff for Option<$ty> {
91            fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
92                if self != baseline {
93                    event_queue.push_param(self.map(|v| v as $cast), path);
94                }
95            }
96        }
97
98        impl Patch for Option<$ty> {
99            type Patch = Self;
100
101            fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
102                match data {
103                    ParamData::$variant(value) => Ok(Some(value.clone() as $ty)),
104                    ParamData::None => Ok(None),
105                    _ => Err(PatchError::InvalidData),
106                }
107            }
108
109            fn apply(&mut self, value: Self::Patch) {
110                *self = value;
111            }
112        }
113    };
114}
115
116primitive_diff!(bool, Bool);
117primitive_diff!(u8, u32, U32);
118primitive_diff!(u16, u32, U32);
119primitive_diff!(u32, U32);
120primitive_diff!(u64, U64);
121primitive_diff!(i8, i32, I32);
122primitive_diff!(i16, i32, I32);
123primitive_diff!(i32, I32);
124primitive_diff!(i64, I64);
125primitive_diff!(usize, u64, U64);
126primitive_diff!(isize, i64, I64);
127primitive_diff!(f32, F32);
128primitive_diff!(f64, F64);
129primitive_diff!(Volume, Volume);
130primitive_diff!(InstantSamples, InstantSamples);
131primitive_diff!(DurationSamples, DurationSamples);
132primitive_diff!(InstantSeconds, InstantSeconds);
133primitive_diff!(DurationSeconds, DurationSeconds);
134
135#[cfg(feature = "musical_transport")]
136primitive_diff!(InstantMusical, InstantMusical);
137#[cfg(feature = "musical_transport")]
138primitive_diff!(DurationMusical, DurationMusical);
139
140primitive_diff!(Vec2, Vector2D);
141primitive_diff!(Vec3, Vector3D);
142
143#[cfg(feature = "glam-29")]
144primitive_diff!(glam_29::Vec2, Vector2D);
145#[cfg(feature = "glam-29")]
146primitive_diff!(glam_29::Vec3, Vector3D);
147
148#[cfg(feature = "glam-30")]
149primitive_diff!(glam_30::Vec2, Vector2D);
150#[cfg(feature = "glam-30")]
151primitive_diff!(glam_30::Vec3, Vector3D);
152
153impl<A: ?Sized + Send + Sync + 'static> Diff for ArcGc<A> {
154    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
155        if !ArcGc::ptr_eq(self, baseline) {
156            event_queue.push(NodeEventType::Param {
157                data: ParamData::any(self.clone()),
158                path: path.build(),
159            });
160        }
161    }
162}
163
164impl<A: ?Sized + Send + Sync + 'static> Patch for ArcGc<A> {
165    type Patch = Self;
166
167    fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
168        if let ParamData::Any(any) = data {
169            if let Some(data) = any.downcast_ref::<Self>() {
170                return Ok(data.clone());
171            }
172        }
173
174        Err(PatchError::InvalidData)
175    }
176
177    fn apply(&mut self, patch: Self::Patch) {
178        *self = patch;
179    }
180}
181
182impl<T: Send + Sync + RealtimeClone + PartialEq + 'static> Diff for Option<T> {
183    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
184        if self != baseline {
185            event_queue.push_param(ParamData::opt_any(self.clone()), path);
186        }
187    }
188}
189
190impl<T: Send + Sync + RealtimeClone + PartialEq + 'static> Patch for Option<T> {
191    type Patch = Self;
192
193    fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
194        Ok(data.downcast_ref::<T>().cloned())
195    }
196
197    fn apply(&mut self, patch: Self::Patch) {
198        *self = patch;
199    }
200}
201
202// Here we specialize the `Notify` implementations since most
203// primitives can have some number of optimizations applied.
204impl Diff for Notify<()> {
205    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
206        if self != baseline {
207            event_queue.push_param(ParamData::U64(self.id()), path);
208        }
209    }
210}
211
212impl Patch for Notify<()> {
213    type Patch = Self;
214
215    fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
216        match data {
217            ParamData::U64(counter) => Ok(Notify::from_raw((), *counter)),
218            _ => Err(PatchError::InvalidData),
219        }
220    }
221
222    fn apply(&mut self, value: Self::Patch) {
223        *self = value;
224    }
225}
226
227impl Diff for Notify<bool> {
228    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
229        if self != baseline {
230            event_queue.push_param(ParamData::U64(self.id()), path.with(**self as u32));
231        }
232    }
233}
234
235impl Patch for Notify<bool> {
236    type Patch = Self;
237
238    fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
239        let value = match path.first() {
240            Some(0) => false,
241            Some(1) => true,
242            _ => return Err(PatchError::InvalidData),
243        };
244
245        match data {
246            ParamData::U64(counter) => Ok(Notify::from_raw(value, *counter)),
247            _ => Err(PatchError::InvalidData),
248        }
249    }
250
251    fn apply(&mut self, value: Self::Patch) {
252        *self = value;
253    }
254}
255
256impl Diff for Notify<i8> {
257    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
258        if self != baseline {
259            event_queue.push_param(ParamData::U64(self.id()), path.with(**self as i32 as u32));
260        }
261    }
262}
263
264impl Patch for Notify<i8> {
265    type Patch = Self;
266
267    fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
268        let value = (*path.first().ok_or(PatchError::InvalidData)?) as i8;
269
270        match data {
271            ParamData::U64(counter) => Ok(Notify::from_raw(value, *counter)),
272            _ => Err(PatchError::InvalidData),
273        }
274    }
275
276    fn apply(&mut self, value: Self::Patch) {
277        *self = value;
278    }
279}
280
281impl Diff for Notify<i16> {
282    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
283        if self != baseline {
284            event_queue.push_param(ParamData::U64(self.id()), path.with(**self as i32 as u32));
285        }
286    }
287}
288
289impl Patch for Notify<i16> {
290    type Patch = Self;
291
292    fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
293        let value = (*path.first().ok_or(PatchError::InvalidData)?) as i16;
294
295        match data {
296            ParamData::U64(counter) => Ok(Notify::from_raw(value, *counter)),
297            _ => Err(PatchError::InvalidData),
298        }
299    }
300
301    fn apply(&mut self, value: Self::Patch) {
302        *self = value;
303    }
304}
305
306impl Diff for Notify<i32> {
307    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
308        if self != baseline {
309            event_queue.push_param(ParamData::U64(self.id()), path.with(**self as u32));
310        }
311    }
312}
313
314impl Patch for Notify<i32> {
315    type Patch = Self;
316
317    fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
318        let value = (*path.first().ok_or(PatchError::InvalidData)?) as i32;
319
320        match data {
321            ParamData::U64(counter) => Ok(Notify::from_raw(value, *counter)),
322            _ => Err(PatchError::InvalidData),
323        }
324    }
325
326    fn apply(&mut self, value: Self::Patch) {
327        *self = value;
328    }
329}
330
331impl Diff for Notify<u8> {
332    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
333        if self != baseline {
334            event_queue.push_param(ParamData::U64(self.id()), path.with(**self as u32));
335        }
336    }
337}
338
339impl Patch for Notify<u8> {
340    type Patch = Self;
341
342    fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
343        let value = (*path.first().ok_or(PatchError::InvalidData)?) as u8;
344
345        match data {
346            ParamData::U64(counter) => Ok(Notify::from_raw(value, *counter)),
347            _ => Err(PatchError::InvalidData),
348        }
349    }
350
351    fn apply(&mut self, value: Self::Patch) {
352        *self = value;
353    }
354}
355
356impl Diff for Notify<u16> {
357    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
358        if self != baseline {
359            event_queue.push_param(ParamData::U64(self.id()), path.with(**self as u32));
360        }
361    }
362}
363
364impl Patch for Notify<u16> {
365    type Patch = Self;
366
367    fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
368        let value = (*path.first().ok_or(PatchError::InvalidData)?) as u16;
369
370        match data {
371            ParamData::U64(counter) => Ok(Notify::from_raw(value, *counter)),
372            _ => Err(PatchError::InvalidData),
373        }
374    }
375
376    fn apply(&mut self, value: Self::Patch) {
377        *self = value;
378    }
379}
380
381impl Diff for Notify<u32> {
382    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
383        if self != baseline {
384            event_queue.push_param(ParamData::U64(self.id()), path.with(**self));
385        }
386    }
387}
388
389impl Patch for Notify<u32> {
390    type Patch = Self;
391
392    fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
393        let value = *path.first().ok_or(PatchError::InvalidData)?;
394
395        match data {
396            ParamData::U64(counter) => Ok(Notify::from_raw(value, *counter)),
397            _ => Err(PatchError::InvalidData),
398        }
399    }
400
401    fn apply(&mut self, value: Self::Patch) {
402        *self = value;
403    }
404}
405
406impl Diff for Notify<f32> {
407    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
408        if self != baseline {
409            let value: f32 = **self;
410            event_queue.push_param(ParamData::U64(self.id()), path.with(value.to_bits()));
411        }
412    }
413}
414
415impl Patch for Notify<f32> {
416    type Patch = Self;
417
418    fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
419        let value = *path.first().ok_or(PatchError::InvalidData)?;
420
421        match data {
422            ParamData::U64(counter) => Ok(Notify::from_raw(f32::from_bits(value), *counter)),
423            _ => Err(PatchError::InvalidData),
424        }
425    }
426
427    fn apply(&mut self, value: Self::Patch) {
428        *self = value;
429    }
430}
431
432macro_rules! trivial_notify {
433    ($ty:path) => {
434        impl Diff for Notify<$ty> {
435            fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
436                if self != baseline {
437                    event_queue.push_param(ParamData::any(self.clone()), path);
438                }
439            }
440        }
441
442        impl Patch for Notify<$ty> {
443            type Patch = Self;
444
445            fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
446                data.downcast_ref()
447                    .ok_or(super::PatchError::InvalidData)
448                    .cloned()
449            }
450
451            fn apply(&mut self, value: Self::Patch) {
452                *self = value;
453            }
454        }
455    };
456}
457
458// No good optimizations possible for these large values.
459trivial_notify!(f64);
460trivial_notify!(i64);
461trivial_notify!(u64);
462
463trivial_notify!(Volume);
464trivial_notify!(InstantSamples);
465trivial_notify!(DurationSamples);
466trivial_notify!(InstantSeconds);
467trivial_notify!(DurationSeconds);
468
469#[cfg(feature = "musical_transport")]
470trivial_notify!(InstantMusical);
471#[cfg(feature = "musical_transport")]
472trivial_notify!(DurationMusical);
473
474trivial_notify!(Vec2);
475trivial_notify!(Vec3);
476
477#[cfg(feature = "glam-29")]
478trivial_notify!(glam_29::Vec2);
479#[cfg(feature = "glam-29")]
480trivial_notify!(glam_29::Vec3);
481
482#[cfg(feature = "glam-30")]
483trivial_notify!(glam_30::Vec2);
484#[cfg(feature = "glam-30")]
485trivial_notify!(glam_30::Vec3);