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

Web viewer: catch and show panic messages that happens at startup #2157

Merged
merged 5 commits into from
May 17, 2023
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
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,13 @@ debug = true
# ALWAYS document what PR the commit hash is part of, or when it was merged into the upstream trunk.

# TODO(andreas/emilk): Update to a stable egui version
# wgpu 0.16 support, device configuration dependent on adapter, and some additions to help egui_tiles, egui::Modifiers::contains
ecolor = { git = "https://github.com/emilk/egui", rev = "ff8e482" }
eframe = { git = "https://github.com/emilk/egui", rev = "ff8e482" }
egui = { git = "https://github.com/emilk/egui", rev = "ff8e482" }
egui-wgpu = { git = "https://github.com/emilk/egui", rev = "ff8e482" }
egui_extras = { git = "https://github.com/emilk/egui", rev = "ff8e482" }
emath = { git = "https://github.com/emilk/egui", rev = "ff8e482" }
# wgpu 0.16 support, device configuration dependent on adapter, and some additions to help egui_tiles, egui::Modifiers::contains, better error reporting for web
ecolor = { git = "https://github.com/emilk/egui", rev = "ea71b7f" }
eframe = { git = "https://github.com/emilk/egui", rev = "ea71b7f" }
egui = { git = "https://github.com/emilk/egui", rev = "ea71b7f" }
egui-wgpu = { git = "https://github.com/emilk/egui", rev = "ea71b7f" }
egui_extras = { git = "https://github.com/emilk/egui", rev = "ea71b7f" }
emath = { git = "https://github.com/emilk/egui", rev = "ea71b7f" }

# TODO(andreas): Either work around this issue in wgpu-egui (never discard command buffers) or wait for wgpu patch release.
# Fix for command buffer dropping crash https://github.com/gfx-rs/wgpu/pull/3726
Expand Down
1 change: 0 additions & 1 deletion crates/re_sdk_comms/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ re_smart_channel.workspace = true

ahash.workspace = true
anyhow.workspace = true
bincode = "1.3"
crossbeam.workspace = true
document-features = "0.2"
rand = { version = "0.8.5", features = ["small_rng"] }
Expand Down
1 change: 0 additions & 1 deletion crates/re_viewer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ winapi = "0.3.9"

# web dependencies:
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3.52", features = ["Window"] }

Expand Down
196 changes: 99 additions & 97 deletions crates/re_viewer/src/web.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use eframe::{
wasm_bindgen::{self, prelude::*},
web::AppRunnerRef,
};
use eframe::wasm_bindgen::{self, prelude::*};

use std::sync::Arc;

Expand All @@ -13,115 +10,120 @@ static GLOBAL: AccountingAllocator<std::alloc::System> =

#[wasm_bindgen]
pub struct WebHandle {
runner: AppRunnerRef,
runner: eframe::WebRunner,
}

