Start profiler UI/thread
This commit is contained in:
+55
-24
@@ -18,7 +18,7 @@ use tracing::{error, warn};
|
||||
|
||||
use crate::{
|
||||
audio::Audio,
|
||||
emulator::{cart::Cart, profiler::Profiler},
|
||||
emulator::{cart::Cart, shrooms_vb_core::SimEvent},
|
||||
graphics::TextureSink,
|
||||
memory::{MemoryRange, MemoryRegion},
|
||||
};
|
||||
@@ -27,7 +27,6 @@ pub use shrooms_vb_core::{VBKey, VBRegister, VBWatchpointType};
|
||||
|
||||
mod address_set;
|
||||
mod cart;
|
||||
mod profiler;
|
||||
mod shrooms_vb_core;
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
|
||||
@@ -70,7 +69,6 @@ pub struct EmulatorBuilder {
|
||||
audio_on: Arc<[AtomicBool; 2]>,
|
||||
linked: Arc<AtomicBool>,
|
||||
start_paused: bool,
|
||||
monitor_events: bool,
|
||||
}
|
||||
|
||||
impl EmulatorBuilder {
|
||||
@@ -87,7 +85,6 @@ impl EmulatorBuilder {
|
||||
audio_on: Arc::new([AtomicBool::new(true), AtomicBool::new(true)]),
|
||||
linked: Arc::new(AtomicBool::new(false)),
|
||||
start_paused: false,
|
||||
monitor_events: false,
|
||||
};
|
||||
let client = EmulatorClient {
|
||||
queue,
|
||||
@@ -113,13 +110,6 @@ impl EmulatorBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn monitor_events(self, monitor_events: bool) -> Self {
|
||||
Self {
|
||||
monitor_events,
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<Emulator> {
|
||||
let mut emulator = Emulator::new(
|
||||
self.commands,
|
||||
@@ -134,9 +124,6 @@ impl EmulatorBuilder {
|
||||
if self.start_paused {
|
||||
emulator.pause_sims()?;
|
||||
}
|
||||
if self.monitor_events {
|
||||
emulator.monitor_events(SimId::Player1)?;
|
||||
}
|
||||
Ok(emulator)
|
||||
}
|
||||
}
|
||||
@@ -150,7 +137,7 @@ pub struct Emulator {
|
||||
state: Arc<Atomic<EmulatorState>>,
|
||||
audio_on: Arc<[AtomicBool; 2]>,
|
||||
linked: Arc<AtomicBool>,
|
||||
profilers: [Profiler; 2],
|
||||
profilers: [Option<ProfileSender>; 2],
|
||||
renderers: HashMap<SimId, TextureSink>,
|
||||
messages: HashMap<SimId, mpsc::Sender<Toast>>,
|
||||
debuggers: HashMap<SimId, DebugInfo>,
|
||||
@@ -178,7 +165,7 @@ impl Emulator {
|
||||
state,
|
||||
audio_on,
|
||||
linked,
|
||||
profilers: [Profiler::new(), Profiler::new()],
|
||||
profilers: [None, None],
|
||||
renderers: HashMap::new(),
|
||||
messages: HashMap::new(),
|
||||
debuggers: HashMap::new(),
|
||||
@@ -228,12 +215,29 @@ impl Emulator {
|
||||
}
|
||||
let sim = &mut self.sims[index];
|
||||
sim.reset();
|
||||
sim.monitor_events(self.profilers[sim_id.to_index()].is_enabled());
|
||||
if let Some(cart) = new_cart {
|
||||
sim.load_cart(cart.rom.clone(), cart.sram.clone())?;
|
||||
self.carts[index] = Some(cart);
|
||||
self.sim_state[index].store(SimState::Ready, Ordering::Release);
|
||||
}
|
||||
let mut profiling = false;
|
||||
if let Some(profiler) = self.profilers[sim_id.to_index()].as_ref() {
|
||||
if let Some(cart) = self.carts[index].as_ref() {
|
||||
if profiler
|
||||
.send(ProfileEvent::Start {
|
||||
file_path: cart.file_path.clone(),
|
||||
})
|
||||
.is_ok()
|
||||
{
|
||||
sim.monitor_events(true);
|
||||
profiling = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if !profiling {
|
||||
sim.monitor_events(false);
|
||||
}
|
||||
|
||||
if self.sim_state[index].load(Ordering::Acquire) == SimState::Ready {
|
||||
self.resume_sims();
|
||||
}
|
||||
@@ -331,6 +335,11 @@ impl Emulator {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start_profiling(&mut self, sim_id: SimId, sender: ProfileSender) -> Result<()> {
|
||||
self.profilers[sim_id.to_index()] = Some(sender);
|
||||
self.reset_sim(sim_id, None)
|
||||
}
|
||||
|
||||
fn start_debugging(&mut self, sim_id: SimId, sender: DebugSender) {
|
||||
if self.sim_state[sim_id.to_index()].load(Ordering::Acquire) != SimState::Ready {
|
||||
// Can't debug unless a game is connected
|
||||
@@ -399,11 +408,6 @@ impl Emulator {
|
||||
self.watched_regions.insert(range, region);
|
||||
}
|
||||
|
||||
fn monitor_events(&mut self, sim_id: SimId) -> Result<()> {
|
||||
self.profilers[sim_id.to_index()].enable(true);
|
||||
self.reset_sim(sim_id, None)
|
||||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
loop {
|
||||
let idle = self.tick();
|
||||
@@ -469,10 +473,20 @@ impl Emulator {
|
||||
.zip(self.profilers.iter_mut())
|
||||
.zip([p1_running, p2_running])
|
||||
{
|
||||
if !running || !profiler.is_enabled() {
|
||||
if !running {
|
||||
continue;
|
||||
}
|
||||
profiler.track(cycles, sim.take_sim_event());
|
||||
if let Some(p) = profiler {
|
||||
if p.send(ProfileEvent::Update {
|
||||
cycles,
|
||||
event: sim.take_sim_event(),
|
||||
})
|
||||
.is_err()
|
||||
{
|
||||
sim.monitor_events(false);
|
||||
*profiler = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if state == EmulatorState::Stepping {
|
||||
@@ -614,6 +628,11 @@ impl Emulator {
|
||||
self.report_error(SimId::Player1, format!("Error setting speed: {error}"));
|
||||
}
|
||||
}
|
||||
EmulatorCommand::StartProfiling(sim_id, profiler) => {
|
||||
if let Err(error) = self.start_profiling(sim_id, profiler) {
|
||||
self.report_error(SimId::Player1, format!("Error enaling profiler: {error}"));
|
||||
}
|
||||
}
|
||||
EmulatorCommand::StartDebugging(sim_id, debugger) => {
|
||||
self.start_debugging(sim_id, debugger);
|
||||
}
|
||||
@@ -751,6 +770,7 @@ pub enum EmulatorCommand {
|
||||
Resume,
|
||||
FrameAdvance,
|
||||
SetSpeed(f64),
|
||||
StartProfiling(SimId, ProfileSender),
|
||||
StartDebugging(SimId, DebugSender),
|
||||
StopDebugging(SimId),
|
||||
DebugInterrupt(SimId),
|
||||
@@ -792,6 +812,7 @@ pub enum EmulatorState {
|
||||
Debugging,
|
||||
}
|
||||
|
||||
type ProfileSender = tokio::sync::mpsc::UnboundedSender<ProfileEvent>;
|
||||
type DebugSender = tokio::sync::mpsc::UnboundedSender<DebugEvent>;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
@@ -815,6 +836,16 @@ pub enum DebugEvent {
|
||||
Stopped(DebugStopReason),
|
||||
}
|
||||
|
||||
pub enum ProfileEvent {
|
||||
Start {
|
||||
file_path: PathBuf,
|
||||
},
|
||||
Update {
|
||||
cycles: u32,
|
||||
event: Option<SimEvent>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct EmulatorClient {
|
||||
queue: mpsc::Sender<EmulatorCommand>,
|
||||
|
||||
Reference in New Issue
Block a user