Profiling #7
			
				
			
		
		
		
	| 
						 | 
				
			
			@ -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<Option<String>> {
 | 
			
		||||
| 
						 | 
				
			
			@ -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 => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue