Skip to content

Commit 3baa4d1

Browse files
committed
Compare waveforms in the PartialEq impl of Periodic
Previously, effects pointing to different locations containing equal waveform data were considered non-equal.
1 parent 3a700dd commit 3baa4d1

1 file changed

Lines changed: 43 additions & 2 deletions

File tree

src/ff.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ ffi_enum! {
157157
SINE = Feature::SINE.0,
158158
SAW_UP = Feature::SAW_UP.0,
159159
SAW_DOWN = Feature::SAW_DOWN.0,
160+
161+
/// Custom waveform data.
162+
///
163+
/// This can be created via [`Periodic::custom`].
160164
CUSTOM = Feature::CUSTOM.0,
161165
}
162166
}
@@ -680,7 +684,12 @@ impl fmt::Debug for Rumble {
680684
}
681685

682686
/// A periodic waveform effect.
683-
#[derive(Clone, Copy, PartialEq, Eq)]
687+
///
688+
/// The `'a` lifetime is only relevant when the effect uses a custom waveform.
689+
/// It indicates the lifetime of that custom waveform data (which the [`Periodic`] struct borrows
690+
/// from).
691+
/// For all other types of [`Periodic`] events, the lifetime can be `'static`.
692+
#[derive(Clone, Copy)]
684693
#[repr(transparent)]
685694
pub struct Periodic<'a> {
686695
raw: ff_periodic_effect,
@@ -701,9 +710,16 @@ impl<'a> Periodic<'a> {
701710
p
702711
}
703712

713+
/// Creates a custom waveform effect.
714+
///
715+
/// The device has to advertise support for [`Feature::CUSTOM`] for this to work.
716+
///
717+
/// # Panics
718+
///
719+
/// Panics when `data` is longer than [`u32::MAX`] elements.
720+
/// In practice, no device will accept a waveform that large anyways.
704721
#[inline]
705722
pub fn custom(data: &'a [i16]) -> Periodic<'a> {
706-
// TODO: seems like a bad idea to expose a near-useless feature like this
707723
let mut p = Periodic {
708724
raw: unsafe { mem::zeroed() },
709725
_p: PhantomData,
@@ -714,6 +730,7 @@ impl<'a> Periodic<'a> {
714730
p
715731
}
716732

733+
/// Returns the type of [`Waveform`] described by this [`Periodic`] effect.
717734
#[inline]
718735
pub fn waveform(&self) -> Waveform {
719736
Waveform(self.raw.waveform)
@@ -772,6 +789,20 @@ impl<'a> Periodic<'a> {
772789
}
773790
}
774791

792+
impl PartialEq for Periodic<'_> {
793+
fn eq(&self, other: &Self) -> bool {
794+
// This has to be done by hand because the derived impl wouldn't compare the waveform data.
795+
self.waveform() == other.waveform()
796+
&& self.period() == other.period()
797+
&& self.magnitude() == other.magnitude()
798+
&& self.offset() == other.offset()
799+
&& self.phase() == other.phase()
800+
&& self.envelope() == other.envelope()
801+
&& self.custom_data() == other.custom_data()
802+
}
803+
}
804+
impl Eq for Periodic<'_> {}
805+
775806
impl fmt::Debug for Periodic<'_> {
776807
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
777808
f.debug_struct("Periodic")
@@ -1125,4 +1156,14 @@ mod tests {
11251156
assert::<EffectType>();
11261157
assert::<EffectId>();
11271158
}
1159+
1160+
#[test]
1161+
fn custom_eq() {
1162+
// These `Periodic` effects point to different waveforms, but those waveforms are equal.
1163+
static BUF: &[i16] = &[0, 1, 2, 3, 2, 1, 0];
1164+
let a = Periodic::custom(&BUF[0..1]); // &[0]
1165+
let b = Periodic::custom(&BUF[6..7]); // &[0]
1166+
1167+
assert_eq!(a, b);
1168+
}
11281169
}

0 commit comments

Comments
 (0)