Skip to content

Commit

Permalink
Use low-level-wasm from bevy
Browse files Browse the repository at this point in the history
  • Loading branch information
johanhelsing committed Nov 19, 2023
1 parent 729962e commit 1b1e5e4
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 6 deletions.
9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,22 @@ version = "0.7.0"

[dependencies]
bevy = {version = "0.12", default-features = false, features = ["bevy_asset"]}

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
ehttp = "0.3"

[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = {version = "0.3", default-features = false}
wasm-bindgen = {version = "0.2", default-features = false}
wasm-bindgen-futures = "0.4"
web-sys = {version = "0.3.22", default-features = false}

[dev-dependencies]
bevy = {version = "0.12", default-features = false, features = [
"bevy_asset",
"bevy_core_pipeline",
"bevy_sprite",
"png",
"webgl2",
"x11", # GitHub Actions runners don't have libxkbcommon installed, so can't use Wayland
]}
5 changes: 1 addition & 4 deletions examples/web_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {

commands.spawn(SpriteBundle {
// Simply use a url where you would normally use an asset folder relative path
texture: asset_server.load(
// TODO: `https://s3.johanhelsing.studio/dump/favicon.png` doesn't seem to work
"https://raw.githubusercontent.com/johanhelsing/bevy_web_asset/main/assets/favicon.png",
),
texture: asset_server.load("https://s3.johanhelsing.studio/dump/favicon.png"),
..default()
});
}
50 changes: 48 additions & 2 deletions src/web_asset_source.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use bevy::asset::io::PathStream;
use bevy::utils::BoxedFuture;
use bevy::{asset::io::PathStream, utils::BoxedFuture};
use std::path::{Path, PathBuf};

use bevy::asset::io::{AssetReader, AssetReaderError, Reader, VecReader};
Expand Down Expand Up @@ -33,6 +32,53 @@ impl WebAssetReader {
}
}

#[cfg(target_arch = "wasm32")]
async fn get<'a>(path: PathBuf) -> Result<Box<Reader<'a>>, AssetReaderError> {
use js_sys::Uint8Array;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::JsFuture;
use web_sys::Response;

fn js_value_to_err<'a>(
context: &'a str,
) -> impl FnOnce(wasm_bindgen::JsValue) -> std::io::Error + 'a {
move |value| {
let message = match js_sys::JSON::stringify(&value) {
Ok(js_str) => format!("Failed to {context}: {js_str}"),
Err(_) => {
format!(
"Failed to {context} and also failed to stringify the JSValue of the error"
)
}
};

std::io::Error::new(std::io::ErrorKind::Other, message)
}
}

let window = web_sys::window().unwrap();
let resp_value = JsFuture::from(window.fetch_with_str(path.to_str().unwrap()))
.await
.map_err(js_value_to_err("fetch path"))?;
let resp = resp_value
.dyn_into::<Response>()
.map_err(js_value_to_err("convert fetch to Response"))?;
match resp.status() {
200 => {
let data = JsFuture::from(resp.array_buffer().unwrap()).await.unwrap();
let bytes = Uint8Array::new(&data).to_vec();
let reader: Box<Reader> = Box::new(VecReader::new(bytes));
Ok(reader)
}
404 => Err(AssetReaderError::NotFound(path)),
status => Err(AssetReaderError::Io(std::io::Error::new(
std::io::ErrorKind::Other,
format!("Encountered unexpected HTTP status {status}"),
))),
}
}

#[cfg(not(target_arch = "wasm32"))]
async fn get<'a>(uri: PathBuf) -> Result<Box<Reader<'a>>, AssetReaderError> {
use ehttp::{fetch, Request};
use std::future::Future;
Expand Down

0 comments on commit 1b1e5e4

Please sign in to comment.