From 6e89a0c9888257f951b80abaddc142abf8f2d136 Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Mon, 1 Sep 2025 17:38:00 -0400 Subject: [PATCH] Improve profiler interface --- src/window/profile.rs | 74 ++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/src/window/profile.rs b/src/window/profile.rs index 0a2d1a1..0499bfa 100644 --- a/src/window/profile.rs +++ b/src/window/profile.rs @@ -1,17 +1,18 @@ use std::{fs, time::Duration}; use anyhow::Result; -use egui::{Button, CentralPanel, Checkbox, ViewportBuilder, ViewportId}; +use egui::{Button, CentralPanel, Checkbox, Label, ViewportBuilder, ViewportId}; use egui_notify::{Anchor, Toast, Toasts}; use crate::{ - emulator::{EmulatorClient, SimId}, + emulator::{EmulatorClient, EmulatorCommand, EmulatorState, SimId}, profiler::{Profiler, ProfilerStatus}, window::AppWindow, }; pub struct ProfileWindow { sim_id: SimId, + client: EmulatorClient, profiler: Profiler, toasts: Toasts, } @@ -20,6 +21,7 @@ impl ProfileWindow { pub fn new(sim_id: SimId, client: EmulatorClient) -> Self { Self { sim_id, + client: client.clone(), profiler: Profiler::new(sim_id, client), toasts: Toasts::new() .with_anchor(Anchor::BottomLeft) @@ -33,6 +35,10 @@ impl ProfileWindow { } fn finish_recording(&mut self) { + let pause = matches!(self.client.emulator_state(), EmulatorState::Running); + if pause { + self.client.send_command(EmulatorCommand::Pause); + } match self.try_finish_recording() { Ok(Some(path)) => { let mut toast = Toast::info(format!("Saved to {path}")); @@ -46,6 +52,9 @@ impl ProfileWindow { self.toasts.add(toast); } } + if pause { + self.client.send_command(EmulatorCommand::Resume); + } } fn try_finish_recording(&mut self) -> Result> { @@ -84,8 +93,32 @@ impl AppWindow for ProfileWindow { let status = self.profiler.status(); let recording = matches!(status, ProfilerStatus::Recording); CentralPanel::default().show(ctx, |ui| { + ui.horizontal_wrapped(|ui| { + ui.spacing_mut().item_spacing.x = 0.0; + ui.add( + Label::new( + "Use this tool to record performance profiles of your game, for use in ", + ) + .wrap_mode(egui::TextWrapMode::Wrap), + ); + ui.hyperlink("https://profiler.firefox.com"); + ui.label("."); + }); + ui.horizontal_wrapped(|ui| { + ui.spacing_mut().item_spacing.x = 0.0; + ui.add( + Label::new("For more instructions, see ").wrap_mode(egui::TextWrapMode::Wrap), + ); + ui.hyperlink_to( + "the Lemur wiki", + "https://git.virtual-boy.com/PVB/lemur/wiki/Profiling-with-Lemur", + ); + ui.label("."); + }); + ui.separator(); + let mut enabled = status.enabled(); - let enabled_checkbox = Checkbox::new(&mut enabled, "Profiling enabled?"); + let enabled_checkbox = Checkbox::new(&mut enabled, "Enable profiling"); if ui.add_enabled(!recording, enabled_checkbox).changed() { if enabled { self.profiler.enable(); @@ -93,23 +126,26 @@ impl AppWindow for ProfileWindow { self.profiler.disable(); } } - - ui.horizontal(|ui| { - if !recording { - let record_button = Button::new("Record"); - let can_record = matches!(status, ProfilerStatus::Enabled); - if ui.add_enabled(can_record, record_button).clicked() { - self.profiler.start_recording(); + if !enabled { + ui.label("Enabling profiling will restart your current game."); + } else { + ui.horizontal(|ui| { + if !recording { + let record_button = Button::new("Record"); + let can_record = matches!(status, ProfilerStatus::Enabled); + if ui.add_enabled(can_record, record_button).clicked() { + self.profiler.start_recording(); + } + } else { + if ui.button("Finish recording").clicked() { + self.finish_recording(); + } + if ui.button("Cancel recording").clicked() { + self.profiler.cancel_recording(); + } } - } else { - if ui.button("Finish recording").clicked() { - self.finish_recording(); - } - if ui.button("Cancel recording").clicked() { - self.profiler.cancel_recording(); - } - } - }); + }); + } match &status { ProfilerStatus::Recording => {