#[wasm_bindgen]
impl WebHandle {
/// This is the entry-point for all the Wasm.
///
/// This is called once from the HTML.
/// It loads the app, installs some callbacks, then returns.
/// The `url` is an optional URL to either an .rrd file over http, or a Rerun WebSocket server.
#[allow(clippy::new_without_default)]
#[wasm_bindgen(constructor)]
pub async fn new(
canvas_id: &str,
url: Option<String>,
) -> Result<WebHandle, wasm_bindgen::JsValue> {
// Make sure panics are logged using `console.error`.
console_error_panic_hook::set_once();

pub fn new() -> Self {
re_log::setup_web_logging();

Self {
runner: eframe::WebRunner::new(),
}
}

/// The `url` is an optional URL to either an .rrd file over http, or a Rerun WebSocket server.
#[wasm_bindgen]
pub async fn start(
&self,
canvas_id: &str,
url: Option<String>,
) -> Result<(), wasm_bindgen::JsValue> {
let web_options = eframe::WebOptions {
follow_system_theme: false,
default_theme: eframe::Theme::Dark,
wgpu_options: crate::wgpu_options(),
depth_buffer: 0,
};

let runner = eframe::start_web(
canvas_id,
web_options,
Box::new(move |cc| {
let build_info = re_build_info::build_info!();
let app_env = crate::AppEnvironment::Web;
let persist_state = get_persist_state(&cc.integration_info);
let startup_options = crate::StartupOptions {
memory_limit: re_memory::MemoryLimit {
// On wasm32 we only have 4GB of memory to play around with.
limit: Some(2_500_000_000),
},
persist_state,
};
let re_ui = crate::customize_eframe(cc);
let url = url.unwrap_or_else(|| get_url(&cc.integration_info));

match categorize_uri(url) {
EndpointCategory::HttpRrd(url) => {
// Download an .rrd file over http:
let (tx, rx) = re_smart_channel::smart_channel(
re_smart_channel::Source::RrdHttpStream { url: url.clone() },
);
let egui_ctx = cc.egui_ctx.clone();
re_log_encoding::stream_rrd_from_http::stream_rrd_from_http(
url,
Arc::new(move |msg| {
egui_ctx.request_repaint(); // wake up ui thread
tx.send(msg).ok();
}),
);

Box::new(crate::App::from_receiver(
build_info,
&app_env,
startup_options,
re_ui,
cc.storage,
rx,
std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)),
))
self.runner
.start(
canvas_id,
web_options,
Box::new(move |cc| {
let build_info = re_build_info::build_info!();
let app_env = crate::AppEnvironment::Web;
let persist_state = get_persist_state(&cc.integration_info);
let startup_options = crate::StartupOptions {
memory_limit: re_memory::MemoryLimit {
// On wasm32 we only have 4GB of memory to play around with.
limit: Some(2_500_000_000),
},
persist_state,
};
let re_ui = crate::customize_eframe(cc);
let url = url.unwrap_or_else(|| get_url(&cc.integration_info));

match categorize_uri(url) {
EndpointCategory::HttpRrd(url) => {
// Download an .rrd file over http:
let (tx, rx) = re_smart_channel::smart_channel(
re_smart_channel::Source::RrdHttpStream { url: url.clone() },
);
let egui_ctx = cc.egui_ctx.clone();
re_log_encoding::stream_rrd_from_http::stream_rrd_from_http(
url,
Arc::new(move |msg| {
egui_ctx.request_repaint(); // wake up ui thread
tx.send(msg).ok();
}),
);

Box::new(crate::App::from_receiver(
build_info,
&app_env,
startup_options,
re_ui,
cc.storage,
rx,
std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)),
))
}
EndpointCategory::WebEventListener => {
// Process an rrd when it's posted via `window.postMessage`
let (tx, rx) = re_smart_channel::smart_channel(
re_smart_channel::Source::RrdWebEventListener,
);
let egui_ctx = cc.egui_ctx.clone();
re_log_encoding::stream_rrd_from_http::stream_rrd_from_event_listener(
Some(Arc::new(move |msg| {
egui_ctx.request_repaint(); // wake up ui thread
tx.send(msg).ok();
})),
);

Box::new(crate::App::from_receiver(
build_info,
&app_env,
startup_options,
re_ui,
cc.storage,
rx,
std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)),
))
}
EndpointCategory::WebSocket(url) => {
// Connect to a Rerun server over WebSockets.
Box::new(crate::RemoteViewerApp::new(
build_info,
app_env,
startup_options,
re_ui,
cc.storage,
url,
))
}
}
EndpointCategory::WebEventListener => {
// Process an rrd when it's posted via `window.postMessage`
let (tx, rx) = re_smart_channel::smart_channel(
re_smart_channel::Source::RrdWebEventListener,
);
let egui_ctx = cc.egui_ctx.clone();
re_log_encoding::stream_rrd_from_http::stream_rrd_from_event_listener(
Some(Arc::new(move |msg| {
egui_ctx.request_repaint(); // wake up ui thread
tx.send(msg).ok();
})),
);

Box::new(crate::App::from_receiver(
build_info,
&app_env,
startup_options,
re_ui,
cc.storage,
rx,
std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)),
))
}
EndpointCategory::WebSocket(url) => {
// Connect to a Rerun server over WebSockets.
Box::new(crate::RemoteViewerApp::new(
build_info,
app_env,
startup_options,
re_ui,
cc.storage,
url,
))
}
}
}),
)
.await?;
}),
)
.await?;

re_log::debug!("Web app started.");

Ok(WebHandle { runner })
Ok(())
}

#[wasm_bindgen]
Expand Down
4 changes: 4 additions & 0 deletions crates/re_web_viewer_server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ tokio = { workspace = true, default-features = false, features = [
"rt-multi-thread",
] }

# Only needed for for main.rs:
clap = { workspace = true, features = ["derive"] }
webbrowser = "0.8.3"

# Optional dependencies:
re_analytics = { workspace = true, optional = true }

Expand Down
Loading