Implement WASM support for bevy_winit (#503)

Also, replaced wasm_timer::Instant with instant::Instant as it is
used by winit WASM implementation.
This commit is contained in:
Tomasz Sterna 2020-09-16 22:40:32 +02:00 committed by GitHub
parent f5146c1896
commit 34c6f5f41b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 71 additions and 6 deletions

View file

@ -270,3 +270,8 @@ required-features = []
name = "headless_wasm" name = "headless_wasm"
path = "examples/wasm/headless_wasm.rs" path = "examples/wasm/headless_wasm.rs"
required-features = [] required-features = []
[[example]]
name = "winit_wasm"
path = "examples/wasm/winit_wasm.rs"
required-features = []

View file

@ -30,4 +30,4 @@ serde = { version = "1.0", features = ["derive"] }
[target.'cfg(target_arch = "wasm32")'.dependencies] [target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = { version = "0.2" } wasm-bindgen = { version = "0.2" }
web-sys = { version = "0.3", features = [ "Window" ] } web-sys = { version = "0.3", features = [ "Window" ] }
wasm-timer = "0.2.5" instant = "0.1.6"

View file

@ -6,10 +6,10 @@ use crate::{
}; };
use std::time::Duration; use std::time::Duration;
#[cfg(target_arch = "wasm32")]
use instant::Instant;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use std::{thread, time::Instant}; use std::{thread, time::Instant};
#[cfg(target_arch = "wasm32")]
use wasm_timer::Instant;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};

View file

@ -26,3 +26,6 @@ bevy_property = { path = "../bevy_property", version = "0.1" }
bevy_type_registry = { path = "../bevy_type_registry", version = "0.1" } bevy_type_registry = { path = "../bevy_type_registry", version = "0.1" }
bevy_math = { path = "../bevy_math", version = "0.1" } bevy_math = { path = "../bevy_math", version = "0.1" }
bevy_utils = { path = "../bevy_utils", version = "0.1" } bevy_utils = { path = "../bevy_utils", version = "0.1" }
[target.'cfg(target_arch = "wasm32")'.dependencies]
instant = "0.1.6"

View file

@ -1,5 +1,10 @@
use bevy_ecs::ResMut; use bevy_ecs::ResMut;
use std::time::{Duration, Instant}; use std::time::Duration;
#[cfg(target_arch = "wasm32")]
use instant::Instant;
#[cfg(not(target_arch = "wasm32"))]
use std::time::Instant;
/// Tracks elapsed time since the last update and since the App has started /// Tracks elapsed time since the last update and since the App has started
pub struct Time { pub struct Time {

View file

@ -25,3 +25,6 @@ bevy_utils = { path = "../bevy_utils", version = "0.1" }
# other # other
uuid = { version = "0.8", features = ["v4", "serde"] } uuid = { version = "0.8", features = ["v4", "serde"] }
parking_lot = "0.11.0" parking_lot = "0.11.0"
[target.'cfg(target_arch = "wasm32")'.dependencies]
instant = "0.1.6"

View file

@ -2,7 +2,12 @@ use crate::{Diagnostic, DiagnosticId, Diagnostics};
use bevy_ecs::{Profiler, Res, ResMut}; use bevy_ecs::{Profiler, Res, ResMut};
use bevy_utils::HashMap; use bevy_utils::HashMap;
use parking_lot::RwLock; use parking_lot::RwLock;
use std::{borrow::Cow, sync::Arc, time::Instant}; use std::{borrow::Cow, sync::Arc};
#[cfg(target_arch = "wasm32")]
use instant::Instant;
#[cfg(not(target_arch = "wasm32"))]
use std::time::Instant;
#[derive(Debug)] #[derive(Debug)]
struct SystemRunInfo { struct SystemRunInfo {

View file

@ -28,3 +28,6 @@ bevy_utils = { path = "../bevy_utils", version = "0.1" }
# other # other
winit = { version = "0.22.2", package = "cart-tmp-winit", default-features = false } winit = { version = "0.22.2", package = "cart-tmp-winit", default-features = false }
log = { version = "0.4", features = ["release_max_level_info"] } log = { version = "0.4", features = ["release_max_level_info"] }
[target.'cfg(target_arch = "wasm32")'.dependencies]
winit = { version = "0.22.2", package = "cart-tmp-winit", features = ["web-sys"] }

View file

@ -71,7 +71,7 @@ where
target_os = "netbsd", target_os = "netbsd",
target_os = "openbsd" target_os = "openbsd"
)))] )))]
fn run_return<F>(event_loop: &mut EventLoop<()>, event_handler: F) fn run_return<F>(_event_loop: &mut EventLoop<()>, _event_handler: F)
where where
F: FnMut(Event<'_, ()>, &EventLoopWindowTarget<()>, &mut ControlFlow), F: FnMut(Event<'_, ()>, &EventLoopWindowTarget<()>, &mut ControlFlow),
{ {

View file

@ -105,3 +105,9 @@ fn get_best_videomode(monitor: &winit::monitor::MonitorHandle) -> winit::monitor
modes.first().unwrap().clone() modes.first().unwrap().clone()
} }
// WARNING: this only works under the assumption that wasm runtime is single threaded
#[cfg(target_arch = "wasm32")]
unsafe impl Send for WinitWindows {}
#[cfg(target_arch = "wasm32")]
unsafe impl Sync for WinitWindows {}

View file

@ -0,0 +1,35 @@
extern crate console_error_panic_hook;
use bevy::prelude::*;
use std::panic;
fn main() {
panic::set_hook(Box::new(console_error_panic_hook::hook));
console_log::init_with_level(log::Level::Debug).expect("cannot initialize console_log");
App::build()
.add_default_plugins()
.add_startup_system(hello_wasm_system.system())
.add_system(counter.system())
.run();
}
fn hello_wasm_system() {
log::info!("hello wasm");
}
fn counter(mut state: Local<CounterState>, time: Res<Time>) {
if state.count % 60 == 0 {
log::info!(
"tick {} @ {:?} [Δ{}]",
state.count,
time.time_since_startup(),
time.delta_seconds
);
}
state.count += 1;
}
#[derive(Default)]
struct CounterState {
count: u32,
}