rich_sdl2_rust/haptic/
joystick.rs

1//! A haptic device integrated with the joystick.
2
3use std::{marker::PhantomData, ops::Deref, ptr::NonNull};
4
5use crate::{bind, event::joystick::Joystick};
6
7use super::Haptic;
8
9/// A haptic device got from the joystick.
10pub struct JoystickHaptic<'joystick> {
11    haptic: Haptic,
12    _phantom: PhantomData<&'joystick Joystick>,
13}
14
15impl std::fmt::Debug for JoystickHaptic<'_> {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        f.debug_struct("JoystickHaptic")
18            .field("haptic", &self.haptic)
19            .finish()
20    }
21}
22
23impl<'joystick> JoystickHaptic<'joystick> {
24    /// Constructs from a reference to [`Joystick`].
25    pub fn new(joystick: impl AsRef<Joystick> + 'joystick) -> Option<Self> {
26        let is_supported = unsafe {
27            bind::SDL_JoystickIsHaptic(joystick.as_ref().ptr().as_ptr()) as bind::SDL_bool
28                == bind::SDL_TRUE
29        };
30        if !is_supported {
31            return None;
32        }
33        let ptr = unsafe { bind::SDL_HapticOpenFromJoystick(joystick.as_ref().ptr().as_ptr()) };
34        Some(Self {
35            haptic: Haptic {
36                ptr: NonNull::new(ptr).unwrap(),
37            },
38            _phantom: PhantomData,
39        })
40    }
41}
42
43impl Deref for JoystickHaptic<'_> {
44    type Target = Haptic;
45
46    fn deref(&self) -> &Self::Target {
47        &self.haptic
48    }
49}
50
51impl Drop for JoystickHaptic<'_> {
52    fn drop(&mut self) {
53        unsafe { bind::SDL_HapticClose(self.ptr.as_ptr()) }
54    }
55}