Create an input module to cleanup code
This commit is contained in:
parent
73160172ee
commit
76f81d6b02
|
@ -12,7 +12,7 @@ use tracing_subscriber::{
|
|||
|
||||
use winit::{window::{WindowBuilder, Window}, event::{Event, WindowEvent, KeyboardInput, ElementState, VirtualKeyCode, DeviceEvent}, event_loop::{EventLoop, ControlFlow}};
|
||||
|
||||
use crate::{render::{renderer::{Renderer, BasicRenderer}, window::WindowOptions}, input_event::InputEvent, ecs::{SimpleSystem, SystemDispatcher, EventQueue, Events}, plugin::Plugin, change_tracker::Ct};
|
||||
use crate::{render::{renderer::{Renderer, BasicRenderer}, window::WindowOptions}, input::InputEvent, ecs::{SimpleSystem, SystemDispatcher, EventQueue, Events}, plugin::Plugin, change_tracker::Ct};
|
||||
|
||||
pub struct Controls<'a> {
|
||||
pub world: &'a mut edict::World,
|
||||
|
|
351
src/input.rs
351
src/input.rs
|
@ -1,351 +0,0 @@
|
|||
use std::{collections::{HashMap, hash_map::DefaultHasher}, hash::{Hash, Hasher}};
|
||||
|
||||
use glam::Vec2;
|
||||
use tracing::debug;
|
||||
use winit::event::{ElementState, MouseScrollDelta};
|
||||
|
||||
use crate::{ecs::{SimpleSystem, EventQueue}, input_event::InputEvent, plugin::Plugin,};
|
||||
|
||||
pub type KeyCode = winit::event::VirtualKeyCode;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||
pub enum ButtonEvent<T: Clone + Hash + Eq + PartialEq + 'static> {
|
||||
Pressed(T),
|
||||
Released(T),
|
||||
JustPressed(T),
|
||||
}
|
||||
|
||||
impl<T: Clone + Hash + Eq + PartialEq + 'static> ButtonEvent<T> {
|
||||
fn take_val(self) -> T {
|
||||
match self {
|
||||
ButtonEvent::Pressed(t) => t,
|
||||
ButtonEvent::JustPressed(t) => t,
|
||||
ButtonEvent::Released(t) => t,
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_val(&self) -> T {
|
||||
self.clone().take_val()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct MouseMotion {
|
||||
pub delta: Vec2,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct MouseWheel {
|
||||
pub delta: Vec2,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct MouseExact {
|
||||
pub pos: Vec2,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
|
||||
pub enum TouchPhase {
|
||||
Started,
|
||||
Moved,
|
||||
Ended,
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
impl From<winit::event::TouchPhase> for TouchPhase {
|
||||
fn from(value: winit::event::TouchPhase) -> Self {
|
||||
match value {
|
||||
winit::event::TouchPhase::Started => TouchPhase::Started,
|
||||
winit::event::TouchPhase::Moved => TouchPhase::Moved,
|
||||
winit::event::TouchPhase::Ended => TouchPhase::Ended,
|
||||
winit::event::TouchPhase::Cancelled => TouchPhase::Cancelled,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Translated `Force` from `winit` crate
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Force {
|
||||
Calibrated {
|
||||
force: f64,
|
||||
max_possible_force: f64,
|
||||
altitude_angle: Option<f64>,
|
||||
},
|
||||
Normalized(f64),
|
||||
}
|
||||
|
||||
impl From<winit::event::Force> for Force {
|
||||
fn from(value: winit::event::Force) -> Self {
|
||||
match value {
|
||||
winit::event::Force::Calibrated { force, max_possible_force, altitude_angle } => Self::Calibrated { force, max_possible_force, altitude_angle },
|
||||
winit::event::Force::Normalized(v) => Self::Normalized(v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Translated `WindowEvent::Touch` from `winit` crate
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Touch {
|
||||
pub phase: TouchPhase,
|
||||
pub location: Vec2,
|
||||
pub force: Option<Force>,
|
||||
pub finger_id: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Touches {
|
||||
pub touches: Vec<Touch>,
|
||||
}
|
||||
|
||||
impl Default for Touches {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Touches {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
touches: Vec::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A mouse button event
|
||||
///
|
||||
/// Translated `WindowEvent::MouseButton` from `winit` crate
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum MouseButton {
|
||||
Left,
|
||||
Right,
|
||||
Middle,
|
||||
Other(u16),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum MouseScrollUnit {
|
||||
Line(Vec2),
|
||||
Pixel(Vec2)
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct MouseScroll {
|
||||
pub unit: MouseScrollUnit,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct CursorEnteredWindow;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct CursorLeftWindow;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InputButtons<T: Clone + Hash + Eq + PartialEq + 'static> {
|
||||
// the u64 as the key is the hashed value of T. this makes it easier to
|
||||
// search for a button and see its state
|
||||
button_events: HashMap<u64, ButtonEvent<T>>,
|
||||
}
|
||||
|
||||
impl<T: Clone + Hash + Eq + PartialEq + 'static> Default for InputButtons<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + Hash + Eq + PartialEq + 'static> InputButtons<T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
button_events: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_button_hash(button: &T) -> u64 {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
button.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
/// Add a button event to this input type
|
||||
pub fn add_input(&mut self, button: ButtonEvent<T>) {
|
||||
let hash = Self::get_button_hash(&button.clone_val());
|
||||
|
||||
self.button_events.insert(hash, button);
|
||||
}
|
||||
|
||||
pub(crate) fn add_input_from_winit(&mut self, button: T, state: ElementState) {
|
||||
let event = match state {
|
||||
ElementState::Pressed if self.is_pressed(button.clone()) => ButtonEvent::Pressed(button),
|
||||
ElementState::Pressed => ButtonEvent::JustPressed(button),
|
||||
ElementState::Released => ButtonEvent::Released(button),
|
||||
};
|
||||
|
||||
self.add_input(event);
|
||||
}
|
||||
|
||||
/// Returns true if the button is pressed (or was just pressed)
|
||||
pub fn is_pressed(&self, button: T) -> bool
|
||||
{
|
||||
let hash = Self::get_button_hash(&button);
|
||||
match self.button_events.get(&hash) {
|
||||
Some(button_event) => match button_event {
|
||||
// this if statement should always be true, but just in case ;)
|
||||
ButtonEvent::Pressed(b) | ButtonEvent::JustPressed(b) if button == *b => true,
|
||||
_ => false,
|
||||
},
|
||||
None => false
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the button was just pressed this tick
|
||||
pub fn was_just_pressed(&self, button: T) -> bool {
|
||||
let hash = Self::get_button_hash(&button);
|
||||
match self.button_events.get(&hash) {
|
||||
Some(button_event) => match button_event {
|
||||
// this if statement should always be true, but just in case ;)
|
||||
ButtonEvent::JustPressed(b) if button == *b => true,
|
||||
_ => false,
|
||||
},
|
||||
None => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait InputStorage {
|
||||
fn update_just_pressed(&mut self);
|
||||
}
|
||||
|
||||
impl<T: Clone + Hash + Eq + PartialEq + 'static> InputStorage for InputButtons<T> {
|
||||
fn update_just_pressed(&mut self) {
|
||||
self.button_events.retain(|_hash, button| {
|
||||
match button {
|
||||
// remove released, no need to keep those around.
|
||||
ButtonEvent::Released(_) => {
|
||||
return false;
|
||||
},
|
||||
ButtonEvent::JustPressed(b) => {
|
||||
*button = ButtonEvent::Pressed(b.clone());
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct InputSystem;
|
||||
|
||||
impl InputSystem {
|
||||
pub fn update(&mut self, event: &InputEvent, world: &mut edict::World) -> bool {
|
||||
let event_queue = world.get_resource_mut::<EventQueue>();
|
||||
if event_queue.is_none() {
|
||||
return false;
|
||||
}
|
||||
let mut event_queue = event_queue.unwrap();
|
||||
|
||||
match event {
|
||||
InputEvent::KeyboardInput { input, .. } => {
|
||||
if let Some(code) = input.virtual_keycode {
|
||||
drop(event_queue);
|
||||
let e = world.with_resource(InputButtons::<KeyCode>::new);
|
||||
//let mut e = with_resource_mut(world, || InputButtons::<KeyCode>::new());
|
||||
e.add_input_from_winit(code, input.state);
|
||||
}
|
||||
},
|
||||
InputEvent::MouseMotion { delta, .. } => {
|
||||
let delta = MouseMotion {
|
||||
delta: Vec2::new(delta.0 as f32, delta.1 as f32)
|
||||
};
|
||||
|
||||
event_queue.trigger_event(delta);
|
||||
},
|
||||
InputEvent::CursorMoved { position, .. } => {
|
||||
let exact = MouseExact {
|
||||
pos: Vec2::new(position.x as f32, position.y as f32)
|
||||
};
|
||||
|
||||
event_queue.trigger_event(exact);
|
||||
},
|
||||
InputEvent::CursorEntered { .. } => {
|
||||
let event = CursorEnteredWindow {};
|
||||
event_queue.trigger_event(event);
|
||||
},
|
||||
InputEvent::CursorLeft { .. } => {
|
||||
let event = CursorLeftWindow {};
|
||||
event_queue.trigger_event(event);
|
||||
},
|
||||
InputEvent::MouseWheel { delta, .. } => {
|
||||
let event = match delta {
|
||||
MouseScrollDelta::LineDelta(x, y) => MouseScroll {
|
||||
unit: MouseScrollUnit::Line(Vec2::new(*x, *y)),
|
||||
},
|
||||
MouseScrollDelta::PixelDelta(delta) => MouseScroll {
|
||||
unit: MouseScrollUnit::Pixel(Vec2::new(delta.x as f32, delta.y as f32)),
|
||||
},
|
||||
};
|
||||
|
||||
event_queue.trigger_event(event);
|
||||
}, //MouseButton
|
||||
InputEvent::MouseInput { button, state, .. } => {
|
||||
let button_event = match button {
|
||||
winit::event::MouseButton::Left => MouseButton::Left,
|
||||
winit::event::MouseButton::Right => MouseButton::Right,
|
||||
winit::event::MouseButton::Middle => MouseButton::Middle,
|
||||
winit::event::MouseButton::Other(v) => MouseButton::Other(*v),
|
||||
};
|
||||
|
||||
event_queue.trigger_event(button_event);
|
||||
drop(event_queue);
|
||||
|
||||
let e = world.with_resource(InputButtons::<MouseButton>::new);
|
||||
e.add_input_from_winit(button_event, *state);
|
||||
},
|
||||
InputEvent::Touch(t) => {
|
||||
drop(event_queue);
|
||||
|
||||
let touch = Touch {
|
||||
phase: TouchPhase::from(t.phase),
|
||||
location: Vec2::new(t.location.x as f32, t.location.y as f32),
|
||||
force: t.force.map(Force::from),
|
||||
finger_id: t.id,
|
||||
};
|
||||
|
||||
let touches = world.with_resource(Touches::new);
|
||||
touches.touches.push(touch);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl SimpleSystem for InputSystem {
|
||||
fn execute_mut(&mut self, world: &mut edict::World) -> anyhow::Result<()> {
|
||||
let queue = world.get_resource_mut::<EventQueue>()
|
||||
.and_then(|q| q.read_events::<InputEvent>());
|
||||
|
||||
if queue.is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut events = queue.unwrap();
|
||||
|
||||
while let Some(event) = events.pop_front() {
|
||||
self.update(&event, world);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Plugin that runs InputSystem
|
||||
#[derive(Default)]
|
||||
pub struct InputPlugin;
|
||||
|
||||
impl Plugin for InputPlugin {
|
||||
fn setup(&self, game: &mut crate::game::Game) {
|
||||
game.with_system("input", InputSystem, &[]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
use std::{hash::{Hash, Hasher}, collections::{HashMap, hash_map::DefaultHasher}};
|
||||
|
||||
use winit::event::ElementState;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||
pub enum ButtonEvent<T: Clone + Hash + Eq + PartialEq + 'static> {
|
||||
Pressed(T),
|
||||
Released(T),
|
||||
JustPressed(T),
|
||||
}
|
||||
|
||||
impl<T: Clone + Hash + Eq + PartialEq + 'static> ButtonEvent<T> {
|
||||
fn take_val(self) -> T {
|
||||
match self {
|
||||
ButtonEvent::Pressed(t) => t,
|
||||
ButtonEvent::JustPressed(t) => t,
|
||||
ButtonEvent::Released(t) => t,
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_val(&self) -> T {
|
||||
self.clone().take_val()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InputButtons<T: Clone + Hash + Eq + PartialEq + 'static> {
|
||||
// the u64 as the key is the hashed value of T. this makes it easier to
|
||||
// search for a button and see its state
|
||||
button_events: HashMap<u64, ButtonEvent<T>>,
|
||||
}
|
||||
|
||||
impl<T: Clone + Hash + Eq + PartialEq + 'static> Default for InputButtons<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + Hash + Eq + PartialEq + 'static> InputButtons<T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
button_events: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_button_hash(button: &T) -> u64 {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
button.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
/// Add a button event to this input type
|
||||
pub fn add_input(&mut self, button: ButtonEvent<T>) {
|
||||
let hash = Self::get_button_hash(&button.clone_val());
|
||||
|
||||
self.button_events.insert(hash, button);
|
||||
}
|
||||
|
||||
pub(crate) fn add_input_from_winit(&mut self, button: T, state: ElementState) {
|
||||
let event = match state {
|
||||
ElementState::Pressed if self.is_pressed(button.clone()) => ButtonEvent::Pressed(button),
|
||||
ElementState::Pressed => ButtonEvent::JustPressed(button),
|
||||
ElementState::Released => ButtonEvent::Released(button),
|
||||
};
|
||||
|
||||
self.add_input(event);
|
||||
}
|
||||
|
||||
/// Returns true if the button is pressed (or was just pressed)
|
||||
pub fn is_pressed(&self, button: T) -> bool
|
||||
{
|
||||
let hash = Self::get_button_hash(&button);
|
||||
match self.button_events.get(&hash) {
|
||||
Some(button_event) => match button_event {
|
||||
// this if statement should always be true, but just in case ;)
|
||||
ButtonEvent::Pressed(b) | ButtonEvent::JustPressed(b) if button == *b => true,
|
||||
_ => false,
|
||||
},
|
||||
None => false
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the button was just pressed this tick
|
||||
pub fn was_just_pressed(&self, button: T) -> bool {
|
||||
let hash = Self::get_button_hash(&button);
|
||||
match self.button_events.get(&hash) {
|
||||
Some(button_event) => match button_event {
|
||||
// this if statement should always be true, but just in case ;)
|
||||
ButtonEvent::JustPressed(b) if button == *b => true,
|
||||
_ => false,
|
||||
},
|
||||
None => false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct MouseMotion {
|
||||
pub delta: glam::Vec2,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct MouseWheel {
|
||||
pub delta: glam::Vec2,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct MouseExact {
|
||||
pub pos: glam::Vec2,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
|
||||
pub enum TouchPhase {
|
||||
Started,
|
||||
Moved,
|
||||
Ended,
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
impl From<winit::event::TouchPhase> for TouchPhase {
|
||||
fn from(value: winit::event::TouchPhase) -> Self {
|
||||
match value {
|
||||
winit::event::TouchPhase::Started => TouchPhase::Started,
|
||||
winit::event::TouchPhase::Moved => TouchPhase::Moved,
|
||||
winit::event::TouchPhase::Ended => TouchPhase::Ended,
|
||||
winit::event::TouchPhase::Cancelled => TouchPhase::Cancelled,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Translated `Force` from `winit` crate
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Force {
|
||||
Calibrated {
|
||||
force: f64,
|
||||
max_possible_force: f64,
|
||||
altitude_angle: Option<f64>,
|
||||
},
|
||||
Normalized(f64),
|
||||
}
|
||||
|
||||
impl From<winit::event::Force> for Force {
|
||||
fn from(value: winit::event::Force) -> Self {
|
||||
match value {
|
||||
winit::event::Force::Calibrated { force, max_possible_force, altitude_angle } => Self::Calibrated { force, max_possible_force, altitude_angle },
|
||||
winit::event::Force::Normalized(v) => Self::Normalized(v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Translated `WindowEvent::Touch` from `winit` crate
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Touch {
|
||||
pub phase: TouchPhase,
|
||||
pub location: glam::Vec2,
|
||||
pub force: Option<Force>,
|
||||
pub finger_id: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Touches {
|
||||
pub touches: Vec<Touch>,
|
||||
}
|
||||
|
||||
impl Default for Touches {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Touches {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
touches: Vec::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A mouse button event
|
||||
///
|
||||
/// Translated `WindowEvent::MouseButton` from `winit` crate
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum MouseButton {
|
||||
Left,
|
||||
Right,
|
||||
Middle,
|
||||
Other(u16),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum MouseScrollUnit {
|
||||
Line(glam::Vec2),
|
||||
Pixel(glam::Vec2)
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct MouseScroll {
|
||||
pub unit: MouseScrollUnit,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct CursorEnteredWindow;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct CursorLeftWindow;
|
|
@ -0,0 +1,11 @@
|
|||
pub mod system;
|
||||
pub use system::*;
|
||||
|
||||
pub mod input_event;
|
||||
pub use input_event::*;
|
||||
|
||||
pub mod events;
|
||||
pub use events::*;
|
||||
|
||||
pub mod buttons;
|
||||
pub use buttons::*;
|
|
@ -0,0 +1,125 @@
|
|||
use glam::Vec2;
|
||||
use winit::event::MouseScrollDelta;
|
||||
|
||||
use crate::{ecs::{SimpleSystem, EventQueue}, plugin::Plugin,};
|
||||
|
||||
use super::{events::*, InputButtons, InputEvent};
|
||||
|
||||
pub type KeyCode = winit::event::VirtualKeyCode;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct InputSystem;
|
||||
|
||||
impl InputSystem {
|
||||
pub fn process_event(&mut self, world: &mut edict::World, event: &InputEvent) -> bool {
|
||||
let event_queue = world.get_resource_mut::<EventQueue>();
|
||||
if event_queue.is_none() {
|
||||
return false;
|
||||
}
|
||||
let mut event_queue = event_queue.unwrap();
|
||||
|
||||
match event {
|
||||
InputEvent::KeyboardInput { input, .. } => {
|
||||
if let Some(code) = input.virtual_keycode {
|
||||
drop(event_queue);
|
||||
let e = world.with_resource(InputButtons::<winit::event::VirtualKeyCode>::new);
|
||||
//let mut e = with_resource_mut(world, || InputButtons::<KeyCode>::new());
|
||||
e.add_input_from_winit(code, input.state);
|
||||
}
|
||||
},
|
||||
InputEvent::MouseMotion { delta, .. } => {
|
||||
let delta = MouseMotion {
|
||||
delta: Vec2::new(delta.0 as f32, delta.1 as f32)
|
||||
};
|
||||
|
||||
event_queue.trigger_event(delta);
|
||||
},
|
||||
InputEvent::CursorMoved { position, .. } => {
|
||||
let exact = MouseExact {
|
||||
pos: Vec2::new(position.x as f32, position.y as f32)
|
||||
};
|
||||
|
||||
event_queue.trigger_event(exact);
|
||||
},
|
||||
InputEvent::CursorEntered { .. } => {
|
||||
let event = CursorEnteredWindow {};
|
||||
event_queue.trigger_event(event);
|
||||
},
|
||||
InputEvent::CursorLeft { .. } => {
|
||||
let event = CursorLeftWindow {};
|
||||
event_queue.trigger_event(event);
|
||||
},
|
||||
InputEvent::MouseWheel { delta, .. } => {
|
||||
let event = match delta {
|
||||
MouseScrollDelta::LineDelta(x, y) => MouseScroll {
|
||||
unit: MouseScrollUnit::Line(Vec2::new(*x, *y)),
|
||||
},
|
||||
MouseScrollDelta::PixelDelta(delta) => MouseScroll {
|
||||
unit: MouseScrollUnit::Pixel(Vec2::new(delta.x as f32, delta.y as f32)),
|
||||
},
|
||||
};
|
||||
|
||||
event_queue.trigger_event(event);
|
||||
}, //MouseButton
|
||||
InputEvent::MouseInput { button, state, .. } => {
|
||||
let button_event = match button {
|
||||
winit::event::MouseButton::Left => MouseButton::Left,
|
||||
winit::event::MouseButton::Right => MouseButton::Right,
|
||||
winit::event::MouseButton::Middle => MouseButton::Middle,
|
||||
winit::event::MouseButton::Other(v) => MouseButton::Other(*v),
|
||||
};
|
||||
|
||||
event_queue.trigger_event(button_event);
|
||||
drop(event_queue);
|
||||
|
||||
let e = world.with_resource(InputButtons::<MouseButton>::new);
|
||||
e.add_input_from_winit(button_event, *state);
|
||||
},
|
||||
InputEvent::Touch(t) => {
|
||||
drop(event_queue);
|
||||
|
||||
let touch = Touch {
|
||||
phase: TouchPhase::from(t.phase),
|
||||
location: Vec2::new(t.location.x as f32, t.location.y as f32),
|
||||
force: t.force.map(Force::from),
|
||||
finger_id: t.id,
|
||||
};
|
||||
|
||||
let touches = world.with_resource(Touches::new);
|
||||
touches.touches.push(touch);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl SimpleSystem for InputSystem {
|
||||
fn execute_mut(&mut self, world: &mut edict::World) -> anyhow::Result<()> {
|
||||
let queue = world.get_resource_mut::<EventQueue>()
|
||||
.and_then(|q| q.read_events::<InputEvent>());
|
||||
|
||||
if queue.is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut events = queue.unwrap();
|
||||
|
||||
while let Some(event) = events.pop_front() {
|
||||
self.process_event(world, &event);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Plugin that runs InputSystem
|
||||
#[derive(Default)]
|
||||
pub struct InputPlugin;
|
||||
|
||||
impl Plugin for InputPlugin {
|
||||
fn setup(&self, game: &mut crate::game::Game) {
|
||||
game.with_system("input", InputSystem, &[]);
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
pub mod game;
|
||||
pub mod render;
|
||||
pub mod input_event;
|
||||
pub mod resources;
|
||||
pub mod ecs;
|
||||
pub mod math;
|
||||
|
|
|
@ -6,7 +6,7 @@ use winit::{window::{Window, Fullscreen}, dpi::{LogicalPosition, LogicalSize, Ph
|
|||
|
||||
pub use winit::window::{CursorGrabMode, CursorIcon, Icon, Theme, WindowButtons, WindowLevel};
|
||||
|
||||
use crate::{plugin::Plugin, change_tracker::Ct, ecs::EventQueue, input_event::InputEvent};
|
||||
use crate::{plugin::Plugin, change_tracker::Ct, ecs::EventQueue, input::InputEvent};
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub enum WindowMode {
|
||||
|
|
Loading…
Reference in New Issue