Start reworking event system
This commit is contained in:
parent
52dcbc6353
commit
ae1e06d52e
9 changed files with 201 additions and 313 deletions
|
@ -60,7 +60,7 @@ impl Context {
|
|||
pub fn next_frame<C, F>(&mut self, world: &mut World, mut f: F) -> Result<bool>
|
||||
where
|
||||
C: Send + Sync + 'static,
|
||||
F: FnMut(&mut World, &mut C, Event) -> Result<()> + Send + Sync + 'static,
|
||||
F: FnMut(&mut World, &mut C, Event<'_>) -> Result<()> + Send + Sync + 'static,
|
||||
{
|
||||
let render_core = self.render_core.clone();
|
||||
let consumer = world.resources.get_mut_unchecked::<C>();
|
||||
|
@ -116,19 +116,9 @@ impl Context {
|
|||
self.core.queue()
|
||||
}
|
||||
|
||||
pub fn controllers(&self) -> &[Arc<RwLock<Controller>>] {
|
||||
pub fn controllers(&self) -> impl Iterator<Item = &Controller> {
|
||||
self.presentation.event_system().controllers()
|
||||
}
|
||||
|
||||
pub fn active_controller(&self) -> &Option<Arc<RwLock<Controller>>> {
|
||||
self.presentation.event_system().active_controller()
|
||||
}
|
||||
|
||||
pub fn set_active_controller(&mut self, controller: &Arc<RwLock<Controller>>) {
|
||||
self.presentation
|
||||
.event_system_mut()
|
||||
.set_active_controller(controller)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Context {
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
// use super::engine_object_data::{EngineObjectAccess, EngineObjectDataHandle};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum EngineEvent {
|
||||
pub enum EngineEvent<'a> {
|
||||
MouseMotion(u32, u32),
|
||||
MouseButtonDown(MouseButton),
|
||||
MouseButtonUp(MouseButton),
|
||||
|
@ -21,14 +16,14 @@ pub enum EngineEvent {
|
|||
ButtonUp(ControllerButton),
|
||||
ControllerAxis(ControllerAxis),
|
||||
|
||||
ControllerAdded(Arc<RwLock<Controller>>),
|
||||
ControllerRemoved(Arc<RwLock<Controller>>),
|
||||
ControllerAdded(&'a Controller),
|
||||
ControllerRemoved(&'a Controller),
|
||||
|
||||
FileDrop(String),
|
||||
}
|
||||
|
||||
pub trait EventConsumer: Send + Sync + 'static {
|
||||
fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()>;
|
||||
fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()>;
|
||||
}
|
||||
|
||||
pub struct InputMap {
|
||||
|
@ -42,7 +37,7 @@ impl Engine {
|
|||
gui_handler: &GuiHandler,
|
||||
input: &InputMap,
|
||||
consumer: &mut T,
|
||||
event: Event,
|
||||
event: Event<'_>,
|
||||
) -> anyhow::Result<()> {
|
||||
match event {
|
||||
Event::MouseMotion(x, y) => {
|
||||
|
@ -71,15 +66,13 @@ impl Engine {
|
|||
Event::TextInput(text) => {
|
||||
Self::text_input(gui_handler, text)?;
|
||||
}
|
||||
Event::ControllerButtonDown(button) => {
|
||||
Event::ControllerButtonDown(_controller, button) => {
|
||||
Self::button_down_event(world, gui_handler, consumer, button)?;
|
||||
}
|
||||
Event::ControllerButtonUp(button) => {
|
||||
Event::ControllerButtonUp(_controller, button) => {
|
||||
Self::button_up_event(world, consumer, button)?;
|
||||
}
|
||||
Event::ControllerAxis(controller) => {
|
||||
let controller = controller.read().unwrap();
|
||||
|
||||
if !gui_handler.check_navigatable()? {
|
||||
Self::axis_event(world, consumer, &controller)?
|
||||
} else {
|
||||
|
@ -92,6 +85,13 @@ impl Engine {
|
|||
Event::ControllerRemoved(controller) => {
|
||||
Self::controller_removed(world, consumer, controller)?
|
||||
}
|
||||
|
||||
Event::JoystickAxis(_joystick) => todo!(),
|
||||
Event::JoystickButtonDown(_joystick) => todo!(),
|
||||
Event::JoystickButtonUp(_joystick) => todo!(),
|
||||
Event::JoystickAdded(_joystick) => todo!(),
|
||||
Event::JoystickRemoved(_joystick) => todo!(),
|
||||
|
||||
Event::FileDrop(filename) => consumer.event(world, EngineEvent::FileDrop(filename))?,
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ impl Engine {
|
|||
fn controller_added<T: EventConsumer>(
|
||||
world: &mut World,
|
||||
consumer: &mut T,
|
||||
controller: Arc<RwLock<Controller>>,
|
||||
controller: &Controller,
|
||||
) -> Result<()> {
|
||||
consumer.event(world, EngineEvent::ControllerAdded(controller))?;
|
||||
|
||||
|
@ -115,7 +115,7 @@ impl Engine {
|
|||
fn controller_removed<T: EventConsumer>(
|
||||
world: &mut World,
|
||||
consumer: &mut T,
|
||||
controller: Arc<RwLock<Controller>>,
|
||||
controller: &Controller,
|
||||
) -> Result<()> {
|
||||
consumer.event(world, EngineEvent::ControllerRemoved(controller))?;
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ impl EngineSettings {
|
|||
button: ControllerButton,
|
||||
) -> Result<Option<Arc<Image>>> {
|
||||
// TODO: don't check it every time we request a button
|
||||
self.check_controller(context)?;
|
||||
// self.check_controller(context)?;
|
||||
|
||||
match self.current_controller_type.read().unwrap().as_ref() {
|
||||
Some(controller_type) => Ok(Some(self.controller_button_for(
|
||||
|
@ -347,61 +347,61 @@ impl EngineSettings {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_controller(&self, context: &Context) -> Result<()> {
|
||||
let active_controller = context.active_controller();
|
||||
// fn check_controller(&self, context: &Context) -> Result<()> {
|
||||
// let active_controller = context.active_controller();
|
||||
|
||||
match &active_controller {
|
||||
// there is an controller connected
|
||||
Some(controller) => {
|
||||
let controller_name = controller.read().unwrap().name().clone();
|
||||
// match &active_controller {
|
||||
// // there is an controller connected
|
||||
// Some(controller) => {
|
||||
// let controller_name = controller.read().unwrap().name().clone();
|
||||
|
||||
// predict controller type from name
|
||||
let controller_type = if controller_name.contains("PS4") {
|
||||
ControllerType::PS4
|
||||
} else if controller_name.contains("Steam") {
|
||||
ControllerType::Steam
|
||||
} else {
|
||||
ControllerType::XBox
|
||||
};
|
||||
// // predict controller type from name
|
||||
// let controller_type = if controller_name.contains("PS4") {
|
||||
// ControllerType::PS4
|
||||
// } else if controller_name.contains("Steam") {
|
||||
// ControllerType::Steam
|
||||
// } else {
|
||||
// ControllerType::XBox
|
||||
// };
|
||||
|
||||
let mut current_controller_type = self.current_controller_type.write().unwrap();
|
||||
// let mut current_controller_type = self.current_controller_type.write().unwrap();
|
||||
|
||||
// check if current controller type is set
|
||||
// // check if current controller type is set
|
||||
|
||||
if current_controller_type.is_some() {
|
||||
// if controller type is set, check if it is different
|
||||
if *current_controller_type.as_ref().unwrap() != controller_type {
|
||||
*current_controller_type = Some(controller_type);
|
||||
// if current_controller_type.is_some() {
|
||||
// // if controller type is set, check if it is different
|
||||
// if *current_controller_type.as_ref().unwrap() != controller_type {
|
||||
// *current_controller_type = Some(controller_type);
|
||||
|
||||
let mut map = self.controller_buttons.write().unwrap();
|
||||
// let mut map = self.controller_buttons.write().unwrap();
|
||||
|
||||
// clear map if filled
|
||||
if !map.is_empty() {
|
||||
map.clear();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// set the controller type
|
||||
*current_controller_type = Some(controller_type);
|
||||
}
|
||||
}
|
||||
// there is no controller connected
|
||||
None => {
|
||||
let mut current_controller_type = self.current_controller_type.write().unwrap();
|
||||
let mut map = self.controller_buttons.write().unwrap();
|
||||
// // clear map if filled
|
||||
// if !map.is_empty() {
|
||||
// map.clear();
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// // set the controller type
|
||||
// *current_controller_type = Some(controller_type);
|
||||
// }
|
||||
// }
|
||||
// // there is no controller connected
|
||||
// None => {
|
||||
// let mut current_controller_type = self.current_controller_type.write().unwrap();
|
||||
// let mut map = self.controller_buttons.write().unwrap();
|
||||
|
||||
// clear current type if set
|
||||
if current_controller_type.is_some() {
|
||||
*current_controller_type = None;
|
||||
}
|
||||
// // clear current type if set
|
||||
// if current_controller_type.is_some() {
|
||||
// *current_controller_type = None;
|
||||
// }
|
||||
|
||||
// clear map if filled
|
||||
if !map.is_empty() {
|
||||
map.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
// // clear map if filled
|
||||
// if !map.is_empty() {
|
||||
// map.clear();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// Ok(())
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ impl GameState {
|
|||
}
|
||||
|
||||
impl EventConsumer for GameState {
|
||||
fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()> {
|
||||
fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> {
|
||||
match self {
|
||||
GameState::Startup => (),
|
||||
GameState::Loading => (),
|
||||
|
@ -72,7 +72,7 @@ impl Game {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()> {
|
||||
fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use ui::prelude::*;
|
|||
|
||||
use super::controlleraxis::ControllerAxis;
|
||||
|
||||
use sdl2;
|
||||
use sdl2::{self, GameControllerSubsystem};
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum State {
|
||||
|
@ -51,7 +51,7 @@ pub struct Controller {
|
|||
|
||||
impl Controller {
|
||||
pub fn new(
|
||||
controller_subsystem: &sdl2::GameControllerSubsystem,
|
||||
controller_subsystem: &GameControllerSubsystem,
|
||||
id: u32,
|
||||
deadzones: ControllerDeadzones,
|
||||
) -> Result<Controller> {
|
||||
|
@ -199,7 +199,7 @@ impl Controller {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_left_x(&mut self, x: f32) {
|
||||
pub(crate) fn set_left_x(&mut self, x: f32) {
|
||||
self.controller_axis.left_stick.x = x;
|
||||
|
||||
let direction = self.check_direction(
|
||||
|
@ -212,7 +212,7 @@ impl Controller {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_left_y(&mut self, y: f32) {
|
||||
pub(crate) fn set_left_y(&mut self, y: f32) {
|
||||
self.controller_axis.left_stick.y = y;
|
||||
|
||||
let direction = self.check_direction(
|
||||
|
@ -225,15 +225,15 @@ impl Controller {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_right_x(&mut self, x: f32) {
|
||||
pub(crate) fn set_right_x(&mut self, x: f32) {
|
||||
self.controller_axis.right_stick.x = x;
|
||||
}
|
||||
|
||||
pub fn set_right_y(&mut self, y: f32) {
|
||||
pub(crate) fn set_right_y(&mut self, y: f32) {
|
||||
self.controller_axis.right_stick.y = y;
|
||||
}
|
||||
|
||||
pub fn set_left_trigger(&mut self, trigger: f32) {
|
||||
pub(crate) fn set_left_trigger(&mut self, trigger: f32) {
|
||||
self.controller_axis.left_trigger = trigger;
|
||||
|
||||
let left_trigger = self.check_trigger(trigger, self.last_left_trigger);
|
||||
|
@ -244,7 +244,7 @@ impl Controller {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_right_trigger(&mut self, trigger: f32) {
|
||||
pub(crate) fn set_right_trigger(&mut self, trigger: f32) {
|
||||
self.controller_axis.right_trigger = trigger;
|
||||
|
||||
let right_trigger = self.check_trigger(trigger, self.last_right_trigger);
|
||||
|
|
|
@ -2,7 +2,9 @@ use sdl2;
|
|||
use sdl2::EventPump;
|
||||
use sdl2::EventSubsystem;
|
||||
use sdl2::GameControllerSubsystem;
|
||||
use sdl2::JoystickSubsystem;
|
||||
use sdl2::Sdl;
|
||||
use sdl2::controller::Axis;
|
||||
use sdl2::controller::Button;
|
||||
use sdl2::event::{Event as SdlEvent, EventType as SdlEventType, WindowEvent};
|
||||
use sdl2::keyboard::Keycode;
|
||||
|
@ -10,11 +12,12 @@ use sdl2::mouse::{MouseButton as SdlMouseButton, MouseUtil, MouseWheelDirection}
|
|||
|
||||
use ui::prelude::*;
|
||||
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::Result;
|
||||
|
||||
use super::controller::{Controller, ControllerDeadzones};
|
||||
use super::joystick::Joystick;
|
||||
|
||||
fn convert_button(button: Button) -> ControllerButton {
|
||||
match button {
|
||||
|
@ -51,7 +54,7 @@ fn convert_button(button: Button) -> ControllerButton {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Event {
|
||||
pub enum Event<'a> {
|
||||
// mouse events
|
||||
MouseMotion(u32, u32),
|
||||
MouseButtonDown(MouseButton),
|
||||
|
@ -64,11 +67,18 @@ pub enum Event {
|
|||
TextInput(String),
|
||||
|
||||
// controller events
|
||||
ControllerAxis(Arc<RwLock<Controller>>),
|
||||
ControllerButtonDown(ControllerButton),
|
||||
ControllerButtonUp(ControllerButton),
|
||||
ControllerAdded(Arc<RwLock<Controller>>),
|
||||
ControllerRemoved(Arc<RwLock<Controller>>),
|
||||
ControllerAxis(&'a Controller),
|
||||
ControllerButtonDown(&'a Controller, ControllerButton),
|
||||
ControllerButtonUp(&'a Controller, ControllerButton),
|
||||
ControllerAdded(&'a Controller),
|
||||
ControllerRemoved(&'a Controller),
|
||||
|
||||
// joystick events
|
||||
JoystickAxis(&'a Joystick),
|
||||
JoystickButtonDown(&'a Joystick),
|
||||
JoystickButtonUp(&'a Joystick),
|
||||
JoystickAdded(&'a Joystick),
|
||||
JoystickRemoved(&'a Joystick),
|
||||
|
||||
// drag'n'drop
|
||||
FileDrop(String),
|
||||
|
@ -78,12 +88,13 @@ pub struct EventSystem {
|
|||
event_pump: EventPump,
|
||||
mouse: MouseUtil,
|
||||
controller_subsystem: GameControllerSubsystem,
|
||||
joystick_subsystem: JoystickSubsystem,
|
||||
event_subsystem: EventSubsystem,
|
||||
|
||||
controller_deadzones: ControllerDeadzones,
|
||||
|
||||
selected_controller: Option<Arc<RwLock<Controller>>>,
|
||||
connected_controllers: Vec<Arc<RwLock<Controller>>>,
|
||||
connected_controllers: HashMap<u32, Controller>,
|
||||
connected_joysticks: HashMap<u32, Joystick>,
|
||||
}
|
||||
|
||||
impl EventSystem {
|
||||
|
@ -96,12 +107,13 @@ impl EventSystem {
|
|||
controller_subsystem: sdl2_context
|
||||
.game_controller()
|
||||
.map_err(|s| anyhow::Error::msg(s))?,
|
||||
joystick_subsystem: sdl2_context.joystick().map_err(|s| anyhow::Error::msg(s))?,
|
||||
event_subsystem: sdl2_context.event().map_err(|s| anyhow::Error::msg(s))?,
|
||||
|
||||
controller_deadzones: ControllerDeadzones::default(),
|
||||
|
||||
selected_controller: None,
|
||||
connected_controllers: Vec::new(),
|
||||
connected_controllers: HashMap::new(),
|
||||
connected_joysticks: HashMap::new(),
|
||||
};
|
||||
|
||||
event_system.disable_mouse();
|
||||
|
@ -180,11 +192,9 @@ impl EventSystem {
|
|||
|
||||
pub fn poll_events<F, R>(&mut self, mut event_callback: F, mut resize: R) -> Result<bool>
|
||||
where
|
||||
F: FnMut(Event) -> Result<()>,
|
||||
F: FnMut(Event<'_>) -> Result<()>,
|
||||
R: FnMut(u32, u32) -> Result<()>,
|
||||
{
|
||||
let mut controller_axis_changed = false;
|
||||
|
||||
for event in self.event_pump.poll_iter() {
|
||||
match event {
|
||||
SdlEvent::Window { win_event, .. } => match win_event {
|
||||
|
@ -266,7 +276,6 @@ impl EventSystem {
|
|||
which as u32,
|
||||
self.controller_deadzones.clone(),
|
||||
) {
|
||||
let controller = {
|
||||
if cfg!(debug_assertions) {
|
||||
println!(
|
||||
"Controller added: {}({})",
|
||||
|
@ -275,175 +284,70 @@ impl EventSystem {
|
|||
);
|
||||
}
|
||||
|
||||
let arc_controller = Arc::new(RwLock::new(controller));
|
||||
self.connected_controllers.push(arc_controller.clone());
|
||||
|
||||
if self.selected_controller.is_none() {
|
||||
if cfg!(debug_assertions) {
|
||||
let contr = arc_controller.read().unwrap();
|
||||
|
||||
println!(
|
||||
"New active controller: {}({})",
|
||||
contr.name(),
|
||||
contr.id()
|
||||
);
|
||||
}
|
||||
|
||||
self.selected_controller = Some(arc_controller.clone());
|
||||
}
|
||||
|
||||
arc_controller
|
||||
};
|
||||
|
||||
event_callback(Event::ControllerAdded(controller))?;
|
||||
event_callback(Event::ControllerAdded(&controller))?;
|
||||
self.connected_controllers
|
||||
.insert(controller.id(), controller);
|
||||
}
|
||||
}
|
||||
SdlEvent::ControllerDeviceRemoved { which, .. } => {
|
||||
let removed_controller = {
|
||||
if self.selected_controller.is_some() {
|
||||
if let Some(controller) = self.connected_controllers.remove(&which) {
|
||||
if cfg!(debug_assertions) {
|
||||
let contr =
|
||||
self.selected_controller.as_ref().unwrap().read().unwrap();
|
||||
|
||||
println!(
|
||||
"Remove active controller: {}({})",
|
||||
contr.name(),
|
||||
contr.id()
|
||||
);
|
||||
}
|
||||
|
||||
// unwrap is save since we just tested for `is_some()`
|
||||
if self
|
||||
.selected_controller
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
.id()
|
||||
== which
|
||||
{
|
||||
self.selected_controller = None;
|
||||
}
|
||||
}
|
||||
|
||||
self.connected_controllers
|
||||
.iter()
|
||||
.position(|controller_cell| {
|
||||
let controller = controller_cell.read().unwrap();
|
||||
controller.id() == which
|
||||
})
|
||||
.map(|remove_index| {
|
||||
let removed_controller =
|
||||
self.connected_controllers.swap_remove(remove_index);
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
let contr = removed_controller.read().unwrap();
|
||||
println!(
|
||||
"Controller removed: {}({})",
|
||||
contr.name(),
|
||||
contr.id()
|
||||
controller.name(),
|
||||
controller.id()
|
||||
);
|
||||
}
|
||||
|
||||
// if we removed the selected controller, take the controller at the first position if possible
|
||||
if self.selected_controller.is_none()
|
||||
&& !self.connected_controllers.is_empty()
|
||||
{
|
||||
if cfg!(debug_assertions) {
|
||||
println!(
|
||||
"Set active controller: {}",
|
||||
self.connected_controllers[0].read().unwrap().name()
|
||||
);
|
||||
}
|
||||
|
||||
self.selected_controller =
|
||||
Some(self.connected_controllers[0].clone());
|
||||
}
|
||||
|
||||
removed_controller
|
||||
})
|
||||
};
|
||||
|
||||
if let Some(removed_controller) = removed_controller {
|
||||
event_callback(Event::ControllerRemoved(removed_controller))?;
|
||||
event_callback(Event::ControllerRemoved(&controller))?;
|
||||
}
|
||||
}
|
||||
// maybe make use of `which`, for support of multiple controllers
|
||||
SdlEvent::ControllerButtonDown {
|
||||
button,
|
||||
// which,
|
||||
..
|
||||
} => {
|
||||
// // only call back if the selected controller pressed a button
|
||||
// match self.selected_controller.read().unwrap().as_ref() {
|
||||
// Some(selected_controller) => {
|
||||
// if selected_controller.read().unwrap().id() != which {
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// None => continue,
|
||||
// }
|
||||
|
||||
event_callback(Event::ControllerButtonDown(convert_button(button)))?;
|
||||
SdlEvent::ControllerButtonDown { button, which, .. } => {
|
||||
event_callback(Event::ControllerButtonDown(
|
||||
self.connected_controllers.get(&which).unwrap(),
|
||||
convert_button(button),
|
||||
))?;
|
||||
}
|
||||
// maybe make use of `which`, for support of multiple controllers
|
||||
SdlEvent::ControllerButtonUp {
|
||||
button,
|
||||
// which,
|
||||
..
|
||||
} => {
|
||||
// // only call back if the selected controller released a button
|
||||
// match self.selected_controller.read().unwrap().as_ref() {
|
||||
// Some(selected_controller) => {
|
||||
// if selected_controller.read().unwrap().id() != which {
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// None => continue,
|
||||
// }
|
||||
|
||||
event_callback(Event::ControllerButtonUp(convert_button(button)))?;
|
||||
SdlEvent::ControllerButtonUp { button, which, .. } => {
|
||||
event_callback(Event::ControllerButtonUp(
|
||||
self.connected_controllers.get(&which).unwrap(),
|
||||
convert_button(button),
|
||||
))?;
|
||||
}
|
||||
SdlEvent::ControllerAxisMotion {
|
||||
axis,
|
||||
value,
|
||||
// which,
|
||||
..
|
||||
axis, value, which, ..
|
||||
} => {
|
||||
if let Some(controller) = self.selected_controller.as_mut() {
|
||||
let mut controller = controller.write().unwrap();
|
||||
|
||||
// // only update axis, when selected controller made the change
|
||||
// if controller.id() != which {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// 1 / 32768 = 0,000030518
|
||||
let controller = self.connected_controllers.get_mut(&which).unwrap();
|
||||
let normalized = value as f32 * 0.000_030_518;
|
||||
|
||||
match axis {
|
||||
sdl2::controller::Axis::LeftX => {
|
||||
Axis::LeftX => {
|
||||
controller.set_left_x(normalized);
|
||||
}
|
||||
sdl2::controller::Axis::RightX => {
|
||||
Axis::RightX => {
|
||||
controller.set_right_x(normalized);
|
||||
}
|
||||
sdl2::controller::Axis::LeftY => {
|
||||
Axis::LeftY => {
|
||||
controller.set_left_y(-normalized);
|
||||
}
|
||||
sdl2::controller::Axis::RightY => {
|
||||
Axis::RightY => {
|
||||
controller.set_right_y(normalized);
|
||||
}
|
||||
sdl2::controller::Axis::TriggerLeft => {
|
||||
Axis::TriggerLeft => {
|
||||
controller.set_left_trigger(normalized);
|
||||
}
|
||||
sdl2::controller::Axis::TriggerRight => {
|
||||
Axis::TriggerRight => {
|
||||
controller.set_right_trigger(normalized);
|
||||
}
|
||||
}
|
||||
|
||||
controller_axis_changed = true;
|
||||
event_callback(Event::ControllerAxis(&*controller))?;
|
||||
}
|
||||
SdlEvent::JoyDeviceAdded { which, .. } => {
|
||||
let joystick = Joystick::new(&self.joystick_subsystem, which)?;
|
||||
|
||||
event_callback(Event::JoystickAdded(&joystick))?;
|
||||
self.connected_joysticks.insert(joystick.id(), joystick);
|
||||
}
|
||||
SdlEvent::DropFile { filename, .. } => {
|
||||
event_callback(Event::FileDrop(filename))?;
|
||||
|
@ -452,58 +356,11 @@ impl EventSystem {
|
|||
}
|
||||
}
|
||||
|
||||
if controller_axis_changed {
|
||||
if let Some(controller) = &self.selected_controller {
|
||||
let (left_trigger, right_trigger) = {
|
||||
let mut controller_lock = controller.write().unwrap();
|
||||
|
||||
(
|
||||
controller_lock.left_trigger(),
|
||||
controller_lock.right_trigger(),
|
||||
)
|
||||
};
|
||||
|
||||
if let Some(right_trigger) = right_trigger {
|
||||
if right_trigger {
|
||||
event_callback(Event::ControllerButtonDown(
|
||||
ControllerButton::RightTrigger,
|
||||
))?;
|
||||
} else {
|
||||
event_callback(Event::ControllerButtonUp(ControllerButton::RightTrigger))?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(left_trigger) = left_trigger {
|
||||
if left_trigger {
|
||||
event_callback(Event::ControllerButtonDown(ControllerButton::LeftTrigger))?;
|
||||
} else {
|
||||
event_callback(Event::ControllerButtonUp(ControllerButton::LeftTrigger))?;
|
||||
}
|
||||
}
|
||||
|
||||
event_callback(Event::ControllerAxis(controller.clone()))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn controllers(&self) -> &[Arc<RwLock<Controller>>] {
|
||||
&self.connected_controllers
|
||||
}
|
||||
|
||||
pub fn active_controller(&self) -> &Option<Arc<RwLock<Controller>>> {
|
||||
&self.selected_controller
|
||||
}
|
||||
|
||||
pub fn set_active_controller(&mut self, controller: &Arc<RwLock<Controller>>) {
|
||||
if let Some(res) = self
|
||||
.connected_controllers
|
||||
.iter()
|
||||
.find(|c| Arc::ptr_eq(c, controller))
|
||||
{
|
||||
self.selected_controller = Some(res.clone());
|
||||
}
|
||||
pub fn controllers(&self) -> impl Iterator<Item = &Controller> {
|
||||
self.connected_controllers.values()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
40
presentation/src/input/joystick.rs
Normal file
40
presentation/src/input/joystick.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use anyhow::Result;
|
||||
use sdl2::JoystickSubsystem;
|
||||
|
||||
pub struct Joystick {
|
||||
_sdl2_joystick: sdl2::joystick::Joystick,
|
||||
id: u32,
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl Joystick {
|
||||
pub fn new(joystick_subsystem: &JoystickSubsystem, id: u32) -> Result<Self> {
|
||||
let sdl2_joystick = joystick_subsystem.open(id)?;
|
||||
|
||||
Ok(Self {
|
||||
name: sdl2_joystick.name(),
|
||||
id,
|
||||
_sdl2_joystick: sdl2_joystick,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn id(&self) -> u32 {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Joystick {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Joystick")
|
||||
.field("id", &self.id)
|
||||
.field("name", &self.name)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for Joystick {}
|
||||
unsafe impl Sync for Joystick {}
|
|
@ -3,3 +3,4 @@
|
|||
pub mod controller;
|
||||
pub mod controlleraxis;
|
||||
pub mod eventsystem;
|
||||
pub mod joystick;
|
||||
|
|
|
@ -113,7 +113,7 @@ impl PresentationCore {
|
|||
|
||||
pub fn poll_events<F, R>(&mut self, event_callback: F, resize_event: R) -> Result<bool>
|
||||
where
|
||||
F: FnMut(Event) -> Result<()>,
|
||||
F: FnMut(Event<'_>) -> Result<()>,
|
||||
R: FnMut(u32, u32) -> Result<()>,
|
||||
{
|
||||
self.event_system.poll_events(event_callback, resize_event)
|
||||
|
|
Loading…
Reference in a new issue