1use 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
202impl 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
458trivial_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);