pub mod filter;
pub mod state;
use std::{
fmt::{Display, Formatter, Result as FmtResult},
time::SystemTime,
};
use crate::{constants::*, gamepad::GamepadId, utils};
#[cfg(feature = "serde-serialize")]
use serde::{Deserialize, Serialize};
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct Code(pub(crate) gilrs_core::EvCode);
impl Display for Code {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
self.0.fmt(f)
}
}
impl Code {
pub fn into_u32(&self) -> u32 {
self.0.into_u32()
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct Event {
pub id: GamepadId,
pub event: EventType,
pub time: SystemTime,
}
impl Event {
pub fn new(id: GamepadId, event: EventType) -> Self {
Event {
id,
event,
time: utils::time_now(),
}
}
pub fn drop(mut self) -> Event {
self.event = EventType::Dropped;
self
}
pub fn is_dropped(&self) -> bool {
self.event == EventType::Dropped
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub enum EventType {
ButtonPressed(Button, Code),
ButtonRepeated(Button, Code),
ButtonReleased(Button, Code),
ButtonChanged(Button, f32, Code),
AxisChanged(Axis, f32, Code),
Connected,
Disconnected,
Dropped,
}
#[repr(u16)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub enum Button {
South = BTN_SOUTH,
East = BTN_EAST,
North = BTN_NORTH,
West = BTN_WEST,
C = BTN_C,
Z = BTN_Z,
LeftTrigger = BTN_LT,
LeftTrigger2 = BTN_LT2,
RightTrigger = BTN_RT,
RightTrigger2 = BTN_RT2,
Select = BTN_SELECT,
Start = BTN_START,
Mode = BTN_MODE,
LeftThumb = BTN_LTHUMB,
RightThumb = BTN_RTHUMB,
DPadUp = BTN_DPAD_UP,
DPadDown = BTN_DPAD_DOWN,
DPadLeft = BTN_DPAD_LEFT,
DPadRight = BTN_DPAD_RIGHT,
Unknown = BTN_UNKNOWN,
}
impl Button {
pub fn is_action(self) -> bool {
use crate::Button::*;
match self {
South | East | North | West | C | Z => true,
_ => false,
}
}
pub fn is_trigger(self) -> bool {
use crate::Button::*;
match self {
LeftTrigger | LeftTrigger2 | RightTrigger | RightTrigger2 => true,
_ => false,
}
}
pub fn is_menu(self) -> bool {
use crate::Button::*;
match self {
Select | Start | Mode => true,
_ => false,
}
}
pub fn is_stick(self) -> bool {
use crate::Button::*;
match self {
LeftThumb | RightThumb => true,
_ => false,
}
}
pub fn is_dpad(self) -> bool {
use crate::Button::*;
match self {
DPadUp | DPadDown | DPadLeft | DPadRight => true,
_ => false,
}
}
pub fn to_nec(self) -> Option<Code> {
use gilrs_core::native_ev_codes as necs;
match self {
Button::South => Some(necs::BTN_SOUTH),
Button::East => Some(necs::BTN_EAST),
Button::North => Some(necs::BTN_NORTH),
Button::West => Some(necs::BTN_WEST),
Button::C => Some(necs::BTN_C),
Button::Z => Some(necs::BTN_Z),
Button::LeftTrigger => Some(necs::BTN_LT),
Button::LeftTrigger2 => Some(necs::BTN_LT2),
Button::RightTrigger => Some(necs::BTN_RT),
Button::RightTrigger2 => Some(necs::BTN_RT2),
Button::Select => Some(necs::BTN_SELECT),
Button::Start => Some(necs::BTN_START),
Button::Mode => Some(necs::BTN_MODE),
Button::LeftThumb => Some(necs::BTN_LTHUMB),
Button::RightThumb => Some(necs::BTN_RTHUMB),
Button::DPadUp => Some(necs::BTN_DPAD_UP),
Button::DPadDown => Some(necs::BTN_DPAD_DOWN),
Button::DPadLeft => Some(necs::BTN_DPAD_LEFT),
Button::DPadRight => Some(necs::BTN_DPAD_RIGHT),
_ => None,
}
.map(Code)
}
}
impl Default for Button {
fn default() -> Self {
Button::Unknown
}
}
#[repr(u16)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub enum Axis {
LeftStickX = AXIS_LSTICKX,
LeftStickY = AXIS_LSTICKY,
LeftZ = AXIS_LEFTZ,
RightStickX = AXIS_RSTICKX,
RightStickY = AXIS_RSTICKY,
RightZ = AXIS_RIGHTZ,
DPadX = AXIS_DPADX,
DPadY = AXIS_DPADY,
Unknown = AXIS_UNKNOWN,
}
impl Axis {
pub fn is_stick(self) -> bool {
use crate::Axis::*;
match self {
LeftStickX | LeftStickY | RightStickX | RightStickY => true,
_ => false,
}
}
pub fn second_axis(self) -> Option<Self> {
use crate::Axis::*;
match self {
LeftStickX => Some(LeftStickY),
LeftStickY => Some(LeftStickX),
RightStickX => Some(RightStickY),
RightStickY => Some(RightStickX),
DPadX => Some(DPadY),
DPadY => Some(DPadX),
_ => None,
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub enum AxisOrBtn {
Axis(Axis),
Btn(Button),
}