bevy_input_bindings 0.0.2

High level, flexible and shareable input binding library for the Bevy game engine
Documentation
use std::time::Duration;

use bevy::input::gamepad::{Gamepad, GamepadAxis, GamepadButton};
use bevy::reflect::Reflect;

use crate::controller_values::VariantValue;

pub trait FunctionTrait {
    fn update_value(&mut self, gamepad: &Gamepad, dt: &Duration, value: &mut VariantValue);
}

#[derive(Reflect, Clone, Debug)]
pub struct ButtonPressed {
    button: GamepadButton,
}

impl ButtonPressed {
    pub fn new(button: GamepadButton) -> Self {
        Self {
            button,
        }
    }
}

impl FunctionTrait for ButtonPressed {
    fn update_value(&mut self, gamepad: &Gamepad, _dt: &Duration, value: &mut VariantValue) {
        *value = VariantValue::Bool(gamepad.pressed(self.button));
    }
}

#[derive(Reflect, Clone, Debug)]
pub struct Direct1d {
    axis: GamepadAxis,
}

impl Direct1d {
    pub fn new(axis: GamepadAxis) -> Self {
        Self {
            axis,
        }
    }
}

impl FunctionTrait for Direct1d {
    fn update_value(&mut self, gamepad: &Gamepad, _dt: &Duration, value: &mut VariantValue) {
        let Some(axis_value) = gamepad.get(self.axis) else {
            return;
        };
        *value = VariantValue::Axis1d(axis_value);
    }
}

#[derive(Reflect, Clone, Debug)]
pub struct Direct2d {
    axis_1: GamepadAxis,
    axis_2: GamepadAxis,
}

impl Direct2d {
    pub fn new(axis_1: GamepadAxis, axis_2: GamepadAxis) -> Self {
        Self {
            axis_1,
            axis_2,
        }
    }
}

impl FunctionTrait for Direct2d {
    fn update_value(&mut self, gamepad: &Gamepad, _dt: &Duration, value: &mut VariantValue) {
        // Get both axis value or do nothing
        let Some(value_1) = gamepad.get(self.axis_1) else {
            return;
        };
        let Some(value_2) = gamepad.get(self.axis_2) else {
            return;
        };
        *value = VariantValue::Axis2d(value_1, value_2);
    }
}

#[derive(Reflect, Clone, Debug)]
pub struct ArrowsFunction {
    up: GamepadButton,
    down: GamepadButton,
    left: GamepadButton,
    right: GamepadButton,
}

impl ArrowsFunction {
    pub fn new(
        up: GamepadButton,
        down: GamepadButton,
        left: GamepadButton,
        right: GamepadButton,
    ) -> Self {
        Self {
            up,
            down,
            left,
            right,
        }
    }
}

impl FunctionTrait for ArrowsFunction {
    fn update_value(&mut self, gamepad: &Gamepad, _dt: &Duration, value: &mut VariantValue) {
        let mut axis_x = 0.0;
        let mut axis_y = 0.0;
        if gamepad.pressed(self.up) {
            axis_y += 1.0;
        }
        if gamepad.pressed(self.down) {
            axis_y -= 1.0;
        }
        if gamepad.pressed(self.left) {
            axis_x += 1.0;
        }
        if gamepad.pressed(self.right) {
            axis_x -= 1.0;
        }
        *value = VariantValue::Axis2d(axis_x, axis_y);
    }
}