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 impl Diff for Notify<$ty> {
66 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
67 if self != baseline {
68 event_queue.push_param(*self, path);
69 }
70 }
71 }
72
73 impl Patch for Notify<$ty> {
74 type Patch = Self;
75
76 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
77 match data {
78 ParamData::$variant(value) => Ok(Notify::new((*value).into())),
79 _ => Err(PatchError::InvalidData),
80 }
81 }
82
83 fn apply(&mut self, value: Self::Patch) {
84 *self = value;
85 }
86 }
87 };
88
89 ($ty:ty, $cast:ty, $variant:ident) => {
90 impl Diff for $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 as $cast, path);
94 }
95 }
96 }
97
98 impl Patch for $ty {
99 type Patch = Self;
100
101 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
102 match data {
103 ParamData::$variant(value) => Ok(value.clone() as $ty),
104 _ => Err(PatchError::InvalidData),
105 }
106 }
107
108 fn apply(&mut self, value: Self::Patch) {
109 *self = value;
110 }
111 }
112
113 impl Diff for Option<$ty> {
114 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
115 if self != baseline {
116 event_queue.push_param(self.map(|v| v as $cast), path);
117 }
118 }
119 }
120
121 impl Patch for Option<$ty> {
122 type Patch = Self;
123
124 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
125 match data {
126 ParamData::$variant(value) => Ok(Some(value.clone() as $ty)),
127 ParamData::None => Ok(None),
128 _ => Err(PatchError::InvalidData),
129 }
130 }
131
132 fn apply(&mut self, value: Self::Patch) {
133 *self = value;
134 }
135 }
136
137 impl Diff for Notify<$ty> {
138 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
139 if self != baseline {
140 event_queue.push_param(**self as $cast, path);
141 }
142 }
143 }
144
145 impl Patch for Notify<$ty> {
146 type Patch = Self;
147
148 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
149 match data {
150 ParamData::$variant(value) => Ok(Notify::new(value.clone() as $ty)),
151 _ => Err(PatchError::InvalidData),
152 }
153 }
154
155 fn apply(&mut self, value: Self::Patch) {
156 *self = value;
157 }
158 }
159 };
160}
161
162primitive_diff!(bool, Bool);
163primitive_diff!(u8, u32, U32);
164primitive_diff!(u16, u32, U32);
165primitive_diff!(u32, U32);
166primitive_diff!(u64, U64);
167primitive_diff!(i8, i32, I32);
168primitive_diff!(i16, i32, I32);
169primitive_diff!(i32, I32);
170primitive_diff!(i64, I64);
171primitive_diff!(f32, F32);
172primitive_diff!(f64, F64);
173primitive_diff!(Volume, Volume);
174primitive_diff!(InstantSamples, InstantSamples);
175primitive_diff!(DurationSamples, DurationSamples);
176primitive_diff!(InstantSeconds, InstantSeconds);
177primitive_diff!(DurationSeconds, DurationSeconds);
178#[cfg(feature = "musical_transport")]
179primitive_diff!(InstantMusical, InstantMusical);
180#[cfg(feature = "musical_transport")]
181primitive_diff!(DurationMusical, DurationMusical);
182primitive_diff!(Vec2, Vector2D);
183primitive_diff!(Vec3, Vector3D);
184
185#[cfg(feature = "glam-29")]
186primitive_diff!(glam::Vec2, Vector2D);
187#[cfg(feature = "glam-29")]
188primitive_diff!(glam::Vec3, Vector3D);
189
190impl Diff for Notify<()> {
191 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
192 if self != baseline {
193 event_queue.push_param(ParamData::None, path);
194 }
195 }
196}
197
198impl Patch for Notify<()> {
199 type Patch = Self;
200
201 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
202 match data {
203 ParamData::None => Ok(Notify::new((()).into())),
204 _ => Err(PatchError::InvalidData),
205 }
206 }
207
208 fn apply(&mut self, value: Self::Patch) {
209 *self = value;
210 }
211}
212
213impl<A: ?Sized + Send + Sync + 'static> Diff for ArcGc<A> {
214 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
215 if !ArcGc::ptr_eq(self, baseline) {
216 event_queue.push(NodeEventType::Param {
217 data: ParamData::any(self.clone()),
218 path: path.build(),
219 });
220 }
221 }
222}
223
224impl<A: ?Sized + Send + Sync + 'static> Patch for ArcGc<A> {
225 type Patch = Self;
226
227 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
228 if let ParamData::Any(any) = data {
229 if let Some(data) = any.downcast_ref::<Self>() {
230 return Ok(data.clone());
231 }
232 }
233
234 Err(PatchError::InvalidData)
235 }
236
237 fn apply(&mut self, patch: Self::Patch) {
238 *self = patch;
239 }
240}
241
242impl<T: Send + Sync + RealtimeClone + PartialEq + 'static> Diff for Option<T> {
243 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
244 if self != baseline {
245 event_queue.push_param(ParamData::opt_any(self.clone()), path);
246 }
247 }
248}
249
250impl<T: Send + Sync + RealtimeClone + PartialEq + 'static> Patch for Option<T> {
251 type Patch = Self;
252
253 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
254 Ok(data.downcast_ref::<T>().cloned())
255 }
256
257 fn apply(&mut self, patch: Self::Patch) {
258 *self = patch;
259 }
260}