mirror of
https://github.com/rust-windowing/winit.git
synced 2026-06-27 07:03:15 -04:00
Gamepad device events - Web/WASM (#1414)
Add gamepad support for stdweb and web-sys, as well as web-specific gamepad examples. * [web] Fix compilation error from device api * [wasm] Apply device api changes * [wasm] Format and cleanup * [wasm32] Implement gamepad connections * [wasm] Harmonize * [Test] Made some tests with wasm-pack * Quick fix instant non supporting Hash trait * Fix on_received_character * [web_sys] Split add_event and add_window_event * [web] split device implementations * Update tests/web...still does not work * [tests/web] do not ignore index.html * [web/web_sys] split canvas and window * [tests/web] enable stack trace * [web] fix borrowmut * [web_sys] fix gamepad registration * [web] harmonize naming * [web_sys] create global emitter * [web] implement gamepad buttons * [web] implement gamepad axis * [web] cleanup * [web] update test * [web] move tests/web to examples/web * [web] axis does produce stick event * [web] Support Stick event * [web] implement gamepad to stdweb * [web] rename examples/web to examples/wasm * [web/web-sys] Move gamepad_manager from backend * [web/web_sys] implement EventLoop::gamepads * [web/web_sys] Drain gamepad events * [web/stdweb] apply web_sys changes * [web] update web/examples * [web] move gamepads code to gamepad_manager * [web] simplify and optimise * [web] replace EventCode to GamepadAxis and GamepadButton structs * [web] reuse gamepad events due to chrome issue * [web] rumble does not work * [web/stdweb] try debugging * [web] fix Chrome gamepad not updated * [web/stdweb] created an example * [examples] fix paths * fix warnings * [web/examples] update comments * [web/stdweb] add experimental support to vibrate() * [web] add CR
This commit is contained in:
committed by
GitHub
parent
0729074ce3
commit
e004bd2bb3
11
examples/web/gamepad/stdweb/Cargo.toml
Normal file
11
examples/web/gamepad/stdweb/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "stdweb-gamepad"
|
||||
version = "0.1.0"
|
||||
authors = ["furiouzz <christophe.massolin@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
winit = { path = "../../../../", features = [ "stdweb" ] }
|
||||
stdweb = "0.4.20"
|
||||
80
examples/web/gamepad/stdweb/src/main.rs
Normal file
80
examples/web/gamepad/stdweb/src/main.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use winit::{
|
||||
event::{device::GamepadEvent, Event, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
window::WindowBuilder,
|
||||
};
|
||||
|
||||
use stdweb::js;
|
||||
|
||||
/**
|
||||
* Build example (from examples/web/gamepad/stdweb):
|
||||
* cargo web build
|
||||
* Run example (from examples/web/gamepad/stdweb):
|
||||
* cargo web start
|
||||
* Development (from project root):
|
||||
* npx nodemon --watch src --watch examples/web/gamepad/stdweb/src -e rs --exec 'cargo web check'
|
||||
*/
|
||||
|
||||
pub fn main() {
|
||||
let event_loop = EventLoop::new();
|
||||
|
||||
let _window = WindowBuilder::new()
|
||||
.with_title("Gamepad tests")
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
|
||||
let deadzone = 0.12;
|
||||
|
||||
event_loop.run(move |event, _, control_flow| match event {
|
||||
Event::GamepadEvent(gamepad_handle, event) => match event {
|
||||
GamepadEvent::Axis {
|
||||
axis_id,
|
||||
axis,
|
||||
value,
|
||||
stick,
|
||||
} if value > deadzone => {
|
||||
let string = format!("Axis {:#?} {:#?} {:#?} {:#?}", axis_id, axis, value, stick);
|
||||
js! { console.log( @{string} ); }
|
||||
}
|
||||
|
||||
GamepadEvent::Stick {
|
||||
x_id,
|
||||
y_id,
|
||||
x_value,
|
||||
y_value,
|
||||
side,
|
||||
} if (x_value.powi(2) + y_value.powi(2)).sqrt() > deadzone => {
|
||||
let string = format!(
|
||||
"Stick {:#?} {:#?} {:#?} {:#?} {:#?}",
|
||||
x_id, y_id, x_value, y_value, side
|
||||
);
|
||||
js! { console.log( @{string} ); }
|
||||
}
|
||||
|
||||
GamepadEvent::Button {
|
||||
button_id,
|
||||
button,
|
||||
state,
|
||||
} => {
|
||||
let string = format!("Button {:#?} {:#?} {:#?}", button_id, button, state);
|
||||
js! { console.log( @{string} ); }
|
||||
}
|
||||
|
||||
GamepadEvent::Added => {
|
||||
let string = format!("[{:?}] {:#?}", gamepad_handle, event);
|
||||
js! { console.log( @{string} ); }
|
||||
}
|
||||
GamepadEvent::Removed => {
|
||||
let string = format!("[{:?}] {:#?}", gamepad_handle, event);
|
||||
js! { console.log( @{string} ); }
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
..
|
||||
} => *control_flow = ControlFlow::Exit,
|
||||
_ => (),
|
||||
});
|
||||
}
|
||||
7
examples/web/gamepad/websys/.gitignore
vendored
Normal file
7
examples/web/gamepad/websys/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
bin/
|
||||
pkg/
|
||||
wasm-pack.log
|
||||
.DS_Store
|
||||
20
examples/web/gamepad/websys/Cargo.toml
Normal file
20
examples/web/gamepad/websys/Cargo.toml
Normal file
@@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "websys-gamepad"
|
||||
version = "0.0.1"
|
||||
authors = ["The winit contributors", "Pierre Krieger <pierre.krieger1708@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
winit = { path = "../../../../", features = [ "web-sys" ] }
|
||||
wasm-bindgen = "0.2.45"
|
||||
wasm-bindgen-test = "0.3.8"
|
||||
web-sys = { version = "0.3.22", features = [ "console" ] }
|
||||
|
||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||
# logging them with `console.error`. This is great for development, but requires
|
||||
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
|
||||
# code size when deploying.
|
||||
console_error_panic_hook = "0.1.6"
|
||||
23
examples/web/gamepad/websys/files/gamepad.html
Normal file
23
examples/web/gamepad/websys/files/gamepad.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Gamepad</title>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="my_id"></canvas>
|
||||
<script>
|
||||
window.Module = {
|
||||
canvas: document.getElementById('my_id')
|
||||
}
|
||||
</script>
|
||||
<script type="module">
|
||||
import example_gamepad from "../pkg/websys_examples.js"
|
||||
example_gamepad()
|
||||
.then((m) => console.log('Success', m))
|
||||
.catch((e) => console.log('Ar error occured', e))
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
78
examples/web/gamepad/websys/src/lib.rs
Normal file
78
examples/web/gamepad/websys/src/lib.rs
Normal file
@@ -0,0 +1,78 @@
|
||||
mod utils;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
use winit::{
|
||||
event::{device::GamepadEvent, Event, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
window::WindowBuilder,
|
||||
};
|
||||
|
||||
/**
|
||||
* Build example (from examples/gamepad/websys):
|
||||
* wasm-pack build --target web
|
||||
* Run web server (from examples/gamepad/websys):
|
||||
* npx http-server
|
||||
* Open your browser at http://localhost:8000/files/${EXAMPLE}.html
|
||||
* Development (from project root):
|
||||
* npx nodemon --watch src --watch examples/web/gamepad/websys/src -e rs --exec 'cd examples/web/gamepad/websys && wasm-pack build --target web'
|
||||
*/
|
||||
|
||||
macro_rules! console_log {
|
||||
($($t:tt)*) => (web_sys::console::log_1(&format_args!($($t)*).to_string().into()))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn example_gamepad() {
|
||||
utils::set_panic_hook(); // needed for error stack trace
|
||||
let event_loop = EventLoop::new();
|
||||
|
||||
let _window = WindowBuilder::new()
|
||||
.with_title("Gamepad tests")
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
|
||||
let deadzone = 0.12;
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
match event {
|
||||
Event::GamepadEvent(gamepad_handle, event) => {
|
||||
match event {
|
||||
GamepadEvent::Axis {
|
||||
axis_id,
|
||||
axis,
|
||||
value,
|
||||
stick,
|
||||
} if value > deadzone => {
|
||||
console_log!("Axis {:#?} {:#?} {:#?} {:#?}", axis_id, axis, value, stick)
|
||||
},
|
||||
|
||||
GamepadEvent::Stick {
|
||||
x_id, y_id, x_value, y_value, side
|
||||
} if (x_value.powi(2) + y_value.powi(2)).sqrt() > deadzone => {
|
||||
console_log!("Stick {:#?} {:#?} {:#?} {:#?} {:#?}", x_id, y_id, x_value, y_value, side)
|
||||
},
|
||||
|
||||
GamepadEvent::Button {
|
||||
button_id,
|
||||
button,
|
||||
state,
|
||||
} => {
|
||||
console_log!("Button {:#?} {:#?} {:#?}", button_id, button, state)
|
||||
},
|
||||
|
||||
GamepadEvent::Added => {
|
||||
console_log!("[{:?}] {:#?}", gamepad_handle, event)
|
||||
},
|
||||
GamepadEvent::Removed => console_log!("[{:?}] {:#?}", gamepad_handle, event),
|
||||
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
..
|
||||
} => *control_flow = ControlFlow::Exit,
|
||||
_ => (),
|
||||
}
|
||||
});
|
||||
}
|
||||
10
examples/web/gamepad/websys/src/utils.rs
Normal file
10
examples/web/gamepad/websys/src/utils.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
pub fn set_panic_hook() {
|
||||
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||
// `set_panic_hook` function at least once during initialization, and then
|
||||
// we will get better error messages if our code ever panics.
|
||||
//
|
||||
// For more details see
|
||||
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||
// #[cfg(feature = "console_error_panic_hook")]
|
||||
console_error_panic_hook::set_once();
|
||||
}
|
||||
Reference in New Issue
Block a user