use core::fmt;
use crate::Holds;
use crate::input::binding::{Axis2Binding, AxisBinding, ButtonBinding, Key};
use crate::input::table::sealed::Binding as Persisted;
pub trait InputAction: Copy + 'static {
type Binding: Persisted + fmt::Display;
fn defaults(&self) -> Vec<Self::Binding>;
fn all() -> Vec<Self>;
fn name(&self) -> &'static str;
fn from_name(name: &str) -> Option<Self>;
}
pub trait InputButtonAction: InputAction<Binding = ButtonBinding> {
fn bindings(&self) -> Vec<ButtonBinding>;
}
pub trait InputAxisAction: InputAction<Binding = AxisBinding> {
fn bindings(&self) -> Vec<AxisBinding>;
}
pub trait InputAxis2Action: InputAction<Binding = Axis2Binding> {
fn bindings(&self) -> Vec<Axis2Binding>;
}
pub trait InputActions {
type Button: InputButtonAction;
type Axis: InputAxisAction;
type Axis2: InputAxis2Action;
}
impl<S: InputActions> Holds<S::Button, ButtonBinding> for S {}
impl<S: InputActions> Holds<S::Axis, AxisBinding> for S {}
impl<S: InputActions> Holds<S::Axis2, Axis2Binding> for S {}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum NoInputActions {}
impl InputActions for NoInputActions {
type Button = NoInputButtons;
type Axis = NoInputAxes;
type Axis2 = NoInputAxes2;
}
macro_rules! empty {
($name:ident, $kind:ident, $binding:ident, $noun:literal) => {
#[doc = concat!("The vocabulary of a game with no ", $noun, " actions of its own.")]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum $name {}
impl InputAction for $name {
type Binding = $binding;
fn defaults(&self) -> Vec<$binding> {
match *self {}
}
fn all() -> Vec<Self> {
Vec::new()
}
fn name(&self) -> &'static str {
match *self {}
}
fn from_name(_name: &str) -> Option<Self> {
None
}
}
impl $kind for $name {
fn bindings(&self) -> Vec<$binding> {
match *self {}
}
}
};
}
empty!(NoInputButtons, InputButtonAction, ButtonBinding, "button");
empty!(NoInputAxes, InputAxisAction, AxisBinding, "number");
empty!(NoInputAxes2, InputAxis2Action, Axis2Binding, "vector");
impl InputAction for Key {
type Binding = ButtonBinding;
fn defaults(&self) -> Vec<ButtonBinding> {
<Self as InputButtonAction>::bindings(self)
}
fn all() -> Vec<Self> {
Self::ALL.to_vec()
}
fn name(&self) -> &'static str {
self.token()
}
fn from_name(name: &str) -> Option<Self> {
Self::from_token(name)
}
}
impl InputButtonAction for Key {
fn bindings(&self) -> Vec<ButtonBinding> {
vec![ButtonBinding::Key(*self)]
}
}
impl InputActions for Key {
type Button = Key;
type Axis = NoInputAxes;
type Axis2 = NoInputAxes2;
}