Remove wasm specific examples (#3705)

# Objective

- There are wasm specific examples, which is misleading as now it works by default
- I saw a few people on discord trying to work through those examples that are very limited

## Solution

- Remove them and update the instructions
This commit is contained in:
François 2022-01-17 22:38:05 +00:00
parent 836ffeda31
commit e88e394feb
8 changed files with 24 additions and 237 deletions

View file

@ -498,27 +498,6 @@ path = "examples/window/transparent_window.rs"
name = "window_settings"
path = "examples/window/window_settings.rs"
# WASM
[[example]]
name = "hello_wasm"
path = "examples/wasm/hello_wasm.rs"
required-features = []
[[example]]
name = "assets_wasm"
path = "examples/wasm/assets_wasm.rs"
required-features = ["bevy_winit"]
[[example]]
name = "headless_wasm"
path = "examples/wasm/headless_wasm.rs"
required-features = []
[[example]]
name = "winit_wasm"
path = "examples/wasm/winit_wasm.rs"
required-features = ["bevy_winit"]
# Android
[[example]]
crate-type = ["cdylib"]

View file

@ -366,24 +366,34 @@ cargo install wasm-bindgen-cli
### Build & Run
Following is an example for `headless_wasm`. For other examples in wasm/ directory,
change the `headless_wasm` in the following commands **and edit** `examples/wasm/index.html`
to point to the correct `.js` file.
Following is an example for `lighting`. For other examples, change the `lighting` in the
following commands.
```sh
cargo build --example headless_wasm --target wasm32-unknown-unknown --no-default-features
wasm-bindgen --out-dir examples/wasm/target --target web target/wasm32-unknown-unknown/debug/examples/headless_wasm.wasm
cargo build --release --example lighting --target wasm32-unknown-unknown
wasm-bindgen --out-name wasm_example --out-dir examples/wasm/target --target web target/wasm32-unknown-unknown/release/examples/lighting.wasm
```
Then serve `examples/wasm` dir to browser. i.e.
The first command will build the example for the wasm target, creating a binary. Then,
[wasm-bindgen-cli](https://rustwasm.github.io/wasm-bindgen/reference/cli.html) is used to create
javascript bindings to this wasm file, which can be loaded using this
[example HTML file](./wasm/index.html).
Then serve `examples/wasm` directory to browser. i.e.
```sh
# cargo install basic-http-server
basic-http-server examples/wasm
# with python
python3 -m http.server --directory examples/wasm
# with ruby
ruby -run -ehttpd examples/wasm
```
Example | File | Description
--- | --- | ---
`hello_wasm` | [`wasm/hello_wasm.rs`](./wasm/hello_wasm.rs) | Runs a minimal example that logs "hello world" to the browser's console
`assets_wasm` | [`wasm/assets_wasm.rs`](./wasm/assets_wasm.rs) | Demonstrates how to load assets from wasm
`headless_wasm` | [`wasm/headless_wasm.rs`](./wasm/headless_wasm.rs) | Sets up a schedule runner and continually logs a counter to the browser's console
`winit_wasm` | [`wasm/winit_wasm.rs`](./wasm/winit_wasm.rs) | Logs user input to the browser's console. Requires the `bevy_winit` features
### Loading Assets
To load assets, they need to be available in the folder examples/wasm/assets. Cloning this
repository will set it up as a symlink on Linux and macOS, but you will need to manually move
the assets on Windows.

1
examples/wasm/assets Symbolic link
View file

@ -0,0 +1 @@
../../assets

View file

@ -1,68 +0,0 @@
use bevy::{
asset::{AssetLoader, AssetServerSettings, LoadContext, LoadedAsset},
prelude::*,
reflect::TypeUuid,
utils::BoxedFuture,
};
fn main() {
App::new()
.insert_resource(AssetServerSettings {
asset_folder: "/".to_string(),
})
.add_plugins(DefaultPlugins)
.add_asset::<RustSourceCode>()
.init_asset_loader::<RustSourceCodeLoader>()
.add_startup_system(load_asset)
.add_system(print_asset)
.run();
}
struct State {
handle: Handle<RustSourceCode>,
printed: bool,
}
fn load_asset(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.insert_resource(State {
handle: asset_server.load("assets_wasm.rs"),
printed: false,
});
}
fn print_asset(mut state: ResMut<State>, rust_sources: Res<Assets<RustSourceCode>>) {
if state.printed {
return;
}
if let Some(code) = rust_sources.get(&state.handle) {
info!("code: {}", code.0);
state.printed = true;
}
}
#[derive(Debug, TypeUuid)]
#[uuid = "1c3445ab-97d3-449c-ab35-16ba30e4c29d"]
pub struct RustSourceCode(pub String);
#[derive(Default)]
pub struct RustSourceCodeLoader;
impl AssetLoader for RustSourceCodeLoader {
fn load<'a>(
&'a self,
bytes: &'a [u8],
load_context: &'a mut LoadContext,
) -> BoxedFuture<'a, Result<(), anyhow::Error>> {
Box::pin(async move {
load_context.set_default_asset(LoadedAsset::new(RustSourceCode(String::from_utf8(
bytes.into(),
)?)));
Ok(())
})
}
fn extensions(&self) -> &[&str] {
&["rs"]
}
}

