ngen 0.1.4

A very simple game engine using OpenGL
Documentation
use crate::math::Vec2;

#[derive(Clone, Copy, Default)]
pub struct Button {
    curr: bool,
    prev: bool,
}

impl Button {
    /// Returns true if a button was down on the previous frame but is currently up for this frame.
    #[inline]
    pub const fn was_down(&self) -> bool {
        self.prev && !self.curr
    }

    /// Returns true if the button was either pressed or released this frame.
    #[inline]
    pub const fn changed(&self) -> bool {
        self.curr != self.prev
    }

    /// Returns true if the button is currently down for this frame.
    #[inline]
    pub const fn is_down(&self) -> bool {
        self.curr
    }

    /// Used to force the button into a particular state.
    #[inline]
    pub fn set_is_down(&mut self, is_down: bool) {
        self.curr = is_down;
    }

    /// Used to move the current state to the previous state.
    #[inline]
    pub(crate) fn frame(&mut self) {
        self.prev = self.curr;
    }
}

trait Buttons: Sized {
    fn buttons(&self) -> &[Button] {
        unsafe {
            let ptr = self as *const Self as *const Button;
            let button_count = std::mem::size_of::<Self>() / std::mem::size_of::<Button>();
            std::slice::from_raw_parts(ptr, button_count)
        }
    }

    fn buttons_mut(&mut self) -> &mut [Button] {
        unsafe {
            let ptr = self as *mut Self as *mut Button;
            let button_count = std::mem::size_of::<Self>() / std::mem::size_of::<Button>();
            std::slice::from_raw_parts_mut(ptr, button_count)
        }
    }
}

pub struct Mouse {
    pub left_button: Button,
    pub right_button: Button,
    pub screen_pos: Vec2,
    pub prev_screen_pos: Vec2,
}

impl Default for Mouse {
    fn default() -> Self {
        Self {
            left_button: Button::default(),
            right_button: Button::default(),
            screen_pos: Vec2::new(0., 0.),
            prev_screen_pos: Vec2::new(0., 0.),
        }
    }
}

impl Mouse {
    pub(crate) fn frame(&mut self) {
        self.left_button.frame();
        self.right_button.frame();
        self.prev_screen_pos = self.screen_pos;
    }
}

#[derive(Default)]
pub struct Controller {
    pub left: Button,
    pub right: Button,
    pub up: Button,
    pub down: Button,

    pub bumper_left: Button,
    pub bumper_right: Button,

    pub start: Button,
    pub select: Button,

    pub action_a: Button,
    pub action_b: Button,
    pub action_c: Button,
    pub action_d: Button,
}

impl Buttons for Controller {}

impl Controller {
    pub(crate) fn frame(&mut self) {
        for button in self.buttons_mut() {
            button.frame();
        }
    }
}

#[derive(Default)]
pub struct Keyboard {
    pub f: [Button; 13],
    pub enter: Button,
    pub escape: Button,
}

impl Buttons for Keyboard {}

impl Keyboard {
    pub(crate) fn frame(&mut self) {
        for button in self.buttons_mut() {
            button.frame();
        }
    }
}

#[derive(Default)]
pub struct Input {
    pub controller: Controller,
    pub mouse: Mouse,
    pub keyboard: Keyboard,
}

impl Input {
    pub(crate) fn frame(&mut self) {
        self.controller.frame();
        self.mouse.frame();
        self.keyboard.frame();
    }
}