1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
//! Traits and derive macros for diffing and patching.
//!
//! _Diffing_ is the process of comparing a piece of data to some
//! baseline and generating events to describe the differences.
//! _Patching_ takes these events and applies them to another
//! instance of this data. The [`Diff`] and [`Patch`] traits facilitate _fine-grained_
//! event generation, meaning they'll generate events for
//! only what's changed.
//!
//! In typical usage, [`Diff`] will be called in non-realtime contexts
//! like game logic, whereas [`Patch`] will be called directly within
//! audio processors. Consequently, [`Patch`] has been optimized for
//! maximum performance and realtime predictability.
//!
//! [`Diff`] and [`Patch`] are [derivable](https://doc.rust-lang.org/book/appendix-03-derivable-traits.html),
//! and most aggregate types should prefer the derive macros over
//! manual implementations since the diffing data model is not
//! yet guaranteed to be stable.
//!
//! # Examples
//!
//! Aggregate types like node parameters can derive
//! [`Diff`] and [`Patch`] as long as each field also
//! implements these traits.
//!
//! ```
//! use firewheel_core::diff::{Diff, Patch};
//!
//! #[derive(Diff, Patch)]
//! struct MyParams {
//! a: f32,
//! b: (bool, bool),
//! }
//! ```
//!
//! The derived implementation produces fine-grained
//! events, making it easy to keep your audio processors in sync
//! with the rest of your code with minimal overhead.
//!
//! ```
//! # use firewheel_core::diff::{Diff, Patch, PathBuilder};
//! # #[derive(Diff, Patch, Clone, PartialEq, Debug)]
//! # struct MyParams {
//! # a: f32,
//! # b: (bool, bool),
//! # }
//! let mut params = MyParams {
//! a: 1.0,
//! b: (false, false),
//! };
//! let mut baseline = params.clone();
//!
//! // A change to any arbitrarily nested parameter
//! // will produce a single event.
//! params.b.0 = true;
//!
//! let mut event_queue = Vec::new();
//! params.diff(&baseline, PathBuilder::default(), &mut event_queue);
//!
//! // When we apply this patch to another instance of
//! // the same type, it will be brought in sync.
//! baseline.apply(MyParams::patch_event(&event_queue[0]).unwrap());
//! assert_eq!(params, baseline);
//!
//! ```
//!
//! Both traits can also be derived on enums.
//!
//! ```
//! # use firewheel_core::diff::{Diff, Patch, PathBuilder};
//! #[derive(Diff, Patch, Clone, PartialEq)]
//! enum MyParams {
//! Unit,
//! Tuple(f32, f32),
//! Struct { a: f32, b: f32 },
//! }
//! ```
//!
//! However, note that enums will only perform coarse diffing. If a single
//! field in a variant changes, the entire variant will still be sent.
//! As a result, you can accidentally introduce allocations
//! in audio processors by including types that allocate on clone.
//!
//! ```
//! # use firewheel_core::diff::{Diff, Patch, PathBuilder};
//! #[derive(Diff, Patch, Clone, PartialEq)]
//! enum MaybeAllocates {
//! A(Vec<f32>), // Will cause allocations in `Patch`!
//! B(f32),
//! }
//! ```
//!
//! [`Clone`] types are permitted because [`Clone`] does
//! not always imply allocation. For example, consider
//! the type:
//!
//! ```
//! use firewheel_core::{collector::ArcGc, sample_resource::SampleResource};
//!
//! # use firewheel_core::diff::{Diff, Patch, PathBuilder};
//! #[derive(Diff, Patch, Clone, PartialEq)]
//! enum SoundSource {
//! Sample(ArcGc<dyn SampleResource>), // Will _not_ cause allocations in `Patch`.
//! Frequency(f32),
//! }
//! ```
//!
//! This bound may be restricted to [`Copy`] in the future.
//!
//! # Macro attributes
//!
//! [`Diff`] and [`Patch`] each accept a single attribute, `skip`, on
//! struct fields. Any field annotated with `skip` will not receive
//! diffing or patching, which may be useful for atomically synchronized
//! types.
//! ```
//! use firewheel_core::{collector::ArcGc, diff::{Diff, Patch}};
//! use bevy_platform::sync::atomic::AtomicUsize;
//!
//! #[derive(Diff, Patch)]
//! struct MultiParadigm {
//! normal_field: f32,
//! #[diff(skip)]
//! atomic_field: ArcGc<AtomicUsize>,
//! }
//! ```
//!
//! # Data model
//!
//! Diffing events are represented as `(data, path)` pairs. This approach
//! provides a few important advantages. For one, the fields within nearly
//! all Rust types can be uniquely addressed with index paths.
//!
//! ```
//! # use firewheel_core::diff::{Diff, Patch};
//! #[derive(Diff, Patch, Default)]
//! struct MyParams {
//! a: f32,
//! b: (bool, bool),
//! }
//!
//! let params = MyParams::default();
//!
//! params.a; // [0]
//! params.b.0; // [1, 0]
//! params.b.1; // [1, 1]
//! ```
//!
//! Since these paths can be arbitrarily long, you can arbitrarily
//! nest implementors of [`Diff`] and [`Patch`].
//!
//! ```
//! # use firewheel_core::diff::{Diff, Patch};
//! # #[derive(Diff, Patch, Default)]
//! # struct MyParams {
//! # a: f32,
//! # b: (bool, bool),
//! # }
//! #[derive(Diff, Patch)]
//! struct Aggregate {
//! a: MyParams,
//! b: MyParams,
//! // Indexable types work great too!
//! collection: [MyParams; 8],
//! }
//! ```
//!
//! Furthermore, since we build up paths during calls to
//! [`Diff`], the derive macros and implementations only need
//! to worry about _local indexing._ And, since the paths
//! are built only during [`Diff`], we can traverse them
//! highly performantly during [`Patch`] calls in audio processors.
//!
//! Firewheel provides a number of primitive types in [`ParamData`]
//! that cover most use-cases for audio parameters. For anything
//! not covered in the concrete variants, you can insert arbitrary
//! data into [`ParamData::Any`]. Since this only incurs allocations
//! during [`Diff`], this will still be generally performant.
//!
//! # Preserving invariants
//!
//! Firewheel's [`Patch`] derive macro cannot make assurances about
//! your type's invariants. If two types `A` and `B` have similar structures:
//!
//! ```
//! struct A {
//! pub field_one: f32,
//! pub field_two: f32,
//! }
//!
//! struct B {
//! special_field_one: f32,
//! special_field_two: f32,
//! }
//! ```
//!
//! Then events produced for `A` are also valid for `B`.
//!
//! Receiving events produced by the wrong type is unlikely. Most
//! types will not need special handling to preserve invariants.
//! However, if your invariants are safety-critical, you _must_
//! implement [`Patch`] manually.
use Arc;
use Vec;
use crate::;
use SmallVec;
pub use Memo;
pub use Notify;
/// Derive macros for diffing and patching.
pub use ;
/// 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][self].
///
/// # 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::{Diff, PathBuilder};
/// # #[derive(Diff, Clone)]
/// # struct MyParams {
/// # a: f32,
/// # b: f32,
/// # }
/// 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};
/// # struct MyParams {
/// # a: f32,
/// # b: f32,
/// # }
///
/// 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;
/// # use firewheel_core::diff::{Diff, PathBuilder, EventQueue};
/// # struct MyParams {
/// # a: f32,
/// # b: f32,
/// # }
///
/// 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.
///
/// ```
/// # use firewheel_core::{diff::{Diff, PathBuilder, EventQueue}, event::ParamData};
/// # #[derive(PartialEq, Clone)]
/// # struct MyParams {
/// # a: f32,
/// # b: f32,
/// # }
/// 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);
/// }
/// }
/// }
/// ```
/// A path of indices that uniquely describes an arbitrarily nested field.
/// Fine-grained parameter patching.
///
/// This trait allows a type to perform patching on itself,
/// applying changes generated from another instance.
///
/// For more information, see the [module docs][self].
///
/// # Examples
///
/// Like with [`Diff`], the typical [`Patch`] usage is simple.
///
/// ```
/// use firewheel_core::{diff::Patch, event::*, node::*, log::*};
///
/// #[derive(Patch)]
/// struct MyParams {
/// a: f32,
/// b: f32,
/// }
///
/// struct MyProcessor {
/// params: MyParams,
/// }
///
/// impl AudioNodeProcessor for MyProcessor {
/// fn process(
/// &mut self,
/// info: &ProcInfo,
/// buffers: ProcBuffers,
/// events: &mut ProcEvents,
/// extra: &mut ProcExtra,
/// ) -> ProcessStatus {
/// // Synchronize `params` from the event list.
/// for patch in events.drain_patches::<MyParams>() {
/// self.params.apply(patch);
/// }
///
/// // ...
///
/// ProcessStatus::OutputsModified
/// }
/// }
/// ```
///
/// If you need fine access to each patch, you can
/// match on the patch type.
///
/// ```
/// # use firewheel_core::{diff::{Patch}, event::*, node::*, log::*};
/// # #[derive(Patch)]
/// # struct MyParams {
/// # a: f32,
/// # b: f32,
/// # }
/// # struct MyProcessor {
/// # params: MyParams,
/// # }
/// impl AudioNodeProcessor for MyProcessor {
/// fn process(
/// &mut self,
/// info: &ProcInfo,
/// buffers: ProcBuffers,
/// events: &mut ProcEvents,
/// extra: &mut ProcExtra,
/// ) -> ProcessStatus {
/// for mut patch in events.drain_patches::<MyParams>() {
/// // When you derive `Patch`, it creates an enum with variants
/// // for each field.
/// match &mut patch {
/// MyParamsPatch::A(a) => {
/// // You can mutate the patch itself if you want
/// // to constrain or modify values.
/// *a = a.clamp(0.0, 1.0);
/// }
/// MyParamsPatch::B(b) => {}
/// }
///
/// // And / or apply it directly.
/// self.params.apply(patch);
/// }
///
/// // ...
///
/// ProcessStatus::OutputsModified
/// }
/// }
/// ```
///
/// # Manual implementation
///
/// Like with [`Diff`], types like parameters should prefer the [`Patch`] derive macro.
/// Nonetheless, Firewheel provides a few tools to make manual implementations straightforward.
///
/// ```
/// use firewheel_core::{diff::{Patch, PatchError}, event::ParamData};
///
/// struct MyParams {
/// a: f32,
/// b: bool,
/// }
///
/// // To follow the derive macro convention, create an
/// // enum with variants for each field.
/// enum MyParamsPatch {
/// A(f32),
/// B(bool),
/// }
///
/// impl Patch for MyParams {
/// type Patch = MyParamsPatch;
///
/// fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
/// match path {
/// [0] => {
/// // Types that exist in `ParamData`'s variants can use
/// // `try_into`.
/// let a = data.try_into()?;
/// Ok(MyParamsPatch::A(a))
/// }
/// [1] => {
/// let b = data.try_into()?;
/// Ok(MyParamsPatch::B(b))
/// }
/// _ => Err(PatchError::InvalidPath)
/// }
/// }
///
/// fn apply(&mut self, patch: Self::Patch) {
/// match patch {
/// MyParamsPatch::A(a) => self.a = a,
/// MyParamsPatch::B(b) => self.b = b,
/// }
/// }
/// }
/// ```
/// A trait which signifies that a struct implements `Clone`, cloning
/// does not allocate or deallocate data, and the data will not be
/// dropped on the audio thread if the struct is dropped.
// NOTE: Using a `SmallVec` instead of a `Box<[u32]>` yields
// around an 8% performance uplift for cases where the path
// is in the range 2..=4.
//
// Beyond this range, the performance drops off around 13%.
//
// Since this avoids extra allocations in the common < 5
// scenario, this seems like a reasonable tradeoff.
/// A simple builder for [`ParamPath`].
///
/// When performing top-level diffing, you should provide a default
/// [`PathBuilder`].
///
/// ```
/// # use firewheel_core::{diff::{Diff, PathBuilder}, event::*, node::*};
/// #[derive(Diff, Default, Clone)]
/// struct FilterNode {
/// frequency: f32,
/// quality: f32,
/// }
///
/// let baseline = FilterNode::default();
/// let node = baseline.clone();
///
/// let mut events = Vec::new();
/// node.diff(&baseline, PathBuilder::default(), &mut events);
/// ```
;
/// An event queue for diffing.
/// An error encountered when patching a type
/// from [`ParamData`].