diff --git a/web/client/src/lib.rs b/web/client/src/lib.rs index 86d11444cf..b79f2d0a66 100644 --- a/web/client/src/lib.rs +++ b/web/client/src/lib.rs @@ -10,12 +10,9 @@ use ambient_ui_native::{ element::{ElementComponentExt, Group}, WindowSized, }; +use anyhow::Context; use app::MainApp; -use tracing_subscriber::{ - filter::{LevelFilter, Targets}, - prelude::*, - registry, -}; +use tracing_subscriber::{filter::Targets, prelude::*, registry}; use tracing_web::MakeConsoleWriter; use wasm_bindgen::prelude::*; @@ -30,30 +27,52 @@ static APP_CONTROL: OnceLock> = OnceLock::new(); /// backwards and forwards compatibility when new fields are added to the settings object in a /// "best fit" approach, similar to the `settings` in the LanguageServerProtocol spec. pub struct Settings { + #[serde(default = "default_true")] enable_logging: bool, + #[serde(default = "default_true")] enable_panic_hook: bool, + #[serde(default)] allow_version_mismatch: bool, - log_filter: Option, + #[serde(default = "default_filter")] + log_filter: String, + #[serde(default)] debugger: bool, } +fn default_filter() -> String { + "info".into() +} + +fn default_true() -> bool { + true +} + #[wasm_bindgen] /// Starts execution of the ambient client and connects to the specified URL /// /// TODO: The `MainApp` setup will move to an Ambient package and this will only load the runtime -pub async fn start(target: Option, server_url: String, settings: JsValue) { - let settings: Settings = - serde_wasm_bindgen::from_value(settings).expect("settings can be parsed from object"); +/// +/// Finishes once the app has been built and initialized +pub async fn start( + target: Option, + server_url: String, + settings: JsValue, +) -> Result<(), JsValue> { + let settings: Settings = serde_wasm_bindgen::from_value(settings)?; - init(&settings).expect("Failed to initialize ambient"); + init(&settings) + .context("Failed to initialize ambient") + .map_err(|e| format!("{e:?}"))?; - if let Err(err) = run(target, server_url, settings).await { - tracing::error!("{err:?}") - } + run(target, server_url, settings) + .await + .map_err(|e| format!("{e:?}"))?; + + Ok(()) } /// Initialize ambient -fn init(settings: &Settings) -> Result<(), JsValue> { +fn init(settings: &Settings) -> anyhow::Result<()> { if settings.enable_logging { let fmt_layer = tracing_subscriber::fmt::layer() .with_ansi(true) // Only partially supported, but works on Chrome @@ -62,13 +81,8 @@ fn init(settings: &Settings) -> Result<(), JsValue> { let filter = settings .log_filter - .as_ref() - .map(|v| { - v.parse::() - .map_err(|_| JsValue::from("Failed to parse filtering directive")) - }) - .transpose()? - .unwrap_or_else(|| Targets::new().with_default(LevelFilter::INFO)); + .parse::() + .context("Failed to parse filtering directive")?; registry().with(filter).with(fmt_layer).init(); } @@ -114,7 +128,6 @@ async fn run( use ambient_sys::timer::TimerWheel; ambient_sys::task::spawn(TimerWheel::new().start()); - use anyhow::Context; let mut app = App::builder() .ui_renderer(true) .parent_element(target) @@ -123,8 +136,6 @@ async fn run( .await .context("Failed to build app")?; - tracing::info!("Finished building app"); - let world = &mut app.world; Group(vec![