diff --git a/beacon/src/client.rs b/beacon/src/client.rs index cd5fec6d..95755d98 100644 --- a/beacon/src/client.rs +++ b/beacon/src/client.rs @@ -43,6 +43,9 @@ pub enum Event { ThemeChanged(theme::Palette), SpanStarted(span::Stage), SpanFinished(span::Stage, Duration), + MessageLogged(String), + CommandsSpawned(usize), + SubscriptionsTracked(usize), } impl Client { diff --git a/beacon/src/lib.rs b/beacon/src/lib.rs index d3d8c722..36d19e30 100644 --- a/beacon/src/lib.rs +++ b/beacon/src/lib.rs @@ -30,6 +30,10 @@ pub enum Event { at: SystemTime, palette: theme::Palette, }, + SubscriptionsTracked { + at: SystemTime, + amount_alive: usize, + }, SpanFinished { at: SystemTime, duration: Duration, @@ -49,6 +53,7 @@ impl Event { Self::Connected { at, .. } | Self::Disconnected { at, .. } | Self::ThemeChanged { at, .. } + | Self::SubscriptionsTracked { at, .. } | Self::SpanFinished { at, .. } | Self::QuitRequested { at } | Self::AlreadyRunning { at } => *at, @@ -87,6 +92,9 @@ pub fn run() -> impl Stream { let _ = stream.set_nodelay(true); + let mut last_message = String::new(); + let mut last_commands_spawned = 0; + loop { match receive(&mut stream, &mut buffer).await { Ok(message) => { @@ -114,6 +122,30 @@ pub fn run() -> impl Stream { }) .await; } + client::Event::SubscriptionsTracked( + amount_alive, + ) => { + let _ = output + .send(Event::SubscriptionsTracked { + at, + amount_alive, + }) + .await; + } + client::Event::MessageLogged(message) => { + last_message = message; + } + client::Event::CommandsSpawned( + commands, + ) => { + last_commands_spawned = commands; + } + client::Event::SpanStarted( + span::Stage::Update, + ) => { + last_message.clear(); + last_commands_spawned = 0; + } client::Event::SpanStarted(_) => {} client::Event::SpanFinished( stage, @@ -121,7 +153,14 @@ pub fn run() -> impl Stream { ) => { let span = match stage { span::Stage::Boot => Span::Boot, - span::Stage::Update => Span::Update, + span::Stage::Update => { + Span::Update { + message: last_message + .clone(), + commands_spawned: + last_commands_spawned, + } + } span::Stage::View(window) => { Span::View { window } } diff --git a/beacon/src/span.rs b/beacon/src/span.rs index 7d673663..38f19acb 100644 --- a/beacon/src/span.rs +++ b/beacon/src/span.rs @@ -5,20 +5,36 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Span { Boot, - Update, - View { window: window::Id }, - Layout { window: window::Id }, - Interact { window: window::Id }, - Draw { window: window::Id }, - Present { window: window::Id }, - Custom { window: window::Id, name: String }, + Update { + message: String, + commands_spawned: usize, + }, + View { + window: window::Id, + }, + Layout { + window: window::Id, + }, + Interact { + window: window::Id, + }, + Draw { + window: window::Id, + }, + Present { + window: window::Id, + }, + Custom { + window: window::Id, + name: String, + }, } impl Span { pub fn stage(&self) -> Stage { match self { Span::Boot => Stage::Boot, - Span::Update => Stage::Update, + Span::Update { .. } => Stage::Update, Span::View { window } => Stage::View(*window), Span::Layout { window } => Stage::Layout(*window), Span::Interact { window } => Stage::Interact(*window), diff --git a/debug/src/lib.rs b/debug/src/lib.rs index 54814b4e..ab7a2853 100644 --- a/debug/src/lib.rs +++ b/debug/src/lib.rs @@ -13,18 +13,24 @@ pub fn toggle_comet() { internal::toggle_comet(); } -pub fn log_message(_message: &impl std::fmt::Debug) {} - pub fn theme_changed(f: impl FnOnce() -> Option) { internal::theme_changed(f); } +pub fn commands_spawned(amount: usize) { + internal::commands_spawned(amount) +} + +pub fn subscriptions_tracked(amount: usize) { + internal::subscriptions_tracked(amount) +} + pub fn boot() -> Span { internal::boot() } -pub fn update() -> Span { - internal::update() +pub fn update(message: &impl std::fmt::Debug) -> Span { + internal::update(message) } pub fn view(window: window::Id) -> Span { @@ -107,12 +113,29 @@ mod internal { } } + pub fn commands_spawned(amount: usize) { + BEACON.log(client::Event::CommandsSpawned(amount)); + } + + pub fn subscriptions_tracked(amount: usize) { + BEACON.log(client::Event::SubscriptionsTracked(amount)); + } + pub fn boot() -> Span { span(span::Stage::Boot) } - pub fn update() -> Span { - span(span::Stage::Update) + pub fn update(message: &impl std::fmt::Debug) -> Span { + let span = span(span::Stage::Update); + let message = format!("{message:.30?}"); + + BEACON.log(client::Event::MessageLogged(if message.len() > 29 { + format!("{}...", &message[..29]) + } else { + message + })); + + span } pub fn view(window: window::Id) -> Span { @@ -191,11 +214,15 @@ mod internal { pub fn theme_changed(_f: impl FnOnce() -> Option) {} + pub fn commands_spawned(_amount: usize) {} + + pub fn subscriptions_tracked(_amount: usize) {} + pub fn boot() -> Span { Span } - pub fn update() -> Span { + pub fn update(_message: &impl std::fmt::Debug) -> Span { Span } diff --git a/runtime/src/program/state.rs b/runtime/src/program/state.rs index 129f2449..033fe018 100644 --- a/runtime/src/program/state.rs +++ b/runtime/src/program/state.rs @@ -143,9 +143,7 @@ where let commands = Command::batch(messages.into_iter().map(|message| { - debug::log_message(&message); - - let update_span = debug::update(); + let update_span = debug::update(&message); let command = self.program.update(message); update_span.finish(); diff --git a/src/application.rs b/src/application.rs index 7bdef972..84aacc07 100644 --- a/src/application.rs +++ b/src/application.rs @@ -119,7 +119,9 @@ where type Flags; /// Returns the unique name of the [`Application`]. - fn name() -> &'static str; + fn name() -> &'static str { + std::any::type_name::() + } /// Initializes the [`Application`] with the flags provided to /// [`run`] as part of the [`Settings`]. diff --git a/winit/src/application.rs b/winit/src/application.rs index d7949b9e..c207fe9b 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -557,7 +557,11 @@ async fn run_instance( &mut proxy, &window, ); - runtime.track(application.subscription().into_recipes()); + + let recipes = application.subscription().into_recipes(); + debug::subscriptions_tracked(recipes.len()); + runtime.track(recipes); + boot_span.finish(); let mut user_interface = ManuallyDrop::new(build_user_interface( @@ -897,11 +901,8 @@ pub fn update( A::Theme: DefaultStyle, { for message in messages.drain(..) { - debug::log_message(&message); - - let update_span = debug::update(); + let update_span = debug::update(&message); let command = runtime.enter(|| application.update(message)); - update_span.finish(); run_command( application, @@ -917,12 +918,14 @@ pub fn update( proxy, window, ); + update_span.finish(); } state.synchronize(application, window); - let subscription = application.subscription(); - runtime.track(subscription.into_recipes()); + let recipes = application.subscription().into_recipes(); + debug::subscriptions_tracked(recipes.len()); + runtime.track(recipes); } /// Runs the actions of a [`Command`]. @@ -949,7 +952,10 @@ pub fn run_command( use crate::runtime::system; use crate::runtime::window; - for action in command.actions() { + let actions = command.actions(); + debug::commands_spawned(actions.len()); + + for action in actions { match action { command::Action::Future(future) => { runtime.spawn(future); diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs index 54208412..1ef313bc 100644 --- a/winit/src/multi_window.rs +++ b/winit/src/multi_window.rs @@ -523,7 +523,10 @@ async fn run_instance( &mut ui_caches, ); - runtime.track(application.subscription().into_recipes()); + let recipes = application.subscription().into_recipes(); + debug::subscriptions_tracked(recipes.len()); + runtime.track(recipes); + boot_span.finish(); let mut messages = Vec::new(); @@ -987,9 +990,7 @@ fn update( A::Theme: DefaultStyle, { for message in messages.drain(..) { - debug::log_message(&message); - - let update_span = debug::update(); + let update_span = debug::update(&message); let command = runtime.enter(|| application.update(message)); update_span.finish(); @@ -1006,8 +1007,9 @@ fn update( ); } - let subscription = application.subscription(); - runtime.track(subscription.into_recipes()); + let recipes = application.subscription().into_recipes(); + debug::subscriptions_tracked(recipes.len()); + runtime.track(recipes); } /// Runs the actions of a [`Command`]. @@ -1031,7 +1033,10 @@ fn run_command( use crate::runtime::system; use crate::runtime::window; - for action in command.actions() { + let actions = command.actions(); + debug::commands_spawned(actions.len()); + + for action in actions { match action { command::Action::Future(future) => { runtime.spawn(Box::pin(future));