Files
winit/src/platform_impl/web/web_sys/window.rs
Christophe Massolin e004bd2bb3 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
2020-03-03 09:56:11 -05:00

89 lines
2.5 KiB
Rust

use super::gamepad;
use crate::error::OsError as RootOE;
use crate::platform_impl::OsError;
use std::{cell::RefCell, rc::Rc};
use wasm_bindgen::{closure::Closure, JsCast};
use web_sys::GamepadEvent;
#[derive(Debug)]
pub struct Shared(pub Rc<RefCell<Window>>);
#[derive(Debug)]
pub struct Window {
raw: web_sys::Window,
on_gamepad_connected: Option<Closure<dyn FnMut(GamepadEvent)>>,
on_gamepad_disconnected: Option<Closure<dyn FnMut(GamepadEvent)>>,
}
impl Shared {
pub fn create() -> Result<Self, RootOE> {
let global = Window::create()?;
Ok(Shared(Rc::new(RefCell::new(global))))
}
}
impl Clone for Shared {
fn clone(&self) -> Self {
Shared(self.0.clone())
}
}
impl Window {
pub fn create() -> Result<Self, RootOE> {
let raw =
web_sys::window().ok_or(os_error!(OsError("Failed to obtain window".to_owned())))?;
Ok(Window {
raw,
on_gamepad_connected: None,
on_gamepad_disconnected: None,
})
}
pub fn on_gamepad_connected<F>(&mut self, mut handler: F)
where
F: 'static + FnMut(gamepad::Gamepad),
{
self.on_gamepad_connected = Some(self.add_event(
"gamepadconnected",
move |event: GamepadEvent| {
let gamepad = event
.gamepad()
.expect("[gamepadconnected] expected gamepad");
handler(gamepad::Gamepad::new(gamepad));
},
))
}
pub fn on_gamepad_disconnected<F>(&mut self, mut handler: F)
where
F: 'static + FnMut(gamepad::Gamepad),
{
self.on_gamepad_disconnected = Some(self.add_event(
"gamepaddisconnected",
move |event: GamepadEvent| {
let gamepad = event
.gamepad()
.expect("[gamepaddisconnected] expected gamepad");
handler(gamepad::Gamepad::new(gamepad));
},
))
}
fn add_event<E, F>(&self, event_name: &str, mut handler: F) -> Closure<dyn FnMut(E)>
where
E: 'static + AsRef<web_sys::Event> + wasm_bindgen::convert::FromWasmAbi,
F: 'static + FnMut(E),
{
let closure = Closure::wrap(Box::new(move |event: E| {
handler(event);
}) as Box<dyn FnMut(E)>);
self.raw
.add_event_listener_with_callback(event_name, &closure.as_ref().unchecked_ref())
.expect("Failed to add event listener with callback");
closure
}
}