Skip to content

Commit

Permalink
Fix minimal-web example (#407)
Browse files Browse the repository at this point in the history
Adds CI steps to check and lint the example. And fixes build failures introduced by updating `winit` and `wgpu` in #391.

`run-wasm` still won't fail out the WASM CI job when there are build errors. That is tracked upstream in rukai/cargo-run-wasm#49

Closes #406
  • Loading branch information
parasyte authored Nov 13, 2024
1 parent 57d339e commit d4df286
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 52 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ jobs:
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
target: wasm32-unknown-unknown
- name: Rust cache
uses: Swatinem/rust-cache@v2
with:
shared-key: common
- name: Cargo check
run: cargo check --workspace
- name: Cargo check WASM
run: cargo check --target wasm32-unknown-unknown --package minimal-web

lints:
name: Lints
Expand All @@ -47,6 +50,7 @@ jobs:
with:
toolchain: stable
components: clippy, rustfmt
target: wasm32-unknown-unknown
- name: Rust cache
uses: Swatinem/rust-cache@v2
with:
Expand All @@ -61,6 +65,8 @@ jobs:
run: cargo doc --workspace --no-deps
- name: Cargo clippy
run: cargo clippy --workspace --tests -- -D warnings
- name: Cargo clippy WASM
run: cargo clippy --target wasm32-unknown-unknown --package minimal-web --tests -- -D warnings
- name: Cargo machete
run: cargo machete

Expand Down Expand Up @@ -105,8 +111,6 @@ jobs:
uses: actions/checkout@v3
- name: Update apt repos
run: sudo apt -y update
- name: Install dependencies
run: sudo apt -y install libgtk-3-dev libudev-dev
- name: Install toolchain
uses: dtolnay/rust-toolchain@master
with:
Expand All @@ -117,7 +121,7 @@ jobs:
with:
shared-key: common
- name: WASM build
run: cargo run-wasm --build-only ${{ matrix.example }}
run: cargo run-wasm --build-only --package ${{ matrix.example }}

# See https://github.com/parasyte/pixels-ci-rust-version
rust-version:
Expand Down
114 changes: 65 additions & 49 deletions examples/minimal-web/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use error_iter::ErrorIter as _;
use log::error;
use pixels::{Pixels, SurfaceTexture};
use pixels::{PixelsBuilder, SurfaceTexture};
use std::rc::Rc;
use winit::dpi::LogicalSize;
use winit::event::{Event, WindowEvent};
Expand Down Expand Up @@ -41,6 +41,16 @@ fn main() {
}
}

#[cfg(target_arch = "wasm32")]
/// Retrieve current width and height dimensions of browser client window
fn get_window_size() -> LogicalSize<f64> {
let client_window = web_sys::window().unwrap();
LogicalSize::new(
client_window.inner_width().unwrap().as_f64().unwrap(),
client_window.inner_height().unwrap().as_f64().unwrap(),
)
}

async fn run() {
let event_loop = EventLoop::new().unwrap();
let window = {
Expand All @@ -60,90 +70,96 @@ async fn run() {
use wasm_bindgen::JsCast;
use winit::platform::web::WindowExtWebSys;

// Retrieve current width and height dimensions of browser client window
let get_window_size = || {
let client_window = web_sys::window().unwrap();
LogicalSize::new(
client_window.inner_width().unwrap().as_f64().unwrap(),
client_window.inner_height().unwrap().as_f64().unwrap(),
)
};

let window = Rc::clone(&window);

// Initialize winit window with current dimensions of browser client
window.set_inner_size(get_window_size());

let client_window = web_sys::window().unwrap();

// Attach winit canvas to body element
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| doc.body())
.and_then(|body| {
body.append_child(&web_sys::Element::from(window.canvas()))
body.append_child(&web_sys::Element::from(window.canvas().unwrap()))
.ok()
})
.expect("couldn't append canvas to document body");

// Listen for resize event on browser client. Adjust winit window dimensions
// on event trigger
let closure = wasm_bindgen::closure::Closure::wrap(Box::new(move |_e: web_sys::Event| {
let size = get_window_size();
window.set_inner_size(size)
let closure = wasm_bindgen::closure::Closure::wrap(Box::new({
let window = Rc::clone(&window);
move |_e: web_sys::Event| {
let _ = window.request_inner_size(get_window_size());
}
}) as Box<dyn FnMut(_)>);
client_window
web_sys::window()
.unwrap()
.add_event_listener_with_callback("resize", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();

// Trigger initial resize event
let _ = window.request_inner_size(get_window_size());
}

let mut input = WinitInputHelper::new();
let mut pixels = {
#[cfg(not(target_arch = "wasm32"))]
let window_size = window.inner_size();

#[cfg(target_arch = "wasm32")]
let window_size = get_window_size().to_physical::<u32>(window.scale_factor());

let surface_texture =
SurfaceTexture::new(window_size.width, window_size.height, window.as_ref());
Pixels::new_async(WIDTH, HEIGHT, surface_texture)
.await
.expect("Pixels error")
let builder = PixelsBuilder::new(WIDTH, HEIGHT, surface_texture);

#[cfg(target_arch = "wasm32")]
let builder = {
// Web targets do not support the default texture format
let texture_format = pixels::wgpu::TextureFormat::Rgba8Unorm;
builder
.texture_format(texture_format)
.surface_texture_format(texture_format)
};

builder.build_async().await.expect("Pixels error")
};
let mut world = World::new();

let res = event_loop.run(|event, elwt| {
// Draw the current frame
if let Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} = event
{
world.draw(pixels.frame_mut());
if let Err(err) = pixels.render() {
log_error("pixels.render", err);
elwt.exit();
return;
}
}
match event {
Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => {
// Draw the current frame
world.draw(pixels.frame_mut());
if let Err(err) = pixels.render() {
log_error("pixels.render", err);
elwt.exit();
return;
}

// Handle input events
if input.update(&event) {
// Close events
if input.key_pressed(KeyCode::Escape) || input.close_requested() {
elwt.exit();
return;
// Update internal state and request a redraw
world.update();
window.request_redraw();
}

// Resize the window
if let Some(size) = input.window_resized() {
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
// Resize the window
if let Err(err) = pixels.resize_surface(size.width, size.height) {
log_error("pixels.resize_surface", err);
elwt.exit();
return;
}
}

// Update internal state and request a redraw
world.update();
window.request_redraw();
_ => (),
}

// Handle input events
if input.update(&event) && (input.key_pressed(KeyCode::Escape) || input.close_requested()) {
elwt.exit();
}
});
res.unwrap();
Expand Down

0 comments on commit d4df286

Please sign in to comment.