Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix minimal-web example #407

Merged
merged 4 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading