use crate::math::Vector2;
use std::fmt::Debug;
use std::sync::{Arc, Mutex};
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum MouseButton {
MouseButtonLeft = 0,
MouseButtonRight = 1,
MouseButtonMiddle = 2,
MouseButtonSide = 3,
MouseButtonExtra = 4,
MouseButtonForward = 5,
MouseButtonBack = 6,
}
pub const MOUSE_BUTTON_LIST: [MouseButton; 7] = [
MouseButton::MouseButtonLeft,
MouseButton::MouseButtonRight,
MouseButton::MouseButtonMiddle,
MouseButton::MouseButtonSide,
MouseButton::MouseButtonExtra,
MouseButton::MouseButtonForward,
MouseButton::MouseButtonBack,
];
pub trait MouseProvider {
fn get_mouse_position(&self) -> Vector2;
fn mouse_button_down(&self, button: MouseButton) -> bool;
fn get_mouse_wheel_move_v(&self) -> Vector2;
}
impl<T: MouseProvider> MouseProvider for Mutex<T> {
fn get_mouse_position(&self) -> Vector2 {
self.lock().unwrap().get_mouse_position()
}
fn mouse_button_down(&self, button: MouseButton) -> bool {
self.lock().unwrap().mouse_button_down(button)
}
fn get_mouse_wheel_move_v(&self) -> Vector2 {
self.lock().unwrap().get_mouse_wheel_move_v()
}
}
impl<T: MouseProvider> MouseProvider for Arc<T> {
fn get_mouse_position(&self) -> Vector2 {
(**self).get_mouse_position()
}
fn mouse_button_down(&self, button: MouseButton) -> bool {
(**self).mouse_button_down(button)
}
fn get_mouse_wheel_move_v(&self) -> Vector2 {
(**self).get_mouse_wheel_move_v()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::{Arc, Mutex};
struct MockMouse {
position: Vector2,
left_down: bool,
wheel: Vector2,
}
impl MouseProvider for MockMouse {
fn get_mouse_position(&self) -> Vector2 {
self.position
}
fn mouse_button_down(&self, button: MouseButton) -> bool {
button == MouseButton::MouseButtonLeft && self.left_down
}
fn get_mouse_wheel_move_v(&self) -> Vector2 {
self.wheel
}
}
#[test]
fn mutex_and_arc_delegate_mouse_provider() {
let mock = MockMouse {
position: Vector2::new(12.0, 34.0),
left_down: true,
wheel: Vector2::new(0.0, 2.5),
};
let mutex = Mutex::new(mock);
assert_eq!(mutex.get_mouse_position().x, 12.0);
assert!(mutex.mouse_button_down(MouseButton::MouseButtonLeft));
assert_eq!(mutex.get_mouse_wheel_move_v().y, 2.5);
let arc = Arc::new(MockMouse {
position: Vector2::new(1.0, 2.0),
left_down: false,
wheel: Vector2::new(-1.0, 0.0),
});
assert_eq!(arc.get_mouse_position().y, 2.0);
assert!(!arc.mouse_button_down(MouseButton::MouseButtonLeft));
assert_eq!(arc.get_mouse_wheel_move_v().x, -1.0);
}
}