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    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            fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError> {
21                match data {
22                    ParamData::$variant(value) => {
23                        *self = *value;
24                        Ok(())
25                    }
26                    _ => Err(PatchError::InvalidData),
27                }
28            }
29        }
30    };
31
32    ($ty:ty, $cast:ty, $variant:ident) => {
33        impl Diff for $ty {
34            fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
35                if self != baseline {
36                    event_queue.push_param(*self as $cast, path);
37                }
38            }
39        }
40
41        impl Patch for $ty {
42            fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError> {
43                match data {
44                    ParamData::$variant(value) => {
45                        *self = *value as $ty;
46                        Ok(())
47                    }
48                    _ => Err(PatchError::InvalidData),
49                }
50            }
51        }
52    };
53}
54
55primitive_diff!(bool, Bool);
56
57primitive_diff!(u8, u32, U32);
58primitive_diff!(u16, u32, U32);
59primitive_diff!(u32, U32);
60primitive_diff!(u64, U64);
61
62primitive_diff!(i8, i32, I32);
63primitive_diff!(i16, i32, I32);
64primitive_diff!(i32, I32);
65primitive_diff!(i64, u64, U64);
66
67primitive_diff!(f32, F32);
68primitive_diff!(f64, F64);
69
70// This may be questionable.
71impl<A: ?Sized + Send + Sync + 'static> Diff for ArcGc<A> {
72    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
73        if ArcGc::ptr_eq(self, baseline) {
74            event_queue.push(NodeEventType::Param {
75                data: ParamData::Any(Box::new(Box::new(self.clone()))),
76                path: path.build(),
77            });
78        }
79    }
80}
81
82impl<A: ?Sized + Send + Sync + 'static> Patch for ArcGc<A> {
83    fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError> {
84        if let ParamData::Any(any) = data {
85            if let Some(data) = any.downcast_ref::<Self>() {
86                *self = data.clone();
87                return Ok(());
88            }
89        }
90
91        Err(PatchError::InvalidData)
92    }
93}
94
95impl Diff for Vec2 {
96    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
97        if self != baseline {
98            event_queue.push_param(*self, path);
99        }
100    }
101}
102
103impl Patch for Vec2 {
104    fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError> {
105        *self = data.try_into()?;
106        Ok(())
107    }
108}
109
110impl Diff for Vec3 {
111    fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
112        if self != baseline {
113            event_queue.push_param(*self, path);
114        }
115    }
116}
117
118impl Patch for Vec3 {
119    fn patch(&mut self, data: &ParamData, _: &[u32]) -> Result<(), PatchError> {
120        *self = data.try_into()?;
121        Ok(())
122    }
123}