use crate::{Button, Event, Input};
#[derive(Copy, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum ButtonState {
Press,
Release,
}
#[derive(Copy, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct ButtonArgs {
pub state: ButtonState,
pub button: Button,
pub scancode: Option<i32>,
}
pub trait ButtonEvent: Sized {
fn from_button_args(args: ButtonArgs, old_event: &Self) -> Option<Self>;
fn button<U, F>(&self, f: F) -> Option<U>
where
F: FnMut(ButtonArgs) -> U;
fn button_args(&self) -> Option<ButtonArgs> {
self.button(|args| args)
}
}
impl ButtonEvent for Event {
fn from_button_args(args: ButtonArgs, old_event: &Self) -> Option<Self> {
let timestamp = if let Event::Input(_, x) = old_event {
*x
} else {
None
};
Some(Event::Input(Input::Button(args), timestamp))
}
fn button<U, F>(&self, mut f: F) -> Option<U>
where
F: FnMut(ButtonArgs) -> U,
{
match *self {
Event::Input(Input::Button(args), _) => Some(f(args)),
_ => None,
}
}
}
pub trait PressEvent: Sized {
fn from_button(button: Button, old_event: &Self) -> Option<Self>;
fn press<U, F>(&self, f: F) -> Option<U>
where
F: FnMut(Button) -> U;
fn press_args(&self) -> Option<Button> {
self.press(|button| button)
}
}
impl<T> PressEvent for T
where
T: ButtonEvent,
{
fn from_button(button: Button, old_event: &Self) -> Option<Self> {
if let Some(mut args) = old_event.button_args() {
args.state = ButtonState::Press;
args.button = button;
ButtonEvent::from_button_args(args, old_event)
} else {
ButtonEvent::from_button_args(
ButtonArgs {
state: ButtonState::Press,
button,
scancode: None,
},
old_event,
)
}
}
fn press<U, F>(&self, mut f: F) -> Option<U>
where
F: FnMut(Button) -> U,
{
if let Some(ButtonArgs {
state: ButtonState::Press,
button,
..
}) = self.button_args()
{
Some(f(button))
} else {
None
}
}
}
pub trait ReleaseEvent: Sized {
fn from_button(button: Button, old_event: &Self) -> Option<Self>;
fn release<U, F>(&self, f: F) -> Option<U>
where
F: FnMut(Button) -> U;
fn release_args(&self) -> Option<Button> {
self.release(|button| button)
}
}
impl<T> ReleaseEvent for T
where
T: ButtonEvent,
{
fn from_button(button: Button, old_event: &Self) -> Option<Self> {
if let Some(mut args) = old_event.button_args() {
args.state = ButtonState::Release;
args.button = button;
ButtonEvent::from_button_args(args, old_event)
} else {
ButtonEvent::from_button_args(
ButtonArgs {
state: ButtonState::Release,
button,
scancode: None,
},
old_event,
)
}
}
fn release<U, F>(&self, mut f: F) -> Option<U>
where
F: FnMut(Button) -> U,
{
if let Some(ButtonArgs {
state: ButtonState::Release,
button,
..
}) = self.button_args()
{
Some(f(button))
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_input_press() {
use super::super::{Button, Key};
let e: Event = ButtonArgs {
state: ButtonState::Press,
button: Key::S.into(),
scancode: None,
}
.into();
let button = Button::Keyboard(Key::A);
let x: Option<Event> = PressEvent::from_button(button, &e);
let y: Option<Event> = x
.clone()
.unwrap()
.press(|button| PressEvent::from_button(button, x.as_ref().unwrap()))
.unwrap();
assert_eq!(x, y);
}
#[test]
fn test_input_release() {
use super::super::{Button, Key};
let e: Event = ButtonArgs {
state: ButtonState::Release,
button: Key::S.into(),
scancode: None,
}
.into();
let button = Button::Keyboard(Key::A);
let x: Option<Event> = ReleaseEvent::from_button(button, &e);
let y: Option<Event> = x
.clone()
.unwrap()
.release(|button| ReleaseEvent::from_button(button, x.as_ref().unwrap()))
.unwrap();
assert_eq!(x, y);
}
}