#![allow(clippy::disallowed_methods)]
use bevy::app::App;
use bevy::ecs::event::{EventReader, EventWriter};
use bevy::ecs::system::{ResMut, Resource};
use bevy::input::keyboard::KeyCode;
use bevy::input::mouse::{MouseButton, MouseMotion};
use bevy::input::{ButtonInput, ButtonState};
use bevy::prelude::Event as BevyEvent;
use bevy::reflect::Reflect;
use crossterm::event::Event as CrossEvent;
mod converters;
use crate::RawConsoleEvent;
#[derive(Debug, Clone, Copy, PartialEq, Eq, BevyEvent, Reflect)]
pub(crate) struct KeyboardInput {
key_code: KeyCode,
state: ButtonState,
}
#[allow(clippy::module_name_repetitions)]
#[derive(Debug, Clone, Copy, PartialEq, BevyEvent, Reflect)]
pub enum MouseInput {
Button(MouseButton, ButtonState, [u16; 2]),
Movement([u16; 2]),
}
#[derive(Debug, Default, Reflect, Resource)]
pub struct MouseState {
last_location: Option<[u16; 2]>,
}
#[derive(Debug, Clone, Copy, PartialEq, Reflect)]
pub struct WindowResized;
pub(crate) fn keyboard_input_system(
mut key_input: ResMut<ButtonInput<KeyCode>>,
mut keyboard_input_events: EventReader<KeyboardInput>,
) {
key_input.clear();
#[allow(clippy::needless_collect)]
let currently_pressed: Vec<KeyCode> = key_input.get_pressed().copied().collect();
let mut pressed_events = vec![];
for event in keyboard_input_events.read() {
match event.state {
ButtonState::Pressed => {
pressed_events.push(event.key_code);
key_input.press(event.key_code);
}
ButtonState::Released => key_input.release(event.key_code),
}
}
for released_key in currently_pressed
.into_iter()
.filter(|kc| !pressed_events.iter().any(|pe| pe == kc))
{
key_input.release(released_key);
}
}
pub(crate) fn mouse_input_system(
mut mouse_input: ResMut<ButtonInput<MouseButton>>,
mut mouse_state: ResMut<MouseState>,
mut mouse_input_events: EventReader<MouseInput>,
mut mouse_motion_event_writer: EventWriter<MouseMotion>,
) {
mouse_input.clear();
for event in mouse_input_events.read() {
let new_location = match event {
MouseInput::Button(_, _, loc) | MouseInput::Movement(loc) => loc,
};
if let Some(last_location) = mouse_state.last_location {
mouse_motion_event_writer.send(MouseMotion {
delta: bevy::math::Vec2 {
x: f32::from(new_location[0]) - f32::from(last_location[0]),
y: f32::from(new_location[1]) - f32::from(last_location[1]),
},
});
}
mouse_state.last_location = Some(*new_location);
if let MouseInput::Button(btn, state, _) = event {
match state {
ButtonState::Pressed => mouse_input.press(*btn),
ButtonState::Released => mouse_input.release(*btn),
}
}
}
}
pub(crate) fn event_handler(app: &mut App, event: CrossEvent) {
match event {
CrossEvent::FocusGained | CrossEvent::FocusLost => {
}
CrossEvent::Key(event) => {
for ki in converters::convert_keyboard_input(event) {
app.world.send_event(ki);
}
}
CrossEvent::Mouse(event) => {
app.world.send_event(converters::convert_mouse_input(event));
}
CrossEvent::Paste(ref _data) => {
}
CrossEvent::Resize(_width, _height) => {
}
}
app.world.send_event(RawConsoleEvent(event));
}