firewheel_core/diff/
leaf.rs1use super::{Diff, EventQueue, Patch, PatchError, PathBuilder};
4use crate::{
5 collector::ArcGc,
6 event::{NodeEventType, ParamData, Vec2, Vec3},
7};
8
9macro_rules! primitive_diff {
10 ($ty:ty, $variant:ident) => {
11 impl Diff for $ty {
12 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
13 if self != baseline {
14 event_queue.push_param(*self, path);
15 }
16 }
17 }
18
19 impl Patch for $ty {
20 type Patch = Self;
21
22 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
23 match data {
24 ParamData::$variant(value) => Ok(*value),
25 _ => Err(PatchError::InvalidData),
26 }
27 }
28
29 fn apply(&mut self, value: Self::Patch) {
30 *self = value;
31 }
32 }
33 };
34
35 ($ty:ty, $cast:ty, $variant:ident) => {
36 impl Diff for $ty {
37 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
38 if self != baseline {
39 event_queue.push_param(*self as $cast, path);
40 }
41 }
42 }
43
44 impl Patch for $ty {
45 type Patch = Self;
46
47 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
48 match data {
49 ParamData::$variant(value) => Ok(*value as $ty),
50 _ => Err(PatchError::InvalidData),
51 }
52 }
53
54 fn apply(&mut self, value: Self::Patch) {
55 *self = value;
56 }
57 }
58 };
59}
60
61primitive_diff!(bool, Bool);
62
63primitive_diff!(u8, u32, U32);
64primitive_diff!(u16, u32, U32);
65primitive_diff!(u32, U32);
66primitive_diff!(u64, U64);
67
68primitive_diff!(i8, i32, I32);
69primitive_diff!(i16, i32, I32);
70primitive_diff!(i32, I32);
71primitive_diff!(i64, u64, U64);
72
73primitive_diff!(f32, F32);
74primitive_diff!(f64, F64);
75
76impl<A: ?Sized + Send + Sync + 'static> Diff for ArcGc<A> {
78 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
79 if ArcGc::ptr_eq(self, baseline) {
80 event_queue.push(NodeEventType::Param {
81 data: ParamData::Any(Box::new(Box::new(self.clone()))),
82 path: path.build(),
83 });
84 }
85 }
86}
87
88impl<A: ?Sized + Send + Sync + 'static> Patch for ArcGc<A> {
89 type Patch = Self;
90
91 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
92 if let ParamData::Any(any) = data {
93 if let Some(data) = any.downcast_ref::<Self>() {
94 return Ok(data.clone());
95 }
96 }
97
98 Err(PatchError::InvalidData)
99 }
100
101 fn apply(&mut self, patch: Self::Patch) {
102 *self = patch;
103 }
104}
105
106impl Diff for Vec2 {
107 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
108 if self != baseline {
109 event_queue.push_param(*self, path);
110 }
111 }
112}
113
114impl Patch for Vec2 {
115 type Patch = Self;
116
117 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
118 data.try_into()
119 }
120
121 fn apply(&mut self, patch: Self::Patch) {
122 *self = patch;
123 }
124}
125
126impl Diff for Vec3 {
127 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
128 if self != baseline {
129 event_queue.push_param(*self, path);
130 }
131 }
132}
133
134impl Patch for Vec3 {
135 type Patch = Self;
136
137 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
138 data.try_into()
139 }
140
141 fn apply(&mut self, patch: Self::Patch) {
142 *self = patch;
143 }
144}
145
146impl<T: Send + Sync + Clone + PartialEq + 'static> Diff for Option<T> {
147 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
148 if self != baseline {
149 event_queue.push_param(ParamData::any(self.clone()), path);
150 }
151 }
152}
153
154impl<T: Send + Sync + Clone + PartialEq + 'static> Patch for Option<T> {
155 type Patch = Self;
156
157 fn patch(data: &ParamData, _: &[u32]) -> Result<Self::Patch, PatchError> {
158 data.downcast_ref().cloned().ok_or(PatchError::InvalidData)
159 }
160
161 fn apply(&mut self, patch: Self::Patch) {
162 *self = patch;
163 }
164}