View file

@ -1,34 +0,0 @@
use bevy::{
app::{ScheduleRunnerPlugin, ScheduleRunnerSettings},
log::LogPlugin,
prelude::*,
utils::Duration,
};
fn main() {
App::new()
.insert_resource(ScheduleRunnerSettings::run_loop(Duration::from_secs_f64(
1.0 / 60.0,
)))
.add_plugin(ScheduleRunnerPlugin::default())
.add_plugin(LogPlugin::default())
.add_startup_system(hello_world_system)
.add_system(counter)
.run();
}
fn hello_world_system() {
info!("hello wasm");
}
fn counter(mut state: Local<CounterState>) {
if state.count % 60 == 0 {
info!("counter system: {}", state.count);
}
state.count += 1;
}
#[derive(Default)]
struct CounterState {
count: u32,
}

View file

@ -1,12 +0,0 @@
use bevy::{log::LogPlugin, prelude::*};
fn main() {
App::new()
.add_plugin(LogPlugin::default())
.add_system(hello_wasm_system)
.run();
}
fn hello_wasm_system() {
info!("hello wasm");
}

View file

@ -21,7 +21,7 @@
</style>
</head>
<script type="module">
import init from './target/headless_wasm.js'
import init from './target/wasm_example.js'
init()
</script>
</html>

View file

@ -1,89 +0,0 @@
use bevy::{
input::{
keyboard::KeyboardInput,
mouse::{MouseButtonInput, MouseMotion, MouseWheel},
},
prelude::*,
};
fn main() {
App::new()
.insert_resource(WindowDescriptor {
width: 300.,
height: 300.,
..Default::default()
})
.add_plugins(DefaultPlugins)
// One time greet
.add_startup_system(hello_wasm_system)
// Track ticks (sanity check, whether game loop is running)
.add_system(counter)
// Track input events
.add_system(track_input_events)
.run();
}
fn hello_wasm_system() {
info!("hello wasm");
}
fn counter(mut state: Local<CounterState>, time: Res<Time>) {
if state.count % 60 == 0 {
info!(
"tick {} @ {:?} [Δ{}]",
state.count,
time.time_since_startup(),
time.delta_seconds()
);
}
state.count += 1;
}
#[derive(Default)]
struct CounterState {
count: u32,
}
fn track_input_events(
mut ev_keys: EventReader<KeyboardInput>,
mut ev_cursor: EventReader<CursorMoved>,
mut ev_motion: EventReader<MouseMotion>,
mut ev_mousebtn: EventReader<MouseButtonInput>,
mut ev_scroll: EventReader<MouseWheel>,
) {
// Keyboard input
for ev in ev_keys.iter() {
if ev.state.is_pressed() {
info!("Just pressed key: {:?}", ev.key_code);
} else {
info!("Just released key: {:?}", ev.key_code);
}
}
// Absolute cursor position (in window coordinates)
for ev in ev_cursor.iter() {
info!("Cursor at: {}", ev.position);
}
// Relative mouse motion
for ev in ev_motion.iter() {
info!("Mouse moved {} pixels", ev.delta);
}
// Mouse buttons
for ev in ev_mousebtn.iter() {
if ev.state.is_pressed() {
info!("Just pressed mouse button: {:?}", ev.button);
} else {
info!("Just released mouse button: {:?}", ev.button);
}
}
// scrolling (mouse wheel, touchpad, etc.)
for ev in ev_scroll.iter() {
info!(
"Scrolled vertically by {} and horizontally by {}.",
ev.y, ev.x
);
}
}