@@ -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) ]
685694pub 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+
775806impl 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