use crate::types::{GamepadAxis, GamepadButton, GamepadId};
use std::collections::HashMap;
#[derive(Debug, Clone, Default)]
pub struct GamepadButtonState {
pub is_down: bool,
pub just_pressed_frame: Option<u32>,
pub just_released_frame: Option<u32>,
pub value: f32, }
#[derive(Debug, Clone, Default)]
pub struct GamepadAxisState {
pub value: f32,
pub threshold: f32,
}
#[derive(Debug, Clone)]
pub struct GamepadState {
pub id: GamepadId,
pub connected: bool,
pub buttons: HashMap<GamepadButton, GamepadButtonState>,
pub axes: HashMap<GamepadAxis, GamepadAxisState>,
pub deadzone: f32,
}
impl GamepadState {
pub fn new(id: GamepadId) -> Self {
Self {
id,
connected: false,
buttons: HashMap::new(),
axes: HashMap::new(),
deadzone: 0.1, }
}
pub fn set_button(&mut self, button: GamepadButton, pressed: bool, value: f32, frame: u32) {
let state = self.buttons.entry(button).or_default();
if pressed && !state.is_down {
state.just_pressed_frame = Some(frame);
} else if !pressed && state.is_down {
state.just_released_frame = Some(frame);
}
state.is_down = pressed;
state.value = value;
}
pub fn set_axis(&mut self, axis: GamepadAxis, value: f32) {
let filtered_value = if value.abs() < self.deadzone {
0.0
} else {
value
};
let state = self.axes.entry(axis).or_default();
state.value = filtered_value;
}
pub fn end_frame(&mut self) {
for state in self.buttons.values_mut() {
state.just_pressed_frame = None;
state.just_released_frame = None;
}
}
pub fn is_button_down(&self, button: GamepadButton) -> bool {
self.buttons
.get(&button)
.map(|b| b.is_down)
.unwrap_or(false)
}
pub fn get_axis(&self, axis: GamepadAxis) -> f32 {
self.axes.get(&axis).map(|a| a.value).unwrap_or(0.0)
}
}
pub struct GamepadsState {
gamepads: HashMap<GamepadId, GamepadState>,
}
impl Default for GamepadsState {
fn default() -> Self {
Self::new()
}
}
impl GamepadsState {
pub fn new() -> Self {
Self {
gamepads: HashMap::new(),
}
}
pub fn get(&self, id: GamepadId) -> Option<&GamepadState> {
self.gamepads.get(&id)
}
pub fn get_mut(&mut self, id: GamepadId) -> &mut GamepadState {
self.gamepads
.entry(id)
.or_insert_with(|| GamepadState::new(id))
}
pub fn end_frame(&mut self) {
for gamepad in self.gamepads.values_mut() {
gamepad.end_frame();
}
}